我的目標是使用簡單代碼來測量(不同)緩存的效果。我正在關注這篇文章,特別是第20頁和第21頁: https://people.freebsd.org/~lstewart/articles/cpumemory.pdf測量C++代碼的CPU週期
我正在使用64位的linux。 L1d緩存爲32K,L2爲256K,L3爲25M。
這是我的代碼(I編譯此代碼與克++無標誌):
#include <iostream>
// ***********************************
// This is for measuring CPU clocks
#if defined(__i386__)
static __inline__ unsigned long long rdtsc(void)
{
unsigned long long int x;
__asm__ volatile (".byte 0x0f, 0x31" : "=A" (x));
return x;
}
#elif defined(__x86_64__)
static __inline__ unsigned long long rdtsc(void)
{
unsigned hi, lo;
__asm__ __volatile__ ("rdtsc" : "=a"(lo), "=d"(hi));
return ((unsigned long long)lo)|(((unsigned long long)hi)<<32);
}
#endif
// ***********************************
static const int ARRAY_SIZE = 100;
struct MyStruct {
struct MyStruct *n;
};
int main() {
MyStruct myS[ARRAY_SIZE];
unsigned long long cpu_checkpoint_start, cpu_checkpoint_finish;
// Initializing the array of structs, each element pointing to the next
for (int i=0; i < ARRAY_SIZE - 1; i++){
myS[i].n = &myS[i + 1];
for (int j = 0; j < NPAD; j++)
myS[i].pad[j] = (long int) i;
}
myS[ARRAY_SIZE - 1].n = NULL; // the last one
for (int j = 0; j < NPAD; j++)
myS[ARRAY_SIZE - 1].pad[j] = (long int) (ARRAY_SIZE - 1);
// Filling the cache
MyStruct *current = &myS[0];
while ((current = current->n) != NULL)
;
// Sequential access
current = &myS[0];
// For CPU usage in terms of clocks (ticks)
cpu_start = rdtsc();
while ((current = current->n) != NULL)
;
cpu_finish = rdtsc();
unsigned long long avg_cpu_clocks = (cpu_finish - cpu_start)/ARRAY_SIZE;
std::cout << "Avg CPU Clocks: " << avg_cpu_clocks << std::endl;
return 0;
}
我有兩個問題:
1-我變化ARRAY_SIZE爲1〜1,000,000(如此的尺寸我的數組範圍在2B到2MB之間),但平均CPU時鐘始終爲10.
根據該PDF(第21頁的圖3-10),如果陣列可以達到3-5個時鐘完全適合L1,當超過L1的尺寸時可以獲得更高的數字(9個週期)。
2-如果我將ARRAY_SIZE增加到1,000,000以上,我會得到分段錯誤(core dumped),這是由於堆棧溢出造成的。我的問題是,使用動態分配(MyStruct *myS = new MyStruct[ARRAY_SIZE]
)是否會導致任何性能損失。
您需要讓您的編譯器進行基準測試優化。所以用'g ++ -O2 -Wall -mtune = native'編譯;不要使用'rdtsc',但讀[時間(7)](http://man7.org/linux/man-pages/man7/time.7.html) –
@BasileStarynkevitch我用這些標誌,現在平均CPU時鐘是4,仍然不管陣列的長度。這就是說,要麼所有的東西都可以適合L1d(事實並非如此),或者預取能夠做出出色的工作(我懷疑)。 – narengi
@BasileStarynkevitch另外,請你告訴我爲什麼rdtsc不適合這個目的? – narengi