Intel AVX
Intel® Intrinsics Guide is all you need.
SSE: Streaming SIMD Extensions
AVX: Advanced Vector Extensions
flow(类似于GPU编程)
- 创建SIMD寄存器
- 加载数据到SIMD寄存器
- 使用SIMD指令
- 将SIMD寄存器中的数据存回内存
Terms
- 命名格式
- 数据类型命名:
__m
+ SIMD寄存器位宽 + 数据类型(不加字母表示单精度), e.g.__m256
表示256位宽的单精度浮点数,__m256i
表示256位宽的整数,__m256d
表示256位宽的双精度浮点数- CPU需要先把数据加载到专门的寄存器才能进行向量指令操作
- Intrinsic函数命名:
_mm
+ 数据类型 + 操作名 + 操作范围和数据类型, e.g._mm
默认128位宽,_mm256
,_mm512
- 操作名如:
_add
,_mul
,_load
,_loadu
等_loadu
表示不对齐加载
- 操作范围和数据类型如:
_ps
,_pd
,_epi32
等_ps
packed(操作所有数据)single(单精度)
_ss
single(操作单个数据)single(单精度)- 第一个元素, 最低位元素
- e.g.
_mm256_load_ps
表示将浮点数加载到256位宽的寄存器_mm256_add_ps
表示将整个向量相加
- 数据类型命名:
- 万能头:
<intrin.h>
- 常用头
<immintrin.h>
Intel-specific intrinsics(AVX)
- 编译配置
-msseN
,-mavxN
其中N表示版本号
向量加法
1 |
|
使用非内存对齐版本的load和store是因为创建变量时没保证内存对齐。这时使用内存对齐的load和store可能会触发边界保护异常。
内存操作
创建内存对齐的变量
- MSVC:
__declspec(align(32)) float a[8];
- GCC:
__attribute__((__aligned__(32))) float a[8];
- 动态分配:
_aligned_malloc(size, 32)
或new ((std::align_val_t)32) float[SIZE]
, 并使用对应的_aligned_free
释放
_mm_load_ps
, _mm_store_ps
的本质就是指针类型转换并接引用。
1 | /* Load four SPFP values from P. The address must be 16-byte aligned. */ |