【发布时间】:2018-07-21 09:59:31
【问题描述】:
我正在使用 AVX 内在 _mm256_extract_epi32()。
我不完全确定我是否正确使用它,因为 gcc 不喜欢我的代码,而 clang 编译它并运行它没有问题。
我是根据整数变量的值提取车道,而不是使用常量。
当用clang3.8(或clang4)为avx2编译以下sn-p时,它generates code并使用vpermd指令。
#include <stdlib.h>
#include <immintrin.h>
#include <stdint.h>
uint32_t foo( int a, __m256i vec )
{
uint32_t e = _mm256_extract_epi32( vec, a );
return e*e;
}
现在,如果我改用 gcc,比如说 gcc 7.2,那么编译器将无法生成代码,并出现以下错误:
In file included from /opt/compiler-explorer/gcc-7.2.0/lib/gcc/x86_64-linux-gnu/7.2.0/include/immintrin.h:41:0,
from <source>:2:
/opt/compiler-explorer/gcc-7.2.0/lib/gcc/x86_64-linux-gnu/7.2.0/include/avxintrin.h: In function 'foo':
/opt/compiler-explorer/gcc-7.2.0/lib/gcc/x86_64-linux-gnu/7.2.0/include/avxintrin.h:524:20: error: the last argument must be a 1-bit immediate
return (__m128i) __builtin_ia32_vextractf128_si256 ((__v8si)__X, __N);
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
In file included from /opt/compiler-explorer/gcc-7.2.0/lib/gcc/x86_64-linux-gnu/7.2.0/include/immintrin.h:37:0,
from <source>:2:
/opt/compiler-explorer/gcc-7.2.0/lib/gcc/x86_64-linux-gnu/7.2.0/include/smmintrin.h:449:11: error: selector must be an integer constant in the range 0..3
return __builtin_ia32_vec_ext_v4si ((__v4si)__X, __N);
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
我有两个问题:
- 为什么clang 可以很好地使用变量,而gcc 是否想要一个 恒定?
- 为什么 gcc 不能下定决心?首先它需要一个 1 位立即数,然后它需要一个 0..3 范围内的整数常量,它们是不同的。
Intels Intrinsics Guide 并没有对 _mm256_extract_epi32() 的索引值指定约束,那么这里是谁,gcc 还是 clang?
【问题讨论】:
-
注意:clang5 也会编译代码,但会往返内存以提取车道。
标签: simd intrinsics avx avx2