#内层对齐补齐与分支目标缓冲器
出自《C++反汇编技术分析与揭秘》
此书我并没有读完,收获是对于底层更加了解,有2个点更加清楚了
内存对齐与补齐,为什么是4字节
CPU运算的第二梯队是cache(高速缓冲区),它的访问速度仅次于寄存器
cache中有虚拟地址映射,当运算时会从中拿到地址进行寻址操作
同时32位机的寄存器位数为32位,我们常用的数据整形int和指针的大小也为4字节
思考2个问题:
一般常用的数据类型基本是4字节以上(除单个的char和short)
cache的内存十分宝贵,里面保存的地址是否有必要精确到1位
对于cache进行了优化,其中保存的内存地址会丢弃后两位,丢弃之后,寻址操作只能基于4字节的倍数
所以对齐补齐是以4字节为基础的
对于循环的优化
先考虑流水线优化,其原理很简单:
A B C D四个工人,当一个任务来的时候,顺序是A->B->C->D
当A做完了,继续来了第2个任务,在此时,B在做第一个任务的第二步,参考如图:A B C D
A B C D
A B C D
……
其核心是,如果只有一个任务,那么就需要花费一整段工作时间
而如果是多个任务,例如2个任务,那么就是5/4的时间,以此类推
分支目标缓冲器,考虑下面的循环:
/** *@brief 外层循环做10次 */ for (int i = 0; i < 10; ++i) { /** *@brief 内层做1000次循环,第一次不预测,预测成功999次,第1001次预测失败 */ for (int j = 0; j < 1000; ++j) { //... } }
分支目标缓冲器要结合流水线优化来理解
当第一个分支启动时,分支目标缓冲器不进行预测,当第二次循环进行时,进行预测,预测成功,直到失败
分支目标缓冲器是经验主义,预测越多,优化更好,如果多次失败,则会刷新
(intel的CPU是这样的,当进行一个分支时,下一个分支已经在进行预测了,它对true/false的情况进行预测
,也就是在这次分支执行时,下一次分支已经准备好了(其中的同步这些则是更底层的知识了)如果预测失败则会回流,
如果预测成功,将会节省时间以达到提升性能的目的)如果外层分支进行10次,内层分支进行1000次,那么1次不预测,999次成功,最后一次失败,这样的操作重复10次
则 10 x 999 = 9990 次
如果外层分支进行1000次,内层分支进行10次,那么1次不预测,9次成功,最后一次失败,这样的操作重复1000次
则 9 x 1000 = 9000 次
分支预测是经验主义,预测越多,优化也就更好,所以:
多重循环,内层循环次数应大于外层循环次数
PS:这需要结合CPU来考虑,intel的CPU是这样的,AMD就不知道了
至于switch,if,等等,都有优化,具体以后再补,分支的结构类似于函数调用,都会发生跳转(inline例外)
PS:强推程序应当了解底层知识,编译器优化和汇编,如果了解了底层,很多知识点都能迎刃而解
当然,前提是有那耐心,一个简单的除法编译器都可能会优化成一堆计算机处理比较简单,而人理解起来就很头疼的代码
那涉及到数学方面的知识,并且不简单…