如何想出一个高缓存未命中率的例子
How to come up with a high cache miss rate example?
我正在尝试提出一个具有高缓存未命中率的示例程序。我想我可以尝试逐列访问矩阵,如下所示:
#include <stdlib.h>
int main(void)
{
int i, j, k;
int w = 1000;
int h = 1000;
int **block = malloc(w * sizeof(int*));
for (i = 0; i < w; i++) {
block[i] = malloc(h * sizeof(int));
}
for (k = 0; k < 10; k++) {
for (i = 0; i < w; i++) {
for (j = 0; j < h; j++) {
block[j][i] = 0;
}
}
}
return 0;
}
当我使用-O0
标志编译它并使用perf stat -r 5 -B -e cache-references,cache-misses ./a.out
运行时,它给了我:
Performance counter stats for './a.out' (5 runs):
715,463 cache-references ( +- 0.42% )
527,634 cache-misses # 73.747 % of all cache refs ( +- 2.53% )
0.112001160 seconds time elapsed ( +- 1.58% )
这对我的目的来说已经足够了。但是,如果我继续将矩阵大小更改为2000x2000
它会得到:
Performance counter stats for './a.out' (5 runs):
6,364,995 cache-references ( +- 2.32% )
2,534,989 cache-misses # 39.827 % of all cache refs ( +- 0.02% )
0.461104903 seconds time elapsed ( +- 0.92% )
如果我进一步将其增加到3000x3000
,我会得到:
Performance counter stats for './a.out' (5 runs):
59,204,028 cache-references ( +- 1.36% )
5,662,629 cache-misses # 9.565 % of all cache refs ( +- 0.11% )
1.116573625 seconds time elapsed ( +- 0.32% )
这很奇怪,因为随着大小的增加,我希望获得更多的缓存未命中率。我需要尽可能独立于平台的东西。计算机体系结构课很久以前,所以任何见解都会受到欢迎。
笔记
我说我需要一些相对独立于平台的东西,但这些仍然是我的规格:
- 英特尔®酷睿™ i5-2467M
- 4 GiB 内存
- 64 位 Ubuntu 12.04
当心现代 CPU 中的自动预取 - 它通常可以检测到跨步访问。也许可以尝试随机访问模式,例如:
int main(void)
{
int i;
int n = 1000 * 1000;
int *block = malloc(n * sizeof(int));
for (i = 0; i < n / 10; i++) {
int ri = rand() % n;
block[ri] = 0;
}
return 0;
}
我不完全确定您可以比较这些程序或真正保证任何事情,因为这取决于操作系统如何分配单个内存块。
您至少应该将所有内存分配为单个块,然后索引到该块中以获取所有数组(int*
和int
)。 这样你就有一个一致的起点。 您可能希望将数组大小作为参数传递,而不是每次都重新编译。
您还可以对其进行调整,以便分配比所需更多的内存,并放置每一行(或列,您编写它的方式),以保证在任何时候只有矩阵的一行(列)加载到缓存中。 即找出缓存的大小,并将每个块至少间隔那么多字节。
请注意,在退出之前,您应该真正free
内存。
正如其他人已经指出的那样,随机化您的访问模式是一个好主意。
相关文章:
- cmake更新缓存的变量
- 试图对缓存进行跨步测试,但程序并没有结束
- 缓存std::数组的选定元素,并在c++中自动保持其一致性
- 通过ccmake在cmake中缓存依赖选项
- 使用宏扩展的泛型:为什么指令缓存使用不当?
- 如何使缓存线程安全
- 存储指令是否会阻止缓存未命中的后续指令?
- 缓存局部性与函数调用
- Qt 网页程序集缓存
- 多线程减慢程序速度:无错误共享,无互斥锁,无缓存未命中,无小工作量
- std::shared_ptr vs std::make_shared:意外的缓存未命中和分支预测
- 多个 rocksdb 实例:使用单个共享缓存还是多个独立缓存?
- 无法链接 LRU 缓存C++
- 空函数的参数是否加载到缓存中?
- 是否可以检查变量是否位于 L1/L2/L3 缓存中
- dynamic_cast每次调用是否比具有空检查的缓存变量更昂贵?
- C++:如何在从给定缓存中排除数字的同时生成随机数
- 堆分配如何损害硬件缓存命中率
- 关联集缓存低估命中率
- 如何想出一个高缓存未命中率的例子