我试图从这本书中理解9点模板的算法,逻辑是清楚的,但是WIDTHP宏的计算是我无法理解的,这里是缩略图代码(原始代码超过300行长!):
#define PAD64 0
#define WIDTH 5900
#if PAD64
#define WIDTHP ((((WIDTH*sizeof(REAL))+63)/64)*(64/sizeof(REAL)))
#else
#define WIDTHP WIDTH
#endif
#define HEIGHT 10000
REAL *fa = (REAL *)malloc(sizeof(REAL)*WIDTHP*HEIGHT);
REAL *fb = (REAL *)malloc(sizeof(REAL)*WIDTHP*HEIGHT);原始数组为5900 x 10000,但如果定义PAD64,则数组为5915.75 x 10000。
尽管到目前为止,我可以猜到作者正在尝试将& pad数组对齐到64字节边界。但是malloc返回的数组通常是对齐的(& padded),而且,memalign为您提供了保证具有所请求的对齐方式的内存块。,我们也可以使用
__attribute__((align(64)))这个WIDTHP会对我的代码的性能产生什么影响?
发布于 2015-05-01 02:36:25
我打算把这个作为一个评论来解压他的答案,因为他是对的。但也许我可以解释得更清楚,尽管用的字符比评论中的要多。
当我计算时,我得到了5904 reals,它是23616字节,这是64个字节缓存行的396条缓存线。它是字节,而不是元素的数量,必须是64的倍数。
至于为什么要填充宽度的值,让我们看一个较小的例子。让我们假设我们有一个包含10个字母的“缓存行”,并且我们有一个宽度为8个字母、高度为4的“数组”。
但是,当它被排列成高速缓存行时,它是什么样子的,因为它们有10个字母长:AAAAAAAABB BBBBBBCCCC CCCCDDDDDD DD
不太好。只有数组的第一行对齐。但是如果我们用两个空格来填充宽度,我们就可以在缓存中得到:AAAAAAAA__ BBBBBBBB__ CCCCCCCC__ DDDDDDDD__
这就是我们想要的。现在我们可以有一个嵌套循环,如
for i = 1 to height
for j = 1 to width并且要知道,每当我们开始在j循环上工作时,我们所需要的数据就会对齐。
是的,他们真的应该做些什么来确保数组的第一个元素是对齐的。'attribute((align(64)))‘不能工作,因为数组是动态分配的,但是它们可以使用posix_memalign而不是malloc。
发布于 2015-04-30 08:43:29
其思想是,矩阵的每一行(或列,如果它被视为列主矩阵)可以通过在行的末尾添加填充来对齐到新缓存行的开始。当然,具体的影响在很大程度上取决于访问模式,但是一般来说,对于密集的数字处理代码来说,对缓存友好是非常重要的。
而且,计算是整数,所以结果肯定不是5915.75,这是没有意义的。
发布于 2015-04-30 08:45:35
宽度p的计算是这样的。
( Width/64) +1很好的整数精度数学。我会给你一个更好的答案,除非在SE移动应用程序中,在这个和清单之间切换是不可行的
https://stackoverflow.com/questions/29962854
复制相似问题