c - 循环的执行速度随变量位置而变化

标签 c arrays time execution

版本 A:

#include<time.h>
#include<stdio.h>
int main()
{

time_t start = time(0); //denote start time
int i,j; // initialize ints
static double dst[4096][4096]; //initialize arrays
static double src[4096][4096]; //
for(i=0; i<4096; ++i){
    for(j=0; j<4096; ++j){
        dst[i][j] = src[i][j];
}
    }
time_t end = time(0); //denote end time


double time = difftime(end, start); //take difference of start and end time to determine elapsed time
printf("Test One: %fms\n",time);

}

版本 B:

#include<time.h>
#include<stdio.h>
int main()
{

time_t start = time(0); //denote start time
int i,j; // initialize ints
static double dst[4096][4096]; //initialize arrays
static double src[4096][4096]; //
for(i=0; i<4096; ++i){
    for(j=0; j<4096; ++j){
        dst[j][i] = src[j][i];
}
    }
time_t end = time(0); //denote end time


double time = difftime(end, start); //take difference of start and end time to determine elapsed time
printf("Test One: %fms\n",time);

}

使用这个程序,我已经确定,如果将数组中 i 和 j 的位置颠倒,则执行时间会延长 1 秒。

为什么会这样?

最佳答案

在您的代码中,循环意味着“逐一遍历同一行中的地址,然后转到下一行”。但是如果把i和j的位置颠倒,就是“把同一列的地址,一个一个的遍历,到下一列”。

在C语言中,多维数组放在线性地址空间中,逐字节,逐行,所以dst[i][j] = src[i][j]你的情况意味着 *(dst + 4096 * i + j) = *(src + 4096 * i + j):

*(dst + 4096 * 0 + 0) = *(src + 4096 * 0 + 0);
*(dst + 4096 * 0 + 1) = *(src + 4096 * 0 + 1);
*(dst + 4096 * 0 + 2) = *(src + 4096 * 0 + 2);
//...

ij 颠倒意味着:

*(dst + 4096 * 0 + 0) = *(src + 4096 * 0 + 0);
*(dst + 4096 * 1 + 0) = *(src + 4096 * 1 + 0);
*(dst + 4096 * 2 + 0) = *(src + 4096 * 2 + 0);
//...

所以在第二种情况下额外的 1 秒是由于以非连续方式访问内存造成的。

您不需要自己计算时间,因为您可以在 linux/UNIX 上使用“time”命令运行您的程序:

$ time ./loop

这两种情况在我的 linux 机器上的结果:

$ time ./loop_i_j

real    0m0.244s
user    0m0.062s
sys     0m0.180s

$ time ./loop_j_i

real    0m1.072s
user    0m0.995s
sys     0m0.073s

关于c - 循环的执行速度随变量位置而变化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20064407/

相关文章:

C 只删除文件的一部分

c - 从Linux内核模块访问/dev/mem

c - 将结构保存到文件

c# - 在 C# 中对数组中的字符串进行二进制搜索

python - 一种几乎正确地定期触发函数的方法

c - 使用 Windows SEH 和 GCC 标签即值跳转到本地错误处理程序

c# - 如何在 C# 中声明一个包含固定数量固定大小字符串的数组?

time - Rust中的基准测试程序

自纪元以来的 Java 时间

arrays - 证明 Excel VBA Scripting.Dictionary 不保留项目插入顺序