由于C是面向过程的语言,在使用C时,我总是最终得到顺序代码,从上到下作为一个或几个C函数运行。
有时,我编写了1000行的函数。因为我认为函数调用有开销。虽然这不会重复代码,但我可以说我在长函数中复制的代码少于5%。
那么,长函数对处理器缓存的影响是什么?长函数会阻止更好的CPU缓存使用吗? CPU缓存是否像缓存整个C函数一样工作?如果处理器缓存不喜欢长函数,那么函数调用会更有效吗?
答案 0 :(得分:1)
一般来说,可读性应该始终排在第一位,而且您几乎可以将其视为“最后的手段”,这种优化不会为您带来显着的性能提升。
今天的CPU正在缓存指令和数据。通常,您应该优化数据布局和内存访问模式,但是指令的排列方式对于指令缓存的使用也很重要。
调用非内联函数实际上是无条件跳转,就像jmp
指令一样。此跳转使CPU开始从内存中的另一个(可能很远)位置获取指令。如果在指令高速缓存中找不到这个新位置,则CPU将停止,直到相应的存储器被带到那里。理论上,如果代码不包含跳转和分支,CPU可以尽可能积极地预取指令。
另外,你真的不知道“走得太远”。向前或向后跳几千字节可能是缓存命中,因为今天通常的指令缓存大约是32千字节。
这是一个非常棘手的优化,我会建议您先查看数据布局和内存访问模式。
另一个问题是在堆栈或寄存器中传递参数的开销。使用今天的CPU这不是一个问题,因为整个堆栈通常在数据高速缓存中“热”,并且寄存器重命名甚至可以消除寄存器到寄存器移动到无操作。