我正在运行一个内存访问实验,其中使用了一个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
在将值写入矩阵之前和之后检查进程的内存使用情况.例如,如果它存储在Linux上的.bss部分中,则归零页面将映射到具有写时复制语义的单个只读页面.因此,即使您正在阅读大量地址,您也可能一遍又一遍地阅读相同的物理内存页面.
这个页面http://madalanarayana.wordpress.com/2014/01/22/bss-segment/有一个很好的解释.
如果是这种情况,那么之后再次将矩阵归零并重新运行读取测试,它应该不再那么快.