我试图从this book了解9点模板算法,逻辑对我很清楚,但WIDTHP宏的计算是我无法理解的,这里是breif代码(原始代码长度超过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),posix_memalign gives you a chunk of memory that is guaranteed to have the requested alignment,我们也可以使用
__attribute__((align(64)))
这个WIDTHP对我的代码性能有什么影响?
答案 0 :(得分:2)
这个想法是矩阵(或列,如果它被视为列主矩阵)的每一行都可以通过在行的末尾添加填充来与新缓存行的开头对齐。究竟什么影响当然在很大程度上取决于访问模式,但总的来说,缓存友好性对于强烈的数字运算代码来说非常重要。
此外,计算是整数,因此结果肯定不是5915.75
,这没有意义。
答案 1 :(得分:1)
我打算将其作为一个评论放宽答案,因为他是对的。但也许我可以更清楚地解释一下,尽管其中的字符多于评论中的字符。
当我进行数学运算时,得到5904个实数,即23616个字节,这是64个字节高速缓存行的396个高速缓存行。它是字节,而不是必须是64的倍数的元素数。
至于为什么要填充宽度值,让我们看一个较小的例子。让我们假设我们有一个“缓存行”,其中包含10个字母,并且我们有一个宽度为8个字母且高度为4的“数组”。现在,由于我们的假设数组位于C且C为行主,因此数组将显示这样的事情:
AAAAAAAA
BBBBBBBB
CCCCCCCC
DDDDDDDD
但是当它被安排在缓存行中时它是什么样子,因为它们是10个字母长:
AAAAAAAABB
BBBBBBCCCC
CCCCDDDDDD
DD
不好。只对齐数组的第一行。但是如果我们将宽度填充两个空格,我们在缓存中得到这个:
AAAAAAAA__
BBBBBBBB__
CCCCCCCC__
DDDDDDDD__
这就是我们想要的。现在我们可以有一个像
这样的嵌套循环for i = 1 to height
for j = 1 to width
并且知道每次我们开始处理j循环时,我们需要的数据都会对齐。
哦,是的,他们真的应该做些什么来确保数组的第一个元素是对齐的。 '属性((align(64)))'不起作用,因为数组是动态分配的,但是他们本可以使用posix_memalign而不是malloc。
答案 2 :(得分:-1)
宽度p计算是
( Width/64) +1
精确计算int精度数学。我给你一个更好的答案,除了在SE移动应用程序中,它在这个和列表之间轻弹是不可行的