百度试题讲解:CPU的数据缓存问题

本文通过对比两种不同遍历二维数组的方式,分析了哪种代码在CPU缓存中更有效,并提出了进一步优化建议,如对齐缓存块边界。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

某型CPU的一级数据缓存大小为16K字节,cache块大小为64字节;二级缓存大小为256K字节,cache块大小为4K字节,采用二路组相联。经测试,下面两段代码运行时效率差别很大,请分析哪段代码更好,以及可能的原因。
为了进一步提高效率,你还可以采取什么办法?
A段代码

int matrix[1023][15];
const char *str = "this is a str";
int i, j, tmp, sum = 0;
tmp = strlen(str);
for(i = 0; i < 1023; i++) {
    for(j = 0; j < 15; j++) {
        sum += matrix[i][j] + tmp;
    }
}
B段代码

int matrix[1025][17];
const char *str = "this is a str";
int i, j, sum = 0;
for(i = 0; i < 17; i++) {
    for(j = 0; j < 1025; j++) {
        sum += matrix[j][i] + strlen(str);
    }
}
思路:(这是绝对的牛人,我的大学的恩师孙志岗给的思路)
这就是利用局部性原理。尽量在一段时间内,让访问的内存控制在一个小局部范围内,才能保证cache命中率高。很明显,程序1对内存的访问是连续的,2是跳跃的。所以1的效率会高。如果想让1更高,就是尽量去对齐cache中的页面边界。
按照以上思路我给出一种解法:(不保证最优,欢迎讨论)
1,谁快我就不说了,两点(恩师说了最关键的一点,我补充一个细节:strlen调用次数1为一次,2为*****次)
2,采取这样的办法:
为了对齐cache,在int matrix[1023][15]; 时,把[15]换作[16]恰好对齐一级缓存的cache块 ,然后matrix的总大小不应该为二级cache的块大小的整数倍,如果有超出的,尽量在内存上对齐,即定义matrix为 int matrix[1024][16];
在for进行处理的时候,可以根据要求浪费一点内存(即不访问),以空间换取宝贵的时间!
http://jingyixiao.com/137-%e6%8a%80%e6%9c%af%e5%ad%a6%e4%b9%a0/%e4%b8%80%e8%b5%b7%e6%9d%a5%e5%81%9a%e7%99%be%e5%ba%a6%e9%a2%98-%e7%99%be%e5%ba%a6%e8%af%95%e9%a2%98%e8%ae%b2%e8%a7%a3%ef%bc%9acpu%e7%9a%84%e6%95%b0%e6%8d%ae%e7%bc%93%e5%ad%98%e9%97%ae%e9%a2%98.html

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值