Answers:
如今,这个问题的复杂性已经超出了人类的理解范围。(自最近5年以来一直是这种方式。)将其与短向量并行性(SIMD)结合使用,您会感到绝望的是,手动优化代码在经济上不再可行-并非不可能,但是这样做不再具有成本效益。
当前的方法是依靠教计算机如何进行优化-通过使代码变体来计算具有不同结构(循环,数据结构,算法)的相同答案并自动评估性能。使用非常严格的数学模型指定了代码转换的规则,因此计算机科学家可以理解并且计算机可以执行。
以下是Larry OBrien在其答案之一中发布的链接。
http://onward-conference.org/2011/images/Pueschel_2011_AutomaticPerformanceProgramming_Onward11.pdf
完全有可能了解和优化缓存。首先要了解硬件,然后继续控制系统。您对系统的控制越少,成功的可能性就越小。Linux或Windows运行一堆没有闲置的应用程序/线程。
大多数缓存的属性有些相似,它们使用地址字段的某些部分来查找匹配项,并具有深度(方向)和宽度(缓存线)。一些具有写缓冲区,一些可以配置为在写时通过或绕过高速缓存,等等。
您需要敏锐地意识到所有正在访问该高速缓存的内存事务(某些系统具有独立的指令和数据高速缓存,使任务更加容易)。
如果不仔细管理内存,很容易使缓存变得无用。例如,如果您要处理多个数据块,希望将它们保留在高速缓存中,但它们在内存中的地址是相对于高速缓存命中/未命中检查的偶数倍,例如0x10000 0x20000 0x30000,并且您拥有更多这些比缓存中的方式要快得多,您可能很快就会使某些东西在打开缓存时运行得非常慢,比关闭缓存时运行得慢。但是将其更改为0x10000、0x21000、0x32000,可能足以充分利用缓存,从而减少逐出。
最重要的是,优化缓存的关键(嗯,除了非常了解系统之外)是将您需要性能的所有内容同时保留在缓存中,对数据进行整理,以便有可能拥有一次全部放入缓存中。并防止代码执行,中断和其他常规或随机事件之类的东西驱逐出您正在使用的数据的重要部分。
代码也一样。但是,这有点困难,因为您需要控制代码所在的位置,以避免与要保留在缓存中的其他代码发生冲突。在测试/分析通过缓存的任何代码时,会在此四处添加一行代码,甚至添加一个nop,而将同一代码的代码所在地址从一个编译到另一个的更改或更改,都会在以下位置更改或更改:缓存行位于该代码之内,并更改了收回的内容和关键部分没有的内容。
另外,请首先信任编译器在这些问题上的优化。
如果使用最新的GCC编译器,则可以使用(带有简约性)其__builtin_prefetch
功能。请参阅关于stackoverflow的答案。