设计 C++ 程序时如何减少可能的缓存未命中次数?
内联函数每次都有帮助吗?还是只有在程序受 CPU 限制时才好(即程序是面向计算而不是面向 I/O)?
以下是我在处理此类代码时喜欢考虑的一些事情。
对于数据绑定操作
在列表、地图和集合上使用数组和向量
按行处理列
允许 CPU 有效地预取数据。例如,您可以减少按行而不是按列处理多维数组的缓存未命中数、展开循环等。
这种优化取决于硬件架构,因此您最好使用某种特定于平台的分析器(例如 Intel VTune)来检测缓存可能存在的问题。
内联函数运行可能会损害指令缓存。如果内存不受 fetch 限制,那么它不太可能产生太大(如果有的话)差异。
与往常一样,任何优化都应该通过分析而不是预感来通知。更不用说您需要了解分析器告诉您的内容,这意味着您熟悉汇编语言以及您正在优化的平台的特定特征。
现在有点老了,但 Mike Abrash 的“Graphic's Programming Black Book”仍然有很多很好的一般性建议。
此外,如果您使用 C++ 和多线程,则需要考虑错误共享、局部性和每个处理器缓存上数据的热度。这可以产生很大的不同。尤其是在多线程中,以 LIFO 方式计算事物比以 FIFO 方式计算更有效,但它在单处理器架构中也有效。
避免在不需要时使用动态内存。使用 new、delete、smart pointers 等等,往往会将您的程序数据分散到内存中。这不好。如果您可以将大部分数据保存在一起(例如,通过在堆栈上声明对象),那么您的缓存肯定会工作得更好。