C++:分配对齐的矩阵

C++: allocate aligned matrices

本文关键字:对齐 分配 C++      更新时间:2023-10-16

我正在阅读C++中的一些代码,我阅读了以下内容:

CACHELINE = 64;
...
/* allocate the three matrices and align to cache lines */
a = (double *)malloc(nmax*nmax*sizeof(double)+CACHELINE);
b = (double *)malloc(nmax*nmax*sizeof(double)+CACHELINE);
c = (double *)malloc(nmax*nmax*sizeof(double)+CACHELINE);
a = (double *)(((unsigned long)a+CACHELINE)&~(CACHELINE-1));
b = (double *)(((unsigned long)b+CACHELINE)&~(CACHELINE-1));
c = (double *)(((unsigned long)c+CACHELINE)&~(CACHELINE-1));

为什么此代码创建与缓存行对齐的矩阵?我特别不明白这个指令的作用:

a = (double *)(((unsigned long)a+CACHELINE)&~(CACHELINE-1));

谢谢!

这很简单。malloc不保证返回的地址将与缓存行大小对齐。因此,您可以分配一些额外的内存(+CACHELINE),并从正确对齐的第一个字节开始使用它。第一个字节在较低的分配中计算。

但是,这是一段可怕的代码。例如,它会丢失有关最初分配的地址的信息,因此您无法free它。或者,它会将指针投射到unsigned long,这是不安全的(有uintptr_t)。

还有其他方法可以分配对齐的存储,例如posix_memalign


示例:假设您要分配 100 字节的内存,但您却分配了 100+64=164。malloc返回地址 16,因此您可以使用地址 16 到 179 之间的字节。

现在,您需要计算此范围内第一个字节的地址,该字节与64对齐,其本身为64。计算公式为 (16+64)&~(64-1)=80&~63=64。最后,您将使用地址 64 到 163 之间的字节,该字节在分配的 16 到 179 范围内。