2016-05-26 5 views
2

どのようにして__m256値のすべてのビットに1の値を設定できますか? AVXまたはAVX2組み込み関数を使用していますか?すべての1ビットに__m256値を設定する最速の方法

すべてゼロを取得するには、_mm256_setzero_si256()を使用することができます。

すべてのものを得るために、私は現在_mm256_set1_epi64x(-1)を使用していますが、私はこれがすべてゼロの場合よりも遅くなると思われます。ここにメモリアクセスまたはSalar/SSE/AVXの切り替えが含まれていますか?

そして、AVXで単純なビット単位のNOT演算を見つけることができないようですか? これが利用可能だった場合は、単純にsetzeroを使用し、その後にはNOTを使用できます。

+2

、 'pcmpeqdのXMM0、そのためxmm0'使用する人は、おそらくAVX {2}の等価操作はありますか? AVX2の@njuffa 'vpcmpeqd '。 – njuffa

+4

Clangは、 '_mm256_set1_epi64x(-1);'を '_mm256_cmpeq_epi64(_mm256_setzero_si256()、_mm256_setzero_si256());と同じように最適化しているようですが、' –

+4

も参照してください:http://stackoverflow.com/q/35085059/555045 – harold

答えて

5

もAVX、AVX2、およびAVX512のZMMおよびK(マスク)レジスタを覆うSet all bits in CPU register to 1 efficiently参照します。


あなたは明らかであっても行うことが自明であるASM出力、見ていない:gcc6.1とclang3.8と

#include <immintrin.h> 
__m256i all_ones(void) { return _mm256_set1_epi64x(-1); } 

compiles to

vpcmpeqd  ymm0, ymm0, ymm0 
    ret 


avx2をサポートするgccの最初のバージョンでは、この最適化を行うのに十分な知識がありました。 -mavx -mno-avx2では、gccはメモリからall-onesのベクトルをロードします。 Clangは128ビットall-onesを作り、vinsertf128を使います。


Agner Fog's optimizing assembly guideのベクトル部で説明したように、この方法は安価であるオンザフライ定数を生成します。すべてのもの(unlike _mm_setzero)を生成するにはまだベクトル実行ユニットが必要ですが、可能な2命令シーケンスよりも優れており、通常はロードよりも優れています。 というタグwikiも参照してください。

コンパイラは、generate more complex constants on the flyに単純なシフトですべてのものから生成することができたとしてもものを好きではありません。試してみても、__m128i float_signbit_mask = _mm_srli_epi32(_mm_set1_epi16(-1), 1)を書くと、コンパイラは通常、定数伝播を行い、ベクトルをメモリに入れます。後で定数を持ち上げるループがない場合に、メモリオペランドに折り畳むことができます。


そして私は、AVXでの簡単なビット単位のNOT演算を見つけることができないよう?

あなたはすべてのものとの排他的論理和演算することによってそれを行います。昔で

関連する問題