2017-11-10 25 views
3

私はメモリに32バイト整列して格納された7つの__m256値からなる構造体を持っています。整列されたmemcpyを使用できるコンパイラへのヒント

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

Iは、動的に割り当てられたデータのためposix_memalign()関数を使用して、または静的に割り当てられたデータのため(aligned(32))属性を使用して32バイトのアラインメントを達成します。

アライメントは問題ありませんが、このような構造体に2つのポインタを使用し、それらをmemcpy()の送り先とソースとして渡すと、コンパイラは__memcpy_avx_unaligned()を使用してコピーを決定します。

代わりに、より高速なバリアントであると思われる、代わりにアラインされたavx memcpy関数を強制的に使用することはできますか?

OS:Ubuntu 16.04.3 LTS、Clang:3.8.0-2ubuntu4。

UPDATE
__memcpy_avx_unaligned()は、2つの以上の構造体をコピーする場合にのみ呼び出されます。ちょうど1つをコピーするとき、clangは14のvmovup命令を出します。

+0

未テストですが、試してみる価値があります。以前は、アドレスが32バイトにアライメントされていることを主張する 'memcpy'の前に' assert() 'を追加していました。コンパイラの中には、これらのヒントを利用して最適化に使用するものがあります。 –

+0

Clang 3.9でこれを再現できませんでした。残念ながら私は試してみることができません。3.8 – harold

+0

@harold memcpy_avx_unaligned()は、2つ以上の構造体を一度にコピーする場合に使用されます。 1つの構造体は実際には私の場合は整列していない移動命令で処理されます:vmovup(そしてそのうち14個が使用されます) – Bram

答えて

6

__memcpy_avx_unalignedは、glibcの内部関数の名前です。それはより速い__memcpy_avx_aligned機能があることを意味するものではありません。この名前はglibc開発者にこのmemcpyの亜種がどのように実装されているかのヒントを伝えるだけです。

もう1つの質問は、AVX2の4つのロード/ストア操作を使用して、Cコンパイラがmemcpyのインライン展開を実行する方が速いかどうかです。そのコードはmemcpyコールよりも大きくなりますが、全体的にはまだ高速です。コンパイラが__builtin_assume_aligned builtinを使用してこれを行うのを手助けすることは可能かもしれません。

+0

ありがとうございます。私はあなたが1つの構造体をmemcpyすれば、14の移動命令が使用されていることに気付きました。私はアライメントされていない動きから構造体 '__builtin_assume_aligned()'を使って動きを整列させるように強制することができました。これを参照することができれば、答えとして受け入れることができます。 – Bram

関連する問題