我有以下問題:爲什麼不同整數大小的數組具有不同的性能?
的寫入時間到std::array
爲int8
,int16
,int32
和int64
與每個大小增加一倍。我可以理解8位CPU的這種行爲,但不是32/64位。
爲什麼32位系統需要比保存8位值多4倍的時間來保存32位值?
這裏是我的測試代碼:
#include <iostream>
#include <array>
#include <chrono>
std::array<std::int8_t, 64 * 1024 * 1024> int8Array;
std::array<std::int16_t, 64 * 1024 * 1024> int16Array;
std::array<std::int32_t, 64 * 1024 * 1024> int32Array;
std::array<std::int64_t, 64 * 1024 * 1024> int64Array;
void PutZero()
{
auto point1 = std::chrono::high_resolution_clock::now();
for (auto &v : int8Array) v = 0;
auto point2 = std::chrono::high_resolution_clock::now();
for (auto &v : int16Array) v = 0;
auto point3 = std::chrono::high_resolution_clock::now();
for (auto &v : int32Array) v = 0;
auto point4 = std::chrono::high_resolution_clock::now();
for (auto &v : int64Array) v = 0;
auto point5 = std::chrono::high_resolution_clock::now();
std::cout << "Time of processing int8 array:\t" << (std::chrono::duration_cast<std::chrono::microseconds>(point2 - point1)).count() << "us." << std::endl;
std::cout << "Time of processing int16 array:\t" << (std::chrono::duration_cast<std::chrono::microseconds>(point3 - point2)).count() << "us." << std::endl;
std::cout << "Time of processing int32 array:\t" << (std::chrono::duration_cast<std::chrono::microseconds>(point4 - point3)).count() << "us." << std::endl;
std::cout << "Time of processing int64 array:\t" << (std::chrono::duration_cast<std::chrono::microseconds>(point5 - point4)).count() << "us." << std::endl;
}
int main()
{
PutZero();
std::cout << std::endl << "Press enter to exit" << std::endl;
std::cin.get();
return 0;
}
我編譯它在linux下有:g++ -o array_issue_1 main.cpp -O3 -std=c++14
和我的結果如下:
Time of processing int8 array: 9922us.
Time of processing int16 array: 37717us.
Time of processing int32 array: 76064us.
Time of processing int64 array: 146803us.
如果我-O2
,那麼結果編譯是int8
差5倍!
您也可以在Windows中編譯此源代碼。你會得到類似的結果之間的關係。
更新#1
當我和-02編譯,然後我的結果如下:
Time of processing int8 array: 60182us.
Time of processing int16 array: 77807us.
Time of processing int32 array: 114204us.
Time of processing int64 array: 186664us.
我沒有分析彙編輸出。我的主要觀點是,我想用C++編寫高效的代碼和諸如此類的東西,從性能角度來看,像std::array
這樣的東西可能具有挑戰性,並且以某種方式違反直覺。
你看過裝配輸出了嗎? –
我[寫了一個基準測試](https://github.com/travisdowns/uarch-bench),其中包括測試:「BYTE」,「WORD」,「DWORD」和「QWORD」的代價。其結果是,它們都在現代英特爾CPU上完全採用1個週期,除非它們跨越高速緩存線邊界,此時它們需要2個週期。請注意,如果您在字節顆粒位置隨機寫入,則較大的值更可能跨越緩存行邊界。實際上,這個基準和大多數代碼將使用對齊的緩衝區,所以根本不會出現跨越邊界。 – BeeOnRope
你的「主要觀點」是亂碼,你可以把它編輯清楚嗎? PS除非在算法/庫和C++抽象機器及其對象和數據類型的層次上,否則不應該擔心在C++中「高效」,直到遇到並找到特定的瓶頸爲止,此時您仍應該尋求解決方案算法/數據類型/對象級別,然後是分配器,所有這些仍然使用C++,如果你曾經關心過機器代碼,那麼你應該解決機器代碼而不是C++中的問題。 – philipxy