这听起来像是一个主观问题,但我正在寻找的是特定的实例,您可能遇到过与此相关的实例。
如何使代码、缓存有效/缓存友好(更多的缓存命中,尽可能少的缓存未命中)?从两个角度来看,数据缓存&程序缓存(指令缓存),
即代码中与数据结构和代码构造相关的哪些内容应该注意以使其缓存有效。
是否存在必须使用/避免的任何特定数据结构,或者是否存在访问该结构的成员等的特定方法......以使代码缓存有效。
在这件事上是否有任何程序结构(if、for、switch、break、goto...)、代码流(for 内部 if、if 内部 for 等...)应该遵循/避免?
我期待听到与制作缓存高效代码相关的个人经验。它可以是任何编程语言(C、C++、汇编……)、任何硬件目标(ARM、Intel、PowerPC……)、任何操作系统(Windows、Linux、Symbian……)等。 。
多样性将有助于更好地深入理解它。
缓存的作用是减少 CPU 因等待内存请求而停止的次数(避免内存占用)latency),作为第二个效果,可能会减少需要传输的数据总量(保留内存带宽).
避免内存获取延迟的技术通常是首先要考虑的事情,有时会有很大帮助。有限的内存带宽也是一个限制因素,特别是对于许多线程想要使用内存总线的多核和多线程应用程序。一组不同的技术有助于解决后一个问题。
改善空间局部性意味着您确保每个缓存行在映射到缓存后都得到充分使用。当我们查看各种标准基准测试时,我们发现其中很大一部分在缓存行被逐出之前未能使用 100% 所获取的缓存行。
提高缓存线利用率有以下三个方面的帮助:
- 它倾向于在缓存中容纳更多有用的数据,从本质上增加有效缓存大小。
- 它倾向于在同一缓存行中容纳更多有用的数据,从而增加了在缓存中找到所请求数据的可能性。
- 它降低了内存带宽要求,因为读取次数会减少。
常见的技术有:
- 使用较小的数据类型
- 组织数据以避免对齐漏洞(通过减小大小对结构成员进行排序是一种方法)
- 请注意标准动态内存分配器,它可能会引入漏洞,并在内存预热时将数据分散在内存中。
- 确保所有相邻数据实际上都在热循环中使用。否则,请考虑将数据结构分解为热组件和冷组件,以便热循环使用热数据。
- 避免表现出不规则访问模式的算法和数据结构,并支持线性数据结构。
我们还应该注意到,除了使用缓存之外,还有其他方法可以隐藏内存延迟。
现代CPU:通常有一个或多个硬件预取器。他们对缓存中的未命中情况进行训练,并尝试发现规律。例如,在后续缓存行发生几次缺失后,硬件预取器将开始将缓存行提取到缓存中,以预测应用程序的需求。如果您有常规的访问模式,那么硬件预取器通常会做得很好。如果您的程序不显示常规访问模式,您可以通过添加来改进预取指令你自己。
以这样一种方式重新组合指令,使缓存中总是丢失的指令彼此靠近,CPU 有时可以重叠这些提取,以便应用程序仅承受一次延迟命中(内存级并行性).
为了减少整体内存总线压力,您必须开始解决所谓的问题时间局部性。这意味着您必须在数据尚未从缓存中清除时重用数据。
合并接触相同数据的循环(循环融合),并采用称为tiling or blocking所有人都努力避免那些额外的内存获取。
虽然此重写练习有一些经验规则,但您通常必须仔细考虑循环携带的数据依赖性,以确保不会影响程序的语义。
这些都是在多核世界中真正得到回报的东西,在添加第二个线程后,您通常不会看到太多吞吐量的改进。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)