1. 环境
OS: win10 和 centos7,其他的linux应该都差不多。(参考这篇文章,作者也在ubuntu18.04以及Archlinux上进行过对应的测试均可)
gcc: 如果使用AVX指令集在编写cmake或者makefile文件时需要加上 -mavx2 参数。低版本的gcc 不支持 -mavx2 参数,具体是在哪个版本加进来的不知道,试试就知道了。
CPU: 其实处理器也需要支持这个指令集,比如avx512需要Intel四代之后才有,可以去对应厂家的官网上查询,或者直接跑代码,看下耗时。
2. 头文件
SIMD的相关头文件包含如下:
#include <mmintrin.h> //MMX
#include <xmmintrin.h> //SSE(include mmintrin.h)
#include <emmintrin.h> //SSE2(include xmmintrin.h)
#include <pmmintrin.h> //SSE3(include emmintrin.h)
#include <tmmintrin.h> //SSSE3(include pmmintrin.h)
#include <smmintrin.h> //SSE4.1(include tmmintrin.h)
#include <nmmintrin.h> //SSE4.2(include smmintrin.h)
#include <wmmintrin.h> //AES(include nmmintrin.h)
#include <immintrin.h> //AVX(include wmmintrin.h)
#include <intrin.h> //(include immintrin.h)
3.部分数据类型(以AVX指令集为例)
typedef float __m256 __attribute__ ((__vector_size__ (32),__may_alias__));
typedef long long __m256i __attribute__ ((__vector_size__ (32),__may_alias__));
typedef double __m256d __attribute__ ((__vector_size__ (32),__may_alias__));
4.部分函数实例(以long long类型的__m256i类型数据为例)
将连续32字节的内存复制到__m256i 类型变量中:
extern __inline __m256i __attribute__((__gnu_inline__, __always_inline__, __artificial__))
_mm256_loadu_si256 (__m256i_u const *__P)
{
return *__P;
}
extern __inline __m256i __attribute__((__gnu_inline__, __always_inline__, __artificial__))
_mm256_load_si256 (__m256i const *__P)
{
return *__P;
}
上边两个函数的区别在: 前者没有u,后者有u。带u的表示即使需要复制的内存起始地址不是32的倍数也没事,应该是汇编那层给处理了,至少不会出错;不带u的,如果起始地址不是32的倍数,运行的时候就会segmentation fault(core dumped)
extern __inline __m256i
__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
_mm256_xor_si256 (__m256i __A, __m256i __B)
{
return (__m256i) ((__v4du)__A ^ (__v4du)__B);
}
extern __inline __m256i
__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
_mm256_subs_epu8 (__m256i __A, __m256i __B)
{
return (__m256i)__builtin_ia32_psubusb256 ((__v32qi)__A, (__v32qi)__B);
}
部分运算函数,这些操作暂时没遇到比较特殊的要求。
extern __inline void __attribute__((__gnu_inline__, __always_inline__, __artificial__))
_mm256_storeu_si256 (__m256i_u *__P, __m256i __A)
{
*__P = __A;
}
extern __inline void __attribute__((__gnu_inline__, __always_inline__, __artificial__))
_mm256_store_si256 (__m256i *__P, __m256i __A)
{
*__P = __A;
}
4.遇到问题如何查找
4.1 官方的函数说明
https://software.intel.com/sites/landingpage/IntrinsicsGuide/#expand=3828,5597&techs=AVX,AVX2
注意举一反三,在查找某一类函数时注意观察他们的特性。
4.2比较好的博客
1 http://www.cnblogs.com/zyl910/archive/2012/10/22/simdsumfloat.html
2 http://www.cnblogs.com/zyl910/archive/2012/08/27/intrin_table_gcc.html
3 http://blog.csdn.net/zyl910/article/category/1128358
4 http://stackoverflow.com/questions/4468420/segmentation-fault-due-to-memory-alignment-in-sse
本文档详细介绍了在Win10和CentOS环境中使用AVX指令集的步骤,涉及头文件引入、__m256i等数据类型及其内存操作函数,如加载、存储和算术运算,以及遇到问题时的官方文档查找和博客参考。

3044

被折叠的 条评论
为什么被折叠?



