我執行了一個小測試來確定訪問指針vs值向量向量的行爲。事實證明,對於小型內存塊而言,兩者的表現同樣出色,但是,對於大型內存塊而言,則會有顯着差異。向量指針vs向量值對大型內存塊和小型內存塊的性能損失
這種行爲的解釋是什麼?
對於下面的代碼,在我的電腦上執行,D = 0的差值約爲35%,而對於D = 10它是不明顯的。
int D = 0;
int K = 1 << (22 - D);
int J = 100 * (1 << D);
int sum = 0;
std::vector<int> a(K);
std::iota(a.begin(), a.end(), 0);
long start = clock();
for (int j = 0; j < J; ++j)
for (int i = 0; i < a.size(); ++i)
sum += a[i];
std::cout << double(clock() - start)/CLOCKS_PER_SEC << " " << sum << std::endl;
sum = 0;
std::vector<int*> b(a.size());
for (int i = 0; i < a.size(); ++i) b[i] = &a[i];
start = clock();
for (int j = 0; j < J; ++j)
for (int i = 0; i < b.size(); ++i)
sum += *b[i];
std::cout << double(clock() - start)/CLOCKS_PER_SEC << " " << sum << std::endl;
指針會導致間接尋址,從而導致額外的內存訪問。以及更多的空間正在使用當然可能會溢出緩存。 – 2015-03-08 19:04:21
'sum + = a [i];'通過溢出有符號'int'的邊界導致未定義的行爲。 (並且另外發生相同的錯誤)。即使您認爲這不應該成爲問題,但使用不調用未定義行爲的代碼進行測試也是一個不錯的主意。這可以通過改變爲'unsigned int sum = 0;'(或其他一些無符號類型,儘管選擇的類型可能會影響基準)來解決。 – 2015-03-08 19:39:45
如果您不處於最佳優化級別,基準並不意味着太多。如果使用「-O3」,則可能需要採取其他措施來防止優化循環。使'sum'變成'volatile'應該這樣做,但是最好仔細檢查生成的程序集以確保時序代碼不被重新排序。你也可以使用C++ 11的[高分辨率時鐘](http://stackoverflow.com/a/5524138/1505939)而不是'clock'。 – 2015-03-08 19:45:13