gpt4 book ai didi

Cachegrind输出解释

转载 作者:行者123 更新时间:2023-12-03 16:53:54 25 4
gpt4 key购买 nike

这是 cachegrind 输出的一部分。这部分代码已经执行了1224次。 elmg1 是一个大小为 16 x 20 的 unsigned long 数组。我的机器 L1 缓存大小为 32KB,64B 缓存行大小和 8 路组关联。

  1. for (i = 0; i < 20; i++) 78,336 2,448 2 50,184 0 0 1,224 0 0
  2. {
  3. telm01 = elmg1[i]; 146,880 0 0 73,440 0 0 24,480 0 0
  4. telm31 = (telm01 << 3) ^ val1; 97,920 0 0 48,960 0 0 24,480 0 0
  5. telm21 = (telm01 << 2) ^ (val1 >> 1); 146,880 1,224 1 48,960 0 0 24,480 0 0
  6. telm11 = (telm01 << 1) ^ (val1 >> 2); 146,880 0 0 48,960 0 0 24,480 0 0
  7. }

一个。我把它放在这里的原因是,在 for 循环内的第 3 行,我看到了一些 I1 未命中(还有一个 L2 未命中)。这有点令人困惑,我猜不出原因是什么?

B.我正在尝试优化(时间)一部分代码。以上只是一个小片段。我认为在我的程序内存访问中花费了我很多。与上面的示例一样,elmg1 是一个 16 x 20 大小的无符号长数组。当我尝试在代码中使用它时,总会有一些遗漏,而在我的程序中这些变量经常出现。有什么建议吗?

C.我需要分配和(有时初始化)这些无符号长整型。你能建议我更喜欢哪一个,calloc 或数组声明,然后显式初始化。顺便问一下,缓存处理它们的方式会有什么不同吗?

谢谢。

最佳答案

你试过展开循环吗?

  1. 我现在不担心 L1 未命中。 1224 次中有一次 L2 未命中也是可以的,CPU 必须在某个时候将值加载到缓存中。
  2. 与程序的其余部分相比,此代码的 L2 未命中百分比是多少?
  3. 使用 calloc(),如果数组大小始终相同并且您使用常量作为大小,则编译器可以优化数组的归零。此外,唯一会影响缓存行使用的是对齐,而不是它是如何启动的。

edit: 数字很难以这种方式阅读并且第一次读错了。

确保我读的是第 5 行的数字:

Ir    146,880
I1mr 1,224
ILmr 1
Dr 48,960
D1mr 0
DLmr 0
Dw 24,480
D1mw 0
DLmw 0

L1 缓存分为两个 32KByte 缓存,一个用于代码 I1,一个用于数据 D1。 IL & DL是数据和指令共享的L2或L3缓存。

大量的 I1mr 是指令未命中而不是数据未命中,这意味着循环代码正在从 I1 指令缓存中弹出。

第 1 行和第 5 行的 I1 未命中总数为 3672,是 1224 的 3 倍,因此每次循环运行时,您都会得到 3 次 I1 缓存未命中和 64 字节缓存行,这意味着您的循环代码大小在 128-192 字节之间以覆盖 3缓存行。所以第 5 行的那些 I1 未命中是因为这是循环代码穿过最后一个缓存行的地方。

I would recommend using KCachegrind for viewing the results from cachegrind

编辑:关于缓存行的更多信息。

那个循环代码看起来不像它自己被调用了 1224 次,所以这意味着有更多的代码将这个代码推出 I1 缓存。

你的 32Kbyte I1 缓存被分成 512 个缓存行(每行 64 字节)。 “8-way set associative”部分意味着每个内存地址仅映射到这 512 个缓存行中的 8 个。如果您要分析的整个程序是一个连续的 32 KB 内存块,那么它会全部放入 I1 高速缓存,并且不会被弹出。这很可能不是这种情况,将有超过 8 个 64 字节的代码块满足相同的 8 个缓存行。假设您的整个程序有 1MB 的代码(包括库),那么每组 8 个缓存行将有大约 32(1Mbyte/32Kbyte)段代码满足这 8 个缓存行。

Read this lwn.net article for all the gory details about CPU caches

编译器无法始终检测程序的哪些函数将成为热点(多次调用),哪些将成为代码点(即错误处理程序代码,几乎从不运行)。 GCC 具有函数属性 hot/cold这将允许您将函数标记为热/冷,这将允许编译器将热函数组合在一个内存块中以获得更好的缓存使用(即冷代码不会将热代码推出缓存)。

无论如何,那些 I1 失误真的不值得花时间去担心。

关于Cachegrind输出解释,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4066937/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com