【问题标题】:Nearly identical code with different running time - Why?几乎相同的代码具有不同的运行时间 - 为什么?
【发布时间】:2016-10-18 11:34:26
【问题描述】:

我正在测试两个几乎相同的代码,其中一个 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 循环:

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];
        } 

如果我打印 /user/bin/time -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

而 /user/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

【问题讨论】:

  • 这可能是因为您使用一种方法比使用另一种方法获得更多的缓存未命中。谷歌“缓存数据本地化”。
  • 尝试使用缓存分析工具(如cachegrind)运行您的代码。

标签: c


【解决方案1】:

基本上,您以不同的模式访问内存 - 您的第一种方法对内存缓存更友好,因为您要访问同一区域中的大量数据,然后继续访问下一块内存等

如果您想要一个真实世界的类比,假设您正在向 10 条不同的道路 (A-J) 分发传单,每条道路的门牌号为 1-10。您可以提供 A1、A2、A3...A10、B1、B2、B3...B10 等...或者您可以提供 A1、B1、C1...J1、A2、B2、C2...等。显然,第一种方法会更有效率。就像在计算机内存中一样 - 访问您最近访问过的内存“附近”内存比四处跳转更有效。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-01-31
    • 2012-04-15
    • 1970-01-01
    • 1970-01-01
    • 2013-02-26
    • 2017-03-15
    相关资源
    最近更新 更多