我正在运行一个内存访问实验,其中使用了一个2D矩阵,每行都是内存页面的大小。实验包括使用行/列主要读取每个元素,然后使用行/列主要写入每个元素。被访问的矩阵被声明为全局范围,以减轻编程需求。是否比读取其他值更快地从内存读取“零”?
这个问题的关键在于,在静态声明测试矩阵的情况下,编译器将这些值初始化为零,我发现结果非常有趣。当我第一次读取操作时,即
rowMajor_read();
colMajor_read();
rowMajor_write();
colMajor_write();
然后我的colMajor_read操作很快完成。
但是,如果我读之前做的写操作,我们有:
rowMajor_write();
colMajor_write();
rowMajor_read();
colMajor_read();
与列主要读取操作增加幅度近一个数量级。
我认为它必须与编译器如何优化代码有关。由于全局矩阵对于每个元素都是相同的零,编译器是否完全删除了读操作?或者是从某种方式“更容易”从内存中读取同样为零的值?
我没有通过任何关于优化的特殊编译器命令,但我确实以这种方式声明了我的函数。
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))
是多余的,但我仍然包括它。我的印象是没有对易变变量实施优化。
任何想法?
我看着生成的程序集,colMajor_read函数的结果是一样的。 (汇编)非内联版本:http://pastebin.com/C8062fYB
我的猜测是系统缓存和预测。 – Nit 2014-10-31 17:24:25
我同意@Nit。缓存局部性很可能是方差的来源。缓存可以轻松地提高访问时间10倍。如果您真的怀疑编译器优化了远离操作(不太可能跨功能,但不是绝对不可能),请获取C函数的汇编程序输出以检查。 – 2014-10-31 17:32:02
挂在家伙身上。我不认为这一切都很复杂。因为这些方法是内联的,这意味着所有这些函数都在同一个编译单元中,所以编译器可以做很棒的事情。主要的是,它可以告诉你是否已经改变了自读写之后的变量,因此可以很容易地将代码重新解释为'temp = 0;',通过比较它会快得疯狂。你可以发布程序集吗? – IdeaHat 2014-10-31 17:50:03