- 1、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。。
- 2、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载。
- 3、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
- 4、该文档为VIP文档,如果想要下载,成为VIP会员后,下载免费。
- 5、成为VIP后,下载本文档将扣除1次下载权益。下载后,不支持退款、换文档。如有疑问请联系我们。
- 6、成为VIP后,您将拥有八大权益,权益包括:VIP文档下载权益、阅读免打扰、文档格式转换、高级专利检索、专属身份标志、高级客服、多端互通、版权登记。
- 7、VIP文档为合作方或网友上传,每下载1次, 网站将根据用户上传文档的质量评分、类型等,对文档贡献者给予高额补贴、流量扶持。如果你也想贡献VIP文档。上传文档
查看更多
cpu缓存的使用和嵌套循环的执行
cpu缓存的使用和嵌套循环的执行
--由剑剑同学的两段代码引发的讨论
跟Jay同学讨论循环不变量的优化问题,在email里比较难说清楚,还是发到blog上来方便贴代码。
剑剑同学写道某型CPU的一级数据缓存大小为16K字节,cache块大小为64字节;二级缓存大小为256K字节,cache块大小为4K字节,采用二路组相联。经测试,下面两段代码运行时效率差别很大,请分析哪段代码更好,以及可能的原因。
为了进一步提高效率,你还可以采取什么办法?
A段代码:
C代码
int matrix[1023][15];constchar*str=this is astr;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段代码
C代码
int matrix[1025][17];constchar*str=this is astr;int i,j,sum=0;for(i=0;i 17;i++){for(j=0;j 1025;j++){sum+=matrix[j][i]+strlen(str);}}
这条问题和大家分享下,希望大家一起讨论。呵呵。
这个问题的主要关注点很明显是关于存储器层次(memory hierarchy)与缓存(caching)的。先看看相关背景。
存储技术在几个不同层次上发展,其中存储密度高、单价便宜的存储器速度比较慢,速度快的存储器的存储密度则相对较低且价格昂贵。为了在性能与价格间找到好的平衡点,现代计算机系统大量采用了缓存机制,使用小容量的高速存储器为大容量的低速存储器提供缓存。
最快的存储器是CPU里的各种寄存器,其次是在CPU芯片内的L1缓存,再次是在CPU芯片内或者离CPU很近的L2缓存,然后可能还有L3缓存,接着到主内存,后面就是各种外部存储设备如磁盘之类,最后还有诸如网络存储器之类的更慢的存储器。
L1缓存可能会成对出现,一个用于指令,另一个用于数据。L2缓存和后面的缓存则设计得更通用些。由于主内存比磁盘快很多但相对来说价格昂贵许多,而同时运行多个程序所需要的存储空间通常不能直接被主内存满足,所以现代操作系统一般还有虚拟内存,使用磁盘作为主内存的扩充。虚拟内存也可以反过来看作所有虚拟内存都是在磁盘上的,将其中活跃的一些放在物理内存里是一种优化(Eric Lippert如是说)。
如果要访问的数据位于存储器层次的较低层,则数据是逐层传递到CPU的。例如,程序要访问某个地址的数据,在L1缓存里没有发现(称为L1缓存不命中,L1 cache miss),则跑到L2缓存找;找到的话,会先把这一数据及邻近的一块数据复制到L1缓存里,然后再从L1缓存把需要的数据传给CPU。
为了充分利用缓存机制,程序应该有良好的局部性(locality)。局部性指的是程序行为的一种规律性:在程序运行中的短时间内,程序访问数据位置的集合限于局部范围。局部性有两种基本形式:时间局部性(temporal locality)与空间局部性(spatial locality)。由于指令也可以看作数据的一种特殊形式,因而局部性对指令来说也有效。
时间局部性指的是反复访问同一个位置的数据:如果程序在某时刻访问了存储器的某个地址,则程序很可能会在短时间内再次访问同一地址。例如,在执行一个循环,则循环的代码就有好的时间局部性;又例如在循环里访问同一个变量,则对该变量的访问也有好的时间局部性。
空间局部性指的是反复访问相邻的数据:如果程序在某时刻访问了存储器的某个地址,则程序很可能会在短时间内访问该地址附近的存储器空间。例如按顺序执行的指令就有良好的空间局部性;又例如按存储顺序挨个遍历数组,也有良好的空间局部性。
还有很多很重要的背景信息,这里就不详细写了。我主要是读《Computer Organization and Architechture:Designing for Performance,5th Edition》和《Computer Systems:A Programmers Perspective》学习的。大一的时候也好好上了计算机组成与结构的课,用的课本就是前一本书,还能记得一些。
那么回到开头的题目。两段代码有一些特征是相同的,包括:
(1)它们都使用了一个int矩阵,而且行的宽度比列的长度要短。
(2)它们都含有一个char指针,指向的是一个字符串字面量。这意味着对该字符串调用strlen()总是会得到同一个值,而且该值在编译时可计算。
(3)它们都遍历了整个矩阵,并且对矩阵中每个元素的值求和。
两段代码主要的差异是:
(1)遍历顺序不同。A按行遍历,B按列遍历。
(2)内外循环的分布不同。使用两
原创力文档


文档评论(0)