在c/c++中,
另一方面,一些编译器的基本内置运算符(如'+'、'-'等)似乎在所有类型(向量和非向量)上都能很好地工作(前提是数据对齐),并且一些混合类型操作(如下面的代码片段所示)可以实现更好的可读性和可扩展性(使用simd指令集)。
显然,这样的灵活性/可扩展性并不适用于所有操作,但似乎
为此,是否有一种替代“intrinsic”头文件与
至于这个问题的目的,我不感兴趣“只需让编译器矢量化”。那只是回答是否使用内部函数的问题。
immintrin.h
提供的显式向量化内嵌函数可以说是一种权宜之计。也就是说,对于每个CPU指令集(如SSE、AVX2、AVX512等)和每种数字类型(即float、double、int等),都有唯一的函数可用于相同的基本操作,例如_mm_add_epi8
、_mm_add_epi16
、_mm256_add_epi8
、_mm256_add_epi16
,所有这些函数都是基于基本运算符+
。因此,如果您使用AVX内嵌函数编码,当您升级到AVX2时,您需要重新编码,然后再升级到AVX512,以此类推。另一方面,一些编译器的基本内置运算符(如'+'、'-'等)似乎在所有类型(向量和非向量)上都能很好地工作(前提是数据对齐),并且一些混合类型操作(如下面的代码片段所示)可以实现更好的可读性和可扩展性(使用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
的结构不如它本可以允许自然表达。为此,是否有一种替代“intrinsic”头文件与
immintrin.h
家族相比,允许更自然的表达,如上所示?至少有一个涵盖许多通用、可扩展操作,如横向加法、非对齐加载、比较等吗?至于这个问题的目的,我不感兴趣“只需让编译器矢量化”。那只是回答是否使用内部函数的问题。
#include "vectorclass.h"
。那是用于C++的。 - Z boson