网站大量收购闲置独家精品文档,联系QQ:2885784924

I代码优化之优化条件分支 I2).docxVIP

  1. 1、本文档共9页,可阅读全部内容。
  2. 2、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。
  3. 3、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载
  4. 4、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
  5. 5、该文档为VIP文档,如果想要下载,成为VIP会员后,下载免费。
  6. 6、成为VIP后,下载本文档将扣除1次下载权益。下载后,不支持退款、换文档。如有疑问请联系我们
  7. 7、成为VIP后,您将拥有八大权益,权益包括:VIP文档下载权益、阅读免打扰、文档格式转换、高级专利检索、专属身份标志、高级客服、多端互通、版权登记。
  8. 8、VIP文档为合作方或网友上传,每下载1次, 网站将根据用户上传文档的质量评分、类型等,对文档贡献者给予高额补贴、流量扶持。如果你也想贡献VIP文档。上传文档
查看更多
代码优化-之-优化条件分支??HouSisong@GM 2007.10.05tag:代码优化,条件分支,饱和,MMX,CMOV,掩码摘要: 条件分支是编程中经常使用的基本操作,然而在某些时候它确可能带来严重的性能问题.当前的CPU都能对条件分支做预测(动用了庞大的晶体管资源),如果分支预测正确,那么条件指令一般只需要花费一个CPU周期,而如果预测错误,那么将可能花费几十个CPU周期! 本文将讨论条件分支的一些有效优化方法.正文: 文章为收集加经验编辑而成的文章,对优化条件分支做了较全面的阐述.?文章假定的CPU为x86,示例代码为C/C++.A.什么是分支? 分支是编程语言中的常见结构;分支可以分为条件分支和非条件分支; 条件分支举例: 条件判断: if (a255) a=255; else if (a0) a=0; 循环: for (i=0;i1000;++i) { ...; } while(!bOk) { bOk=...;? }? ... 对应汇编指令的jnz,jg等等 非条件分支举例: 函数调用(call),函数返回(return/ret),软件中断(int 3),直接跳转(jmp),...??B.CPU分支预测错误的惩罚由来 为了加快CPU的处理频率,现代CPU都设计了多级流水线,有的甚至有20级以上;当CPU遇到跳转指令的时候,会做一个预测,把预测的分支代码载入流水线,当发现预测错误的时候,需要清空流水线,重新载入正确的分支到流水线;那么预测错误的代价周期数至少应该和流水线长度相当;然而考虑到各级的缓存失效、指令解码等等,实际损失的周期数有可能是流水线长度的几倍! 对于非条件分支,一般来说CPU都能得到相当高的预测准确率;我们主要来讨论一下条件分支的预测;?(有人可能会说,当CPU遇到条件分支时不做预测不就没有预测错误的惩罚了吗??这种流水线空着的惩罚实质和每次都预测错误然后清空流水线的代价相当,退一步说就算每次随机选择一个分支来执行也有50%的收益)C:需要优化的条件分支 当前的CPU对各种简单的条件分支模式都能做出很的预测,比如奇偶模式: for (int i=0;i1000;++i) { if (a%2==0) do0(); else do1(); } 而对于随机的分支模式,再好的预测器也不可能做出好的预测; 我们要优化条件分支,这些分支代码应该满足:该分支处于时间热点上,并且分支预测错误率较高;这样我们才能得到优化的收益; (intel的VTune工具可以采样分支预测错误率)D.把条件分支移动到热点外 比如前面的那个奇偶循环模式,假设CPU不能正确预测,那么可以尝试改写为两个for循环,一个处理偶数,一个处理奇数; 一些图像处理算法里(比如模板运算/卷积运算/形态学运算等),经常需要判断边界像素点,进行特殊处理;可以考略的优化方案是把边界区域和内部区域分开处理;或者条件允许的话,可以扩大原图像的边界,形成哨兵数据,这样访问像素的时候就不用考虑越界的问题了;E.合并多个条件来减少条件分支 比如: if ( (a0==0) (a1==0) (a2==0) ) ... 编译器将生成3个条件跳转指令,而且使分支可预测性大大降低; 可以改写为: if ( (a0|a1|a2)==0 ) ... 从而同时改进代码和分支预测率; 比如:if ( (b0=64) || (b1=64)) ...? //b0,b1=0 改写为: if ( (b0|b1)=64 ) ... (请尝试证明其等价性)F.将出现几率高的分支优先处理,从而提高预测准确率G.优化第一次执行的条件分支 当CPU第一次执行到一个条件分支的时候,默认的预测分支规则是不跳转的那个分支(也就是紧接着条件跳转指令之后的那些指令);? (下面的内容主要讨论完全替换掉分支的一些方法; 移除分支意味着代码的性能可以不受输入数据的影响,并可能能更好的使用SIMD类指令)H.使用条件状态值生成掩码来移除条件分支 比如: if (color0) color=0; 改写为: color =-(color=0);//求负是为了生成掩码,也可以减1来生成掩码 这里的思路是利用比较来产生0或1值,然后利用生成的值参与运算从而移除了分支;?? 比如: if (color255) color=255; 改写为: color = (color | -(color255) ) 0xFF; 比如: if (a=b) return a; else return b; 改写为: return? a + ( (b-a) -(ba) ); (警告:这里利用了C/C++中比较的结果是0或1,在其他语言或编译器中可能定义不同)I.使用带符号的移位生成掩码来移除条件分支 (建议使用该方案替代上面的条件状

文档评论(0)

yingrong + 关注
实名认证
文档贡献者

该用户很懒,什么也没介绍

1亿VIP精品文档

相关文档