如何分配16byte内存对齐数据

我试图在一段代码上实现SSE矢量化,我需要将我的1D数组与16字节内存对齐。 但是,我已经尝试了几种方法来分配16byte内存对齐数据,但它最终是4byte内存对齐。

我必须使用Intel icc编译器。 这是我正在测试的示例代码:

#include  #include  void error(char *str) { printf("Error:%s\n",str); exit(-1); } int main() { int i; //float *A=NULL; float *A = (float*) memalign(16,20*sizeof(float)); //align // if (posix_memalign((void **)&A, 16, 20*sizeof(void*)) != 0) // error("Cannot align"); for(i = 0; i < 20; i++) printf("&A[%d] = %p\n",i,&A[i]); free(A); return 0; } 

这是我得到的输出:

  &A[0] = 0x11fe010 &A[1] = 0x11fe014 &A[2] = 0x11fe018 &A[3] = 0x11fe01c &A[4] = 0x11fe020 &A[5] = 0x11fe024 &A[6] = 0x11fe028 &A[7] = 0x11fe02c &A[8] = 0x11fe030 &A[9] = 0x11fe034 &A[10] = 0x11fe038 &A[11] = 0x11fe03c &A[12] = 0x11fe040 &A[13] = 0x11fe044 &A[14] = 0x11fe048 &A[15] = 0x11fe04c &A[16] = 0x11fe050 &A[17] = 0x11fe054 &A[18] = 0x11fe058 &A[19] = 0x11fe05c 

它每次都是4字节对齐,我使用了memalign,posix memalign。 由于我在Linux上工作,我不能使用_mm_malloc也不能使用_aligned_malloc。 当我尝试使用_aligned_attribute(我认为它仅适用于gcc)时,我收到内存损坏错误。

任何人都可以帮助我准确地为linux平台上的icc生成16byte内存对齐数据。

您分配的内存是16字节对齐的。 看到:
&A[0] = 0x11fe010
但是在float数组中,每个元素都是4个字节,所以第二个是4字节对齐的。

您可以使用一个结构数组,每个结构包含一个浮点数,并带有aligned属性:

 struct x { float y; } __attribute__((aligned(16))); struct x *A = memalign(...); 

memalign函数返回的地址是0x11fe010 ,是0x10的倍数。 所以这个function正在做正确的事情。 这也意味着您的数组在16字节边界上正确对齐。 您以后要做的是在数组中打印float类型的每个下一个元素的地址。 由于在您的情况下float大小恰好是4个字节,因此每个下一个地址将等于前一个地址+4。 例如, 0x11fe010 + 0x4 = 0x11FE014 。 当然,地址0x11FE014不是0x10的倍数。 如果要在16字节边界上对齐所有浮点数,那么每个元素将不得不浪费16 / 4 - 1个字节。 仔细检查您正在使用的内在函数的要求。

AFAIK, memalignposix_memalign都在做他们的工作。

 &A[0] = 0x11fe010 

这与16字节对齐。

 &A[1] = 0x11fe014 

当你执行&A[1]你告诉compiller将一个位置添加到float指针。 它将不可避免地导致:

 &A[0] + sizeof( float ) = 0x11fe010 + 4 = 0x11fe014 

如果您打算将向量中的每个元素对齐到16个字节,则应考虑声明一个16字节宽的结构数组。

 struct float_16byte { float data; float padding[ 3 ]; } A[ ELEMENT_COUNT ]; 

然后,您必须为ELEMENT_COUNT (在您的示例中为20)变量分配内存:

 struct float_16byte *A = ( struct float_16byte * )memalign( 16, ELEMENT_COUNT * sizeof( struct float_16byte ) ); 

我在维基百科上找到了这段代码:

 Example: get a 12bit aligned 4KBytes buffer with malloc() // unaligned pointer to large area void *up=malloc((1<<13)-1); // well aligned pointer to 4KBytes void *ap=aligntonext(up,12); where aligntonext() is meant as: move p to the right until next well aligned address if not correct already. A possible implementation is // PSEUDOCODE assumes uint32_t p,bits; for readability // --- not typesafe, not side-effect safe #define alignto(p,bits) (p>>bits< 

我个人认为您的代码是正确的,适用于英特尔SSE代码。 当您将数据加载到XMM寄存器时,我相信处理器只能从主存储器加载4个连续的浮点数据,第一个浮点数据由16字节对齐。

简而言之,我相信你所做的正是你想要的。