void row_order (){
char A[1024][1024] = {0};
char B[1024][1024] = {0};
char C[1024][1024] = {0};
for(int i = 0 ; i<1024;i++){
for(int j = 0 ; j<1024;j++){
C[i][j] = A[i][j] * B[i][j];
}
}
}
int main() {
for(int i = 0 ; i< 1000; i++){
row_order();
}
}
= =比;C[j][i] = A[j][i] * B[j][i];
通过交换C数组中的i和j变量,代码的性能提高了400%。原因是什么?[我][j][j][我]
在第一种情况下,C[i][j] = A[i][j] * B[i][j];
,您访问附近位置的内存。
例如,对于i=0
,j=0
和1
,您将访问A[0][0]
,A[0][1]
,它们接近位置。所以当CPU加载A[0][0]
时,它有机会放入缓存A[0][0]
,A[0][1]
,A[0][2]
…后面的值
在第二种情况下,C[j][i] = A[j][i] * B[j][i];
,您访问远位置的内存。
例如,对于i=0
,j=0
和1
,您将访问A[0][0]
和A[1][0]
,它们的位置较远。因此,当CPU加载A[0][0]
时,它没有机会加载
你可以在这里测试:tio.run
行为与int
相同(减小数组大小)。
关于cache的一些阅读:
- https://dzone.com/articles/optimizing-memory-access-with-cpu-cache
- http://pld.cs.luc.edu/courses/264/spr19/notes/cache.html
请注意,使用-O2
选项,您的代码将更快,因为它可以优化,尝试在这里看到它godbolt.org