在c/c++中,由immintrin.h
提供的显式向量化内部函数,我认为,是一个杂乱无章的东西。也就是说,对于每个CPU指令集(例如,SSE、AVX2、AVX512等)对于每种数字类型(即浮点数、双精度数、整型数等),都有一个唯一的函数用于相同的基本运算,如_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
的结构并没有尽可能多地允许自然表达式。
为此,有没有替代immintrin.h
家族的“内在”头,允许更自然的表达,如上所述?至少一个涵盖了许多通用的、可伸缩的操作,如水平相加、不对齐加载、比较等?
对于这个问题,我对“让编译器向量化”不感兴趣。这简单地回答了是否使用内部函数的问题。
发布于 2016-05-03 00:08:32
在__attribute__ ((__vector_size__...
中使用类型定义的主要理由是,它可以生成更容易的源码。
首选immintrin.h
的主要理由是,它不是特定于编译器的。
你可以在网上搜索immintrin
和gcc vector extension
的组合,了解更多关于这两种语言的局限性。
在任何情况下,应用程序的其余部分都不应该注意到您正在使用其中的哪一个!:
通过将所有这些抽象到一个数学向量类/结构中,我会尽可能地推迟决定。它首先可以有一个简单的非矢量化实现。首先开发应用程序的所有其他部分。然后,您可以在将来始终使mathvector类成为矢量化类。
https://stackoverflow.com/questions/36986159
复制相似问题