为什么可以添加填充使您的循环更快
Why can adding padding make your loop faster?
人们告诉我,添加填充可以帮助获得更好的性能,因为它以更好的方式使用了缓存。
我不明白,通过使数据更大,您可以获得更好的性能。
有人可以理解为什么吗?
数组填充
阵列填充技术包括增加数组尺寸的大小,以减少访问缓存内存时的冲突错过。当访问的元素映射到同一集的数量大于缓存的关联性程度时,可能会发生这种错过。填充更改数据布局,可以在变量(间变量填充)之间应用(1)或(2)之间的变量( Intra-intra-Variable Padding ):
1。可变填充
float x[LEN], padding[P], y[LEN];
float redsum() {
float s = 0;
for (int i = 0; i < LEN; i++)
s = s + x[i] + y[i];
return s;
}
如果我们有一个直接映射的缓存,并且元素x[i]
和y[i]
被映射到同一组中,则访问x
将从y
驱逐一个块,反之亦然,导致高率和低性能。
2。可变内填充
float x[LEN][LEN+PAD], y[LEN][LEN];
void symmetrize() {
for (int i = 0; i < LEN; i++) {
for (int j = 0; j < LEN; j++)
y[i][j] = 0.5 *(x[i][j] + x[j][i]);
}
}
在这种情况下,如果将列的元素映射到少数集合中,则它们的访问顺序可能导致冲突错过,因此不会利用空间位置。
例如,假设在外循环的第一次迭代中,驱逐包含x[0][0] x[0][1] ... x[0][15]
的块以存储包含元素x[k][0]
的块。然后,在第二次迭代开始时,对x[0][1]
的引用将导致缓存失误。
此技术文档分析了快速傅立叶变换(FFT)的性能,这是计算中使用的矩阵大小的函数:
https://www.intel.com/content/www/us/en/developer/articles/technical/technical/fft-length-length-harm-layout-advisor.html
参考
加布里埃尔·里维拉(Gabriel Rivera)和蔡(Chau-wen Tseng)。消除冲突错过的数据转换。PLDI1998。doi:https://doi.org/10.1145/277650.277661
Changwan Hong等人。有效的多维阵列填充,以避免缓存冲突错过。pldi 2016. doi:https://doi.org/10.1145/2908080.2908123
我认为这在一个简单的循环中并不重要。看看这个答案:在C 11中的性能真的很重要?
从该答案中对您来说最有趣的位可能是您可以安排您的课程,以便将成员一起使用在一个缓存线中,而不同线程使用的成员则不是。
- 如何在C++中从两个单独的for循环中添加两个数组
- 如何通过替换顺序代码的while循环来添加OpenMP for循环
- C++ 在循环中添加计数器变量并再次初始化其值
- 如何添加循环期间分配的变量?
- 是否可以在 for 循环中添加两个浮点数?
- 需要循环帮助以迭代方式添加到程序集中的总和变量
- 添加#pragma循环后出现Segfault
- 在 C++ 中向 rand() 添加模数会影响 for 循环之外的执行,为什么以及如何补救?
- C++ 循环逐行写入文件还是添加到数组并在循环后写入文件?
- 如何从 while 循环中添加数字
- 循环以使用设置模板类将所有 26 个字母添加到 s 中
- C++在 while 循环后添加一行代码会导致错误
- 为什么if语句和变量声明要比循环中的添加更快
- C++:如何在"for"循环中动态地向文本行添加后缀以创建先前声明的变量
- 计算平均值,而不向退出循环添加负等级
- C 如何结束一个段循环,该循环添加数字而不使用数字作为触发器来结束循环
- 我们如何在 C++ 中使用 while 循环添加前 10 个整数
- Qt从其他线程向事件循环添加函数调用
- 如何在C++中阻止循环添加额外的字符迭代
- for循环添加整数