【发布时间】:2016-08-27 10:30:19
【问题描述】:
我认为,在 c/c++ 中,immintrin.h 提供的显式矢量化内在函数是一个杂项。也就是说,对于每个 CPU 指令集(例如 SSE、AVX2、AVX512、...)和每种数字类型(即 float、double、int 等),对于相同的基本操作,都有一个独特的函数,例如 @ 987654326@,_mm_add_epi16,_mm256_add_epi8,_mm256_add_epi16,都是基本的+。因此,如果您使用 AVX 的内在函数进行编码,则必须在升级到 AVX2 时重新编码,然后再升级到 AVX512 等等。
另一方面,一些编译器基本的内置运算符(即“+”、“-”等)似乎在所有类型(向量和非向量)上都能很好地工作(提供数据对齐)和一些混合类型的操作(如下面的 sn-p 所示),从而提高了可读性和可扩展性(使用 simd 指令集)。
// no need for #include "immintrin.h"
#ifndef __AVX2__
#define SIMD_LEN 16
#else
#define SIMD_LEN 32
#endif
typedef int num_t;
num_t a[N], b[N];
// for any num_t and SIMD_LEN, explicitly vectorize b[n] = 2*a[n] + 4
typedef num_t vec_t __attribute__ ((__vector_size__ (SIMD_LEN)));
vec_t *vA = (vec_t*)a;
vec_t *vB = (vec_t*)b;
int nNums = SIMD_LEN/sizeof(num_t);
for (int n=0; n < (N/nNums); n++)
vB[n] = 2*vA[n] + 4;
显然,这种灵活性/可扩展性不适用于所有操作,但似乎immintrin.h 的结构并未尽可能允许自然表达。
为此,如上图所示,immintrin.h 系列是否有替代的“内在”标头允许更自然的表达?至少一个涵盖许多通用的、可扩展的操作,如水平添加、未对齐加载、比较等?
出于这个问题的目的,我对“让编译器向量化”不感兴趣。这只是回答了是否使用内在函数的问题。
【问题讨论】:
-
gcc.gnu.org/onlinedocs/gcc/Vector-Extensions.html 部分是 gcc 特有的,但很好用。
-
关于gcc向量扩展gcc.gnu.org/bugzilla/show_bug.cgi?id=68123的一些有趣的事情
-
我知道内置矢量扩展,如 ihttps://gcc.gnu.org/onlinedocs/gcc/Vector-Extensions.html 所示。事实上,
immintrin.h只是建立在它们之上的宏和函数。我正在寻找immintrin.h的替代方案,它建立在相同的向量扩展之上,但使用不同的语法,在将代码从 SSE 迁移到 AVX 到 AVX2 到 AVX512 时不会中断。 -
是的。使用
#include "vectorclass.h"。那是 C++ 的。 -
Yeppp! 支持 C.
标签: c gcc vectorization simd intrinsics