如何使用(读写)CPU缓存L1,L2,L3

4
我有一个需要超高性能的任务。
当然,我可以优化算法,但我还想在硬件级别上进行优化。
我可以使用CPU亲和力来将整个核心分配给处理我的任务的线程。
另一种优化方式是将我任务所需的数据放入CPU缓存(L1、L2、L3),以尽可能避免"RAM访问"延迟。
什么API可以用于这样的开发?
换句话说,我的问题可能是:"如何强制CPU将给定的数据结构放置在缓存中?"
谢谢您的帮助。
3个回答

4

Peter C提到预取的评论非常好。作为一名前优化师,我们改进代码的第一件事就是删除所有的软件预取。此外,不要尝试操作电源状态等内容。现在它们已经非常好了,投入与性能收益不成正比。唯一需要注意的可能是超线程。您需要使用超线程的唯一时机是某些需要保持一致性和性能的基准测试。

查看英特尔优化资源,例如优化指南。同时获取一个好的分析器;Intel的VTune确实是最好的之一。如果需要英特尔的信息,请使用bing(或谷歌)搜索相关内容。英特尔的网站一直都是一个花哨的混乱。VTune有学生和教育者许可证。

以下是我优化应用程序性能所采取的步骤。首先,耗尽高级软件更改。然后进入硬件性能调整。为什么?两个原因:(1)代码更改通常与架构无关,并且在移动到不同的硬件平台和代之后有更好的生存机会。(2)它们要简单得多(虽然可能不太有趣)。
代码更改:
  1. 移除所有SW预取功能。
  2. 将任何轮询替换为定期中断。
  3. 确保任何检查中断都有适当的间隔。
  4. 使用Fortran。真的。Fortran之所以仍然存在是有原因的。看看英特尔Fortran论坛。该论坛都是经典的HPC。而英特尔的Fortran编译器是最好的之一。
  5. 使用优秀的优化编译器,并尝试调整编译器设置和指示/注释(例如#pragma loop count)。再次强调,英特尔的编译器是最好的之一。(我不想这么说,但事实如此。)
  6. 使用优秀的软件分析工具找到优化机会(花费大部分时间的地方)。确保分析工具能够深入源代码中,以识别在不同函数中花费的时间。首先优化这些函数。
  7. 找到线程并行化(多线程)的机会,适当范围限制在核心数量上。
  8. 找到向量化的机会。
  9. 从AoS(结构数组)转换为SoFA。请注意,如果您必须即时进行转换,则可能不值得性能成本。
  10. 重构循环,使其更有利于编译器发现向量化机会。参见任何优化书籍,了解如何实现。

硬件黑客/优化(使用良好的硬件级性能分析器)

  1. 识别缓存和TLB未命中,并重构代码。
  2. 识别分支预测错误并重构代码。
  3. 识别流水线停顿并重构代码。

最后一个建议,尽管我相信你已经知道这一点。记住,要针对热点问题进行优化。小机会耗时且性能改进对整个应用程序的影响不大。

祝你好运。优化可能很有趣且具有回报(如果您稍微有点疯狂)。


2

通常情况下,您无法覆盖 CPU 缓存中的 LRU 替换策略。至少 x86 CPU 不支持任何方式将某些地址范围“锁定”到任何缓存级别。

您可以在使用前进行“预取”。软件预取仅在极少数情况下有帮助。通常情况下,硬件预取会做得很好,只要您的缓存占用足够小,数据就会保留在缓存中。Ulrich Drepper 的 What every programmer should know about memory 涵盖了这一点,并且仍然很重要。但是,它对软件预取(尤其是单独的预取线程)的强调适用于 P4,但对其他 CPU 不是一个好主意。在阅读时请记住这一点。

设计缓存友好的数据结构和访问模式也非常重要。可以尝试搜索“cache aware”算法,或者只需阅读 Ulrich 的论文。或者随着性能计数器的使用进行调整,以查看是否意外地导致了大量的缓存未命中。


如果您正在使用英特尔Haswell Xeon或更新版本(Exxx v3或更高版本),则可以将L3高速缓存分区,以便运行关键线程的核心拥有一部分L3缓存,并且它不会被其他核心驱逐。这称为Cache Allocation Technology (CAT)。请参阅Dan Luu的本文

1

好的,您需要使用低级语言(在这种情况下,C可能是首选)。

然后您需要阅读一些内容:程序员应该了解的有关内存的所有知识。特别注意第6章,其中包含非常有用的编程建议,可以针对特定的使用模式进行优化。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接