2016-10-18 135 views
5

我正在测试两个几乎相同的代码,其中一个for循环的差异很小。第一个使用三个循环迭代索引y,z,x而第二次迭代x,z,y具有不同运行时间的几乎相同的代码 - 为什么?

我的问题是为什么在用户时间和挂钟时间的差异?是因为一个代码和另一个代码中的内存位置?

test_1.c时:

#define N 1000 

// Matrix definition 
long long int A[N][N],B[N][N],R[N][N]; 

int main() 
{ 
    int x,y,z; 
    char str[100]; 

/*Matrix initialization*/ 
    for(y=0;y<N;y++) 
     for(x=0;x<N;x++) 
     { 
      A[y][x]=x; 
      B[y][x]=y; 
      R[y][x]=0; 
     } 
/*Matrix multiplication*/ 
    for(y=0;y<N;y++) 
     for(z=0;z<N;z++) 
      for(x=0;x<N;x++) 
      { 
       R[y][x]+= A[y][z] * B[z][x]; 
      } 
exit(0); 
} 

在第二个代码(test_2.c)的差异及其对持续循环:

for(x=0;x<N;x++) 
    for(z=0;z<N;z++) 
     for(y=0;y<N;y++) 
     { 
      R[y][x]+= A[y][z] * B[z][x]; 
     } 

如果我打印/用户/斌/时间 - v ./test_1我得到以下数据:

Command being timed: "./test_1" 
User time (seconds): 5.19 
System time (seconds): 0.01 
Percent of CPU this job got: 99% 
Elapsed (wall clock) time (h:mm:ss or m:ss): 0:05.22 

虽然/用户/ bin/time会-v ./test_2提供了以下数据:

Command being timed: "./test_2" 
User time (seconds): 7.75 
System time (seconds): 0.00 
Percent of CPU this job got: 99% 
Elapsed (wall clock) time (h:mm:ss or m:ss): 0:07.76 
+2

这可能是因为您使用一种方法获取的缓存未命中次数高于另一种。 Google“缓存数据区域”。 –

+0

尝试使用['cachegrind'](http://valgrind.org/docs/manual/cg-manual.html)等缓存分析工具运行您的代码。 –

回答

17

基本上,你所访问的内存在不同的模式 - 你的第一种方法是更加友好的内存缓存,因为你所访问大量的数据在同一个区域,然后移动到下一块内存等等。

如果你想要一个现实世界的比喻,想象你正在为10条不同的道路(AJ)提供传单,其中每个道路都有房屋号1-10。您可以交付A1,A2,A3 ... A10,B1,B2,B3 ... B10等等,或者您可以交付A1,B1,C1 ... J1,A2,B2,C2 ...等。显然,第一种方法将会更有效率。就像在计算机内存中一样 - 访问最近访问的内存“接近”的内存比跳过内存效率更高。

相关问题