这是我做的一个小测试,结果让我感到惊讶:做两次相同的循环大约是循环一次的两倍。我猜它是因为内存访问?
float* A = new float[1000000];
float* B = new float[1000000];
int h,w;
h = w = 1000;
CString txt;
double time1, time2;
time1 = Timer::instance()->getTime();
for(int j = 0; j < h; j++){
for(int i = 0; i < w; i++){
A[i+j*w] = 1;
B[i+j*w] = 1;
}
}
time2 = Timer::instance()->getTime();
txt.Format(_T("Both in same loop = %f"),time2-time1);
AfxMessageBox(txt);
time1 = Timer::instance()->getTime();
for(int j = 0; j < h; j++){
for(int i = 0; i < w; i++){
A[i+j*w] = 1;
}
}
for(int j = 0; j < h; j++){
for(int i = 0; i < w; i++){
B[i+j*w] = 1;
}
}
time2 = Timer::instance()->getTime();
txt.Format(_T("Different loops = %f"),time2-time1);
AfxMessageBox(txt);
答案 0 :(得分:8)
它可能是CPU缓存,但更可能是并发内存访问。当您访问array1[x]
,然后紧接array2[x]
之后,这些是内存中两个非常不同的位置,并且很难进行优化。但是array[0]
,array[1]
,array[2]
等都在连续的内存中,访问效率更高。 Intel seems to agree
答案 1 :(得分:4)
在开始测量时间之前,可能需要添加一个额外的,不定时的循环。
答案 2 :(得分:2)
这是一个缓存问题。在您同时访问A
和B
的循环中,CPU被强制加载到缓存中,因此其中每个数组的元素较少。在其他循环中,缓存中充满了A
个(或B
个)元素,因此缓存未命中的次数较少。