星期一, 四月 18, 2011

What every programmer should know about memory 阅读笔记(6.2.2)

http://lwn.net/Articles/255364/
6.2.2 Optimizing Level 1 Instruction Cache Access

尽量减小代码大小,要注意loop unrolling和inlining对代码规模的影响,保持平衡。
比如如果一个函数只调用一次,将其inline就没问题。

代码尽量是线性的,减少代码空洞(不需要经常执行的代码块)的存在。
比如一个条件执行代码 条件执行的并不会经常执行 这就会形成空洞。Linux
Kernel中使用了宏likely和unlikely,当使用这2个宏的时候,如果gcc编译选项 -freorder-blocks
(默认包含在-O2中 不包含在-Os中)打开,gcc就会将标记好的代码块移动到函数尾部,从而不产生代码空洞。
还有另一选项 -freorder-blocks-and-partition 但是有使用限制,其不能和exception handling 一起使用。

Intel Core 2有一种针对小循环的功能 Loop Stream Detector (LSD)。
如果一个循环has no more than 18 instructions (none of which is a call to a
subroutine), requires only up to 4 decoder fetches of 16 bytes, has at
most 4 branch instructions, and is executed more than 64
times。这个循环就会被锁进指令队列中,下次再执行这个循环速度就会更快。
一个大循环中的小循环,即使没有这个功能,执行速度也会快一些。

代码尽量对齐。对各种对齐问题,汇编器提供了.align伪指令来处理这种问题。
函数头的对齐。gcc 编译选项-falign-functions=N,函数都将以N对齐。如果一个小函数碰到一个很大的N,这就会造成浪费,对一个很少执行的函数,这也是浪费。后一种情况经常发生在库中,一个库会包行常用的函数和不常用的函数。一个正确的N的选择可以提高程序的效率。-fno-align-functions可以关闭这个选项。
基本块的对齐。gcc编译选项-falign-jumps=N,和上面的参数有同样的问题。
循环的对齐。gcc编译选项-falign-loops=N,和上面的参数有同样的问题。
最后还有一个参数-falign-labels,会影响程序速度,作者建议不要使用。

0 Comments:

发表评论

<< Home