我有一个通用构建的二进制文件,需要包含一个查找例程,该例程被编译成矢量化指令或基于 cpu 是否支持 avx/avx2。
查找例程与此处解释的相同: 使用 SSE/AVX/AVX2 检查 __m128i 的所有字节是否匹配单个字节
如果 cpu 支持 avx/avx2,这里 (_mm_set1_epi8, __mm_cmpeq_epi8,_mm_movemask_epi8) 内在集将编译为向量化指令,否则仅编译为基于 sse 的指令。
在一个过于简化的 main.c 中:在没有 mavx/mavx2 和 -msse3 -msse4 -o 3 的情况下编译
#define __SSE2__
#define SSE_Lookup() \ /*psuedo code*/
_mm_set1_epi8; \
__mm_cmpeq_epi8; \
match_bitmap=_mm_movemask_epi8
#endif
static inline __attribute__((always_inline))
uint64_t foo()
{
unsigned int a=1,b,c,d;
uint64_t match_bitmap;
__cpuid(1,a,b,c,d);
if(c & bit_AVX)
{
match_bitmap= avx_lookup();
}else
{
#if __SSE__
SSE_Lookup();
#endif
}
}
foo_avx.c
#include <emmintrin.h>
//mimicing an intrinsic wrapper
//don't want to create any new stack frames so keeping it inline
extern __inline int __attribute__((__gnu_inline__, __always_inline__, __artificial__))
__avx_lookup (char kk, __m128i h)
{
__m128i k = _mm_set1_epi8(kk);
__m128i r = _mm_cmpeq_epi8(k,h);
return _mm_movemask_epi8(r);
}
使用 x86_64_gcc-7.5.0_glibc/bin/x86_64-openwrt-linux-gnu-gcc 编译
Makefile:72: 目标 '/build/x86_64/common/foo_avx.o' 的配方失败 make[3]: *** [/build/x86_64/common/foo_avx.o] 错误 1
所以问题是: