2017-11-10 84 views
3

我有一个由7个__m256值组成的结构,它存储在内存中的32字节对齐。提示编译器可以使用对齐的memcpy

typedef struct 
{ 
     __m256 xl,xh; 
     __m256 yl,yh; 
     __m256 zl,zh; 
     __m256i co; 
} bloxset8_t; 

我通过使用posix_memalign()函数动态分配的数据,或者使用用于静态分配数据的(aligned(32))属性实现32字节对齐。

对齐方式很好,但是当我使用两个指向这样一个结构体的指针,并将它们作为memcpy()的目标和源代码传递时,编译器决定使用__memcpy_avx_unaligned()进行复制。

我该如何强制clang使用对齐的avx memcpy函数,而我认为这是更快的变体?

操作系统:Ubuntu 16.04.3 LTS,Clang:3.8.0-2ubuntu4。

UPDATE
的__memcpy_avx_unaligned()复制两个或更多个结构,当仅调用。当只复制一个时,clang会发出14个vmovup指令。

+0

未经测试,但值得一试:我认为我之前通过在memcpy之前添加一个assert()来声明地址是32字节对齐的。一些编译器可以采取这些提示并使用它们进行优化。 –

+0

我无法用Clang 3.9重新编译(我收到一堆'vmovaps'),不幸的是我无法尝试3.8 – harold

+0

@harold如果您一次复制两个或更多结构,则使用memcpy_avx_unaligned()。一个结构实际上是通过移动指令完成的,在我的情况下它是未对齐的:vmovup(并且它使用了其中的14个)。 – Bram

回答

6

__memcpy_avx_unaligned只是一个内部的glibc函数名称。这并不意味着有更快的__memcpy_avx_aligned函数。这个名字只是向glibc开发者传达了这个memcpy变体是如何实现的。

另一个问题是,C编译器使用四个AVX2加载/存储操作发出memcpy的内联扩展会更快。该代码将比memcpy呼叫更大,但总体来说可能会更快。有可能帮助编译器使用__builtin_assume_aligned builtin来做到这一点。

+0

谢谢。我注意到如果memcpy只有1个结构,则使用14条移动指令。我能够强制他们从未对齐的移动到构造'__builtin_assume_aligned()'的对齐移动如果您可以添加对此的引用,我可以接受这个答案。 – Bram

相关问题