正在阅读"零"从记忆中读取其他值更快?

时间:2014-10-31 17:21:57

标签: c memory time

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

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

rowMajor_read();
colMajor_read();
rowMajor_write();
colMajor_write(); 

然后我的colMajor_read操作很快就完成了。 enter image description here

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

rowMajor_write();
colMajor_write();
rowMajor_read();
colMajor_read(); 

enter image description here

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

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

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

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

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

有什么想法吗?


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

1 个答案:

答案 0 :(得分:7)

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

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

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