了解CPU如何决定加载到缓存中的内容

fis*_*ood 5 c++ optimization caching

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

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

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

struct x
{
  vec3 pos;
  vec3 normal;
  vec2 texcoord;
};
Run Code Online (Sandbox Code Playgroud)

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

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

程序员如何检查任何给定体系结构的缓存行的大小?

程序员如何确保数据的组织以适应缓存行?

数据对齐字节边界是否可以完成以帮助此过程?

程序员可以做些什么来最小化缓存未命中?

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

Pot*_*ter 12

这里有很多问题所以我会简短地回答这些问题.

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

无论你使用什么,都可以加载.L2的行为与L1相同,除了它有更多,并且混叠(可能导致过早驱逐)更常见,因为更大的线条和更少的集合关联性.有些CPU只使用从L1推出的数据加载L2,但它对程序员没有太大影响.

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

程序员如何检查任何给定体系结构的缓存行的大小?

通过查阅用户手册.某些操作系统提供了类似的查询工具sysctl.

程序员如何确保数据的组织以适应缓存行?

关键的想法是空间局部性.通过相同的内部循环同时访问的数据应该进入相同的数据结构.最佳组织是将该结构适配到缓存行并将其与缓存行大小对齐.

除非您仔细使用您的探查器作为指导,否则不要麻烦.

数据对齐字节边界是否可以完成以帮助此过程?

不,另一部分是避免使用无关数据填充缓存.如果某些字段仅被某些其他算法使用,则它们在本算法运行时浪费缓存空间.但是您无法始终优化所有内容,重新组织数据结构需要编程工作.

程序员可以做些什么来最小化缓存未命中?

使用真实数据进行配置,并将过多的未命中视为错误.

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

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