【问题标题】:Understanding how the CPU decides what gets loaded into cache memory了解 CPU 如何决定将哪些内容加载到高速缓存中
【发布时间】:2013-09-02 08:32:22
【问题描述】:

假设一台计算机有 64k 的 L1 缓存和 512k 的 L2 缓存。

程序员在主内存中创建/填充了一个 10mb 的数据数组(例如 3d 模型的顶点/索引数据)。

数组可能包含一系列结构,例如:

struct x
{
  vec3 pos;
  vec3 normal;
  vec2 texcoord;
};

接下来,程序员必须对所有这些数据执行一些操作,例如在将数据传递给 GPU 之前进行一次正常计算。

CPU 如何决定数据如何加载到 L2 缓存中?

程序员如何检查任何给定架构的缓存线大小?

程序员如何确保组织数据以使其适合高速缓存行?

数据对齐到字节边界是唯一可以帮助这个过程的事情吗?

程序员可以做些什么来最大程度地减少缓存未命中?

有哪些分析工具可以帮助可视化 Windows 和 linux 平台的优化过程?

【问题讨论】:

  • 这是一个相当大的问题,所以我希望它会被“搁置”。无论如何,为了确保良好的缓存使用率,请考虑切换到 Struct of Arrays 布局。这将确保您几乎不会将缓存空间浪费在您没有立即使用的数据上。拆分 vecx 可能也是一个好主意,但原因不同:矢量化。
  • 为了尽量减少缓存未命中,请查看stackoverflow.com/questions/460666/…
  • 我主要反对关闭问题(暂停,哈哈!按钮仍然显示“关闭”),但这里有太多问题,有点令人讨厌。这将是大学课程中大型课程单元的材料。如果您至少知道其中一些问题的答案,请在问题中提供。您知道什么是缓存行这一事实表明您也知道 CPU 如何决定如何将数据加载到 L2 中。

标签: c++ caching optimization


【解决方案1】:

这里有很多问题,所以我会尽量简短地回答。

CPU 如何决定数据如何加载到 L2 缓存中?

无论你使用什么,都会被加载。 L2 的行为与 L1 相同,只是它的数量更多,并且由于行更大且集合关联性更少,混叠(可能导致过早驱逐)更常见。一些 CPU 只加载 L2 的数据,这些数据是从 L1 推出的,但这对程序员来说并没有太大的区别。

大多数 MMU 都有用于未缓存内存的功能,但这是针对设备驱动程序的。我不记得曾经看到过在不禁用 L1 的情况下禁用 L2 的选项。没有缓存,就没有性能。

程序员如何检查任何给定架构的缓存线大小?

通过查阅用户手册。一些操作系统提供像sysctl 这样的查询工具。

程序员如何确保数据被组织成适合缓存行?

关键思想是空间局部性。同一个内循环同时访问的数据应该进入同一个数据结构。最佳组织是将该结构适合缓存行并将其与缓存行大小对齐。

除非您小心地将分析器用作指南,否则不要自找麻烦。

数据对齐到字节边界是唯一可以帮助这个过程的事情吗?

不,另一部分是避免用无关数据填充缓存。如果某些字段只被其他算法使用,那么它们在当前算法运行时正在浪费缓存空间。但是你不能一直优化所有东西,重新组织数据结构需要编程工作。

程序员可以做些什么来最大程度地减少缓存未命中?

使用真实数据进行分析,并将过多的未命中视为错误。

有哪些分析工具可以帮助可视化 Windows 和 linux 平台的优化过程?

Cachegrind 非常好,但使用的是虚拟机。英特尔 V-Tune 使用您的实际硬件,无论好坏。后者我没用过。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-05-01
    • 1970-01-01
    • 1970-01-01
    • 2023-04-05
    • 2014-05-19
    • 2013-12-13
    相关资源
    最近更新 更多