从内存中读取"零"比读取其他值更快吗?

she*_*lbc 8 c memory time

我正在运行一个内存访问实验,其中使用了一个2D矩阵,每行都是一个内存页面的大小.该实验包括使用行/列主要读取每个元素,然后使用行/列主要写入每个元素.正在访问的矩阵是使用全局范围声明的,以简化编程要求.

这个问题的关键是,在静态声明测试矩阵的情况下,编译器将值初始化为零,我发现的结果非常有趣.当我第一次读取操作时,即

rowMajor_read();
colMajor_read();
rowMajor_write();
colMajor_write(); 
Run Code Online (Sandbox Code Playgroud)

然后我的colMajor_read操作很快就完成了. 在此输入图像描述

但是,如果我在阅读之前进行写操作,我们有:

rowMajor_write();
colMajor_write();
rowMajor_read();
colMajor_read(); 
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

并且列主要读取操作增加了近一个数量级.

我认为它必须与编译器如何优化代码有关.由于每个元素的全局矩阵都相同,编译器是否完全删除了读取操作?或者以某种方式"更容易"从内存中读取相同为零的值?

我没有传递任何关于优化的特殊编译器命令,但我确实以这种方式声明了我的函数.

inline void colMajor_read(){
    register int row, col;
    register volatile char temp __attribute__((unused));
    for(col = 0; col < COL_COUNT; col++)
        for(row = 0; row < ROW_COUNT; row++)
            temp = testArray[row][col];
}
Run Code Online (Sandbox Code Playgroud)

因为我遇到了编译器temp从上面的函数中完全删除变量的问题,因为它从未被使用过.我认为,同时具有volatile__attribute__((unused))是多余的,但我把它不过.我的印象是没有对volatile变量实现优化.

有任何想法吗?


我查看了生成的程序集,结果与colMajor_read函数的结果相同.(汇编)非内联版本:http://pastebin.com/C8062fYB

Fat*_*ror 7

在将值写入矩阵之前和之后检查进程的内存使用情况.例如,如果它存储在Linux上的.bss部分中,则归零页面将映射到具有写时复制语义的单个只读页面.因此,即使您正在阅读大量地址,您也可能一遍又一遍地阅读相同的物理内存页面.

这个页面http://madalanarayana.wordpress.com/2014/01/22/bss-segment/有一个很好的解释.

如果是这种情况,那么之后再次将矩阵归零并重新运行读取测试,它应该不再那么快.