IntelX86优化指南阅读笔记--通用优化(前端)

更新时间:2023-07-02 02:08:36 阅读: 评论:0

IntelX86优化指南阅读笔记--通⽤优化(前端)PROCESSOR PERSPECTIVES
以下优化建议,在不同微架构下收益差别较⼤:
指令译码的吞吐量很重要。利⽤好decoded ICache,Loop Stream Detector和macro-fusion能进⼀步提⾼CPU前端性能。
充分利⽤好4个译码器来产⽣代码。利⽤好micro-fusion和macro-fusion,这样其中3个简单译码器就再被限制为只能译码只含有⼀条uop的简单指令。
Sandy Bridge, Ivy Bridge 和 Haswell微架构,优化代码⼤⼩来提⾼前端性能,取决于代码⼤⼩与decode ICache⼤⼩的关系。
只使⽤⼀个寄存器的⼀部分来写⼊数据,在不同微架构下会导致差异很⼤的性能惩罚。为了避免部分写⼊寄存器引起的伪依赖,使⽤完整的寄存器写⼊。
硬件预取通常能够有效减少内存延时和指令访问。但是不同微架构下可能需要⾃⼰选择特定的硬件预取实现算法。
OPTIMIZING THE FRONT END
优化CPU前端包括两⽅⾯:
保持稳定的速度向cpu后端提供uop。错误的分⽀预测会打断uop流,或者导致后端在错误的uop路径上浪费资源。⼤量的调优⼯作聚焦在这个⽅⾯,利⽤Branch Prediction Unit。
2015职称英语成绩查询提供uop流来尽可能的充分利⽤执⾏带宽和retirement带宽。
Branch Prediction Optimization
分⽀优化对性能有显著地影响。通过理解分⽀流和提⾼其预测性,你可以显著提⾼代码性能。
帮助分⽀预测的⽅法有:
保持代码和数据在不同page,这⼀点⾮常重要。
尽可能的减少分⽀。
安排代码使其符合静态分⽀预测算法。
在spin-wait循环中使⽤PAUSE指令。
常回家看看英文版
使⽤inline函数,和让call和return指令尽可能配对。
对于⼩于等于16次的循环,使⽤unroll编译指令把代码展开成顺序执⾏(除⾮这个展开使代码⼤⼩增加过⼤)。
Avoid putting two conditional branch instructions in a loop so that both have the same branch target address and, at the same time, belong to (i.e. have their last bytes’ address within) the same 16- byte aligned code block. (我还没弄明⽩)
Eliminating Branches
消除分⽀能够提⾼性能是因为:
减少了分⽀错误预测的概率。
减少了对branch target buffer (BTB) 的消耗。
有四个最重要的⽅法来消除分⽀:
安排代码块连续执⾏。
对循环利⽤unroll编译指令。
使⽤CMOV指令。该指令是条件移动指令,伪代码:
if (cond) {
mov dst, src
} el {
nop
}
我们常⽤的分⽀跳转指令jump,当预测失败时,必须回退重新执⾏。但是CMOV不是分⽀跳转,他会顺序执⾏下去,保证了流⽔线的通畅。但是相应的,它的执⾏开销⽐jump指令⼤。
使⽤SETCC指令。伪代码:
IF condition
THEN DEST ← 1;
ELSE DEST ← 0;
FI;
同样的,该指令避免了分⽀跳转。
Asmbly/Compiler Coding Rule 1. (MH impact, M generality):la cros
安排代码让基本代码块连续存放,并消除不需要的分⽀。
Asmbly/Compiler Coding Rule 2. (M impact, ML generality) :
当分⽀跳转很难预测时,可以⽤CMOV和SETCC替代分⽀。值得注意的是,这两个指令相⽐成功的分⽀预测指令,会有额外的开销,因为它们其实在内部把两个分⽀都执⾏了。在使⽤这两个指令替换分⽀跳转指令时,要对⽐其总开销。
Spin-Wait and Idle Loops ####
Memory Order Violation: load 和store指令是可以乱序执⾏,当load投机执⾏,先于store指令时,读取了错误的数据,就会导致这个性能 惩罚。
从Pentium 4开始的微架构,在⾃旋锁中加⼊PAUSE指令,可以显著地减少内存发⽣Memory Order Violation的概率。
Static Prediction ####
静态分⽀预测算法,不占⽤BTB。
Asmbly/Compiler Coding Rule 3. (M impact, H generality):
向前跳转分⽀时,安排最可能执⾏的代码放到条件分⽀ fall-through处。
向后跳转分⽀时,安排最不可能执⾏的代码放到条件分⽀ fall-through处。
有条件向前跳转为不跳转
//Forward condition branches not taken (fall through)
IF {….2011泉州中考
↓ 预测执⾏这⾥
}
有条件向后跳转为跳转
/
/Backward conditional branches are taken
LOOP {…
预测继续执⾏循环体
↑ −− }
⽆条件跳转直接跳转
//Unconditional branches taken
JMP
——→ 预测直接执⾏跳转指令
Inlining, Calls and Returns
return address stack:我估计是⼀个独⽴的硬件,它含有16个entries。⽤来记录返回地址。求人帮忙说
call和return指令会打断流⽔线,因为他们造成了执⾏流程的跳转。⽤BTB可以提前预测call跳转,⽤return address stack则可以提前预测return跳转。当函数嵌套超过16个后,性能会下降。
请确保call指令和return指令严格配对,这样return address stack超过阈值的可能性会⼤⼤减少。
Asmbly/Compiler Coding Rule 4. (MH impact, MH generality):
paul最近调⽤的call要和最近的return匹配。不要⾃⼰把返回地址压⼊⽤户栈然后call函数,这样会造成call和return不匹配。
call和return是昂贵的操作,使⽤inline替代它们:
可以省略参数传递开销。
对编译器来说,inline函数有更⼤的⼏率可以优化。
如果inline函数有分⽀跳转,包含inline函数的caller有更多的上下⽂来提⾼分⽀预测。
分⽀预测失败在函数中的惩罚⽐在inline函数中的⼤。
Asmbly/Compiler Coding Rule 5. (MH impact, MH generality):
如果inline⼀个函数可以减少代码⼤⼩,或者这个函数本⾝就很⼩,调⽤频率很⾼,那就inline它。
Asmbly/Compiler Coding Rule 6. (H impact, H generality):
如果inline⼀个函数增加了代码⼤⼩,使它不能完全放在trace cache(这个应该只有Intel NetBust微架构才有)中,那么不要inline它。
Asmbly/Compiler Coding Rule 7. (ML impact, ML generality):
函数嵌套超过了16个,考虑inline其中⼀些函数。
Asmbly/Compiler Coding Rule 8. (ML impact, ML generality):
函授研究生函数内部逻辑的分⽀预测成功率很低时,可以考虑inline这个函数。这是因为分⽀预测失败,导致提前执⾏的return指令⽆意义,会增加性能惩罚。
Asmbly/Compiler Coding Rule 9. (L impact, L generality):
如果⼀个函数的最后阶段是调⽤另外⼀个函数,可以考虑优化成⽤jump替代call指令,这样节省了⼀个call/return对。这个⼯作编译器来做。
Asmbly/Compiler Coding Rule 10. (M impact, L generality):
在⼀个16字节的指令块中不要超过4个分⽀。
Asmbly/Compiler Coding Rule 11. (M impact, L generality):
在⼀个16字节的指令块中不要有超过2个循环逻辑。
Code Alignment
仔细的安排代码布局可以增加cache和内存局部性。经常执⾏的基本代码块应该在内存中连续布局。不怎么执⾏的代码,⽐如错误处理,可以单独存放。
direct branches:jump的地址是具体数值。
indirect branch:jump的地址保存在寄存器或内存中,需要通过计算才能知道跳转地址。
Asmbly/Compiler Coding Rule 12. (M impact, H generality):
如果uop是从DSB(Decode ICache)中获取的。最常执⾏的direct branches,应该把指令部分放在64B cache line的尽可能尾部,跳转指令的⽬的放在64B cache line的尽可能⾸部。
如果uop是从legacy decode pipeline中获取的。最常执⾏的direct branches,应该把指令部分放在16B对齐的内存块的尽可能尾部,跳转指令的⽬的放在16B对齐的尽可能⾸部。
没看明⽩,编译器怎么知道uop能从哪⾥来的,还能动态调整指令布局懵逼,或许即时编译器可以利⽤这个优化,看⼿册该优化效果还挺⼤的。求⼤神指点。
大自然在说话
Asmbly/Compiler Coding Rule 13. (M impact, H generality):
音响没有声音怎么办
如果⼀个条件语句的执⾏体,不怎么执⾏,它应该放到程序的其他部分,如果这个执⾏体⼏乎不怎么执⾏,那它应该放到⼀个不同的code page。
继续懵逼,编译器究竟怎么利⽤这个点的
Branch Type Selection
indirect call:call的地址保存在寄存器或内存中,需要通过计算才能知道跳转地址,这将打断流⽔线。
对于indirect branch和indirect call指令,缺省是预测其会失败,流⽔线会使⽤其后⼀条指令(fall-through path, 没办法,跳转地址要计算才知道,缺省没法预测)。之后可以通过动态预测硬件来覆盖这个缺省选择。
对于indirect call,fall-through不会造成性能问题,即使预测错误,反正call的函数会return回来继续执⾏下⼀条指令,预测只是提前执⾏了⽽已。
Asmbly/Compiler Coding Rule 14. (M impact, L generality):
把indirect branch最有可能执⾏的逻辑体紧跟在indirect branch后⾯。如果indirect branch经常执⾏并且不能被预测硬件预测,那就在indirect branch后跟⼀个UD2指令,阻⽌处理器来做投机执⾏。
indirect branch会使执⾏流跳转到任意位置。如果⼤部分时间都是到同⼀个位置,那么BTB会⼯作的很好。因为只有⼀个跳转地址会存在BTB中,太过随机的跳转会降低预测成功率。
indirect branch(⽐如switch语句)可以⽤多个条件分⽀来等价替换,这会增加BTB中的预测条⽬。添加条件分⽀来替代indirect branch的部分或全部跳转⽬标需要满⾜如下条件才会有更⼤收益:
条件分⽀必须与分⽀历史关联。之后的例⼦可以看到解释。
The source/target pair is common enough to warrant using the extra branch prediction capacity. This may increa the number of overall branch mispredictions, while improving the misprediction of indirect branches. The profitability is lower if the number of mispredicting branches is very large.
Ur/Source Coding Rule 1. (M impact, L generality) :
如果⼀个indirect branch(⽐如switch语句)有2个或多个常⽤的跳转⽬标,⾄少有⼀个与分⽀历史相关联,那么可以把这个跳转⽬标⽤条件分⽀替代。
burton
Loop Unrolling
Loop Unrolling:循环展开,是⼀种牺牲程序的尺⼨来加快程序的执⾏速度的优化⽅法。可以由程序员完成,也可由编译器⾃动优化完成。循环展开最常⽤来降低循环开销,为具有多个功能单元的处理器提供指令级并⾏。也有利于指令流⽔线的调度。
induction variable:循环⾥那个递增递减变量。
common subexpression elimination:⼀种编译优化技术,它会搜索有没有等价表达式,是否值得⽤保存了计算结果的变量来替换它。 使⽤unrolling的好处:
消除了每次循环的分⽀语句和操作induction variable。
更加容易流⽔线处理来隐藏延时。
把代码暴露给了其它优化器,例如对冗余load的移除,common subexpression elimination等。
使⽤unrolling的潜在坏处:
unrolling⼤的循环体,会导致代码⼤⼩增加。如果unrolling后的循环代码过⼤⽽不能保存在trace cache (TC)中,那将是有害的。
如果循环体内有分⽀,unrolling后会增加对BTB的容量需求。
Asmbly/Compiler Coding Rule 15. (H impact, M generality):
unroll⼩的循环,直到分⽀和induction variable开销⼩于执⾏开销的10%。
Asmbly/Compiler Coding Rule 16. (H impact, M generality) :
避免unroll过多循环结构,这个可能会撑爆trace cache 或者 指令cache。

本文发布于:2023-07-02 02:08:36,感谢您对本站的认可!

本文链接:https://www.wtabcd.cn/fanwen/fan/78/1073270.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

标签:指令   预测   代码   跳转   优化   函数   地址   性能
相关文章
留言与评论(共有 0 条评论)
   
验证码:
推荐文章
排行榜
Copyright ©2019-2022 Comsenz Inc.Powered by © 专利检索| 网站地图