AVX全称Advanced Vcetor Extension,是对SSE的后续扩展,主要分为AVX、AVX二、AVX512三种。在目前常见的机器上,大多只支持到AVX系列,所以其余SIMD扩展指令咱们就先不学习了。git
AVX使用了16个YMM寄存器,主要针对的是浮点数计算优化,支持32位单精度和64位双精度。AVX将打包长度由SSE的128位扩展为256位。github
AVX主要有两个改进:学习
AVX使用了SSE的128的寄存器,YMM寄存器的低位部分是XMM寄存器:fetch
AVX2是AVX指令的扩展,主要在整形数据方面作了完善:优化
AVX-512指令扩展主要把256位数据扩展到512位,在数据级并行又迈进了一步。AVX-512扩展包含好几个部分:ui
可是只有Foundation部分是各实现保证支持的。code
不是全部机型都通用的指令集须要调用cpuid
指令来检测:blog
push ecx mov eax, 0 cpuid cmp ecx, 1 jb notSupported // check if supports EAX=1 when using CPUID mov eax, 1 cpuid and ecx, 0x18000000 // clear non-related bits cmp ecx, 0x18000000 // check OSXSAVE and avx jne notSupported mov ecx, 0 XGETBV // get XCR0 register value and eax, 0x6 cmp eax, 0x6 // check XMM and YMM state jne notSupported mov eax, 1 jmp done notSupported: mov eax, 0 done: pop ecx
根据Intel开发者指南,咱们须要检测OSXSAVE、AVX、XMM state、YMM state这四个功能。cpuid隐式使用eax寄存器做为指令参数执行:当eax位0时,cpuid返回eax可传入最大值;传入1时,返回功能标记为,这时候咱们经过检查ecx寄存器的第2八、29位就能够判断是否分别支持OSXSAVE和AVX功能;以后咱们要给ecx赋值0来做为参数调用XGETBV指令,这个指令返回结果的第二、3位代表XMM、YMM状态是否开启。ip
与以前的随笔同样,咱们对10000000个单精度浮点数进行加操做,可是我电脑机型不支持AVX2,所以没法演示AVX系列的整数优化操做:ci
__m256 step = _mm256_set_ps(10.0, 10.0, 10.0, 10.0, 10.0, 10.0, 10.0, 10.0); __m256* dst = reinterpret_cast<__m256*>(data); for (unsigned i = 0; i < count; i += 8) { __m256 sum = _mm256_add_ps(*dst, step); *dst++ = sum; }
这个运行时间代表,有时候简单的使用AVX来进行计算优化并不必定会提高程序的运行效率,得深刻分析,完整代码见连接。