6

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

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

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

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

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

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

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

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

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

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

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

4

1 回答 1

14

这里有很多问题,所以我会保持简短的答案。

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

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

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

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

通过查阅用户手册。一些操作系统提供查询工具,例如sysctl.

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

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

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

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

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

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

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

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

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

于 2013-09-02T09:12:53.733 回答