AVX图像算法优化系列一: 初步接触AVX。( 二 )


inline void _mm256_store2si256_16char(unsigned char *Dest, __m256i Result_L, __m256i Result_H){//short A0A1A2A3B0B1B2B3A4A5A6A7B4B5B6B7__m256i Result = _mm256_packs_epi32(Result_L, Result_H);//byte A0A1A2A3B0B1B2B300000000A4A5A6A7B4B5B6B700000000Result = _mm256_packus_epi16(Result, _mm256_setzero_si256());//A0A1A2A3B0B1B2B3A4A5A6A7B4B5B6B70000000000000000_mm_storeu_si128((__m128i *)Dest, _mm256_castsi256_si128(_mm256_permutevar8x32_epi32(Result, _mm256_setr_epi32(0, 4, 1, 5, 2, 3, 6, 7))));}可以这样认为,_mm256_permutevar8x32_epi32就是类似于SSE环境下的256位的32位shuffle,即真正的_mm256_shuffle_epi32 。
AVX2里还增加了一各比较特别的功能,gather系列指令,这个系列的指令可以从不同的位置收集数据到寄存器中,这个是在SSE中缺失的 。这个功能可以实现更为快速的数据查表功能,我们后续应该会有一个单独的文章讲这个算子 。
【AVX图像算法优化系列一: 初步接触AVX。】第五、AVX相较于SSE的提速可能没有你想象的高
表面上看 , AVX一次性可以处理256位数据,SSE只能处理128位,带宽是提高了一倍,但是从实际的测试表现来看 , 同样的算法 , 使用AVX的提速比相对于SSE来说绝对是不可能达到1倍的 , 能有40%的提速就已经很不错了,这也导致我们从SSE转型为AVX时能得到的喜悦绝对没有从C++转型到SSE时那么充足 。很多算法只有5%的提速,这当然于算法本身的结构有关,如果是以读取内存为主的程序 , 提速比会很低,以数值计算、比较等等为主的程序就要稍微高一些 , 我目前写的一些AVX程序和SSE比较 , 提速比大概5%到35%之间 。
另外一点 , 在不同的CPU上(都支持AVX及AVX2),同一个算法的提速比例也是不同,我甚至遇到过AVX还比SSE慢一点的CPU(都是64位程序) , 这个目前我不知道是为什么 。
    第六、AVX和SSE的选择问题
这个没有绝对的 , 只是谈点自己的看法 。
在PC上,一个算法如果需要使用SIMD优化,除了考虑硬件的因素外(现在市面上能看到的硬件不支持AVX或者AVX2的还是有很多在使用的,特备是AVX2,我他妈的去年买的一个机器,CPU居然还只支持AVX , 也是醉了),还要考虑算法本身的粒度,SSE真的很自由,特别是shuffle,说实在的,我倒现在还没想到,如何用AVX2实现 32个字节的自由shuffle, AVX的那个_mm256_shuffle_epi8就是个太监啊 。所以你的算法里需要借用大量这样的shuffle,还是考虑用SSE吧 ,  如果以32位整形数据或者浮点计算为主,AVX肯定在效率上还是要更为高效 。
在学习曲线上,如果你没有AVX的基?。苯哟覥开始使用AVX,你会发现你要做很多弯路,因为正如前面所述,使用AVX脱离不了SSE , 最好先了解一点SSE的知识 。
如果有SSE的基础 , 去转学AVX,则轻松很多,只需要把AVX2里的那个permute、broadcast等等理解透了 , 你也就基本掌握了真谛 。
其他:
十一期间 , 我大概把我原有的基于SSE算法里抽取20个左右,转换为AVX的版本,另外,还提供了普通的C语言版本的算法 , 并提供了速度比较,注意,其实这里的C语言算法,并不是真正的C算法了,他只能说是编译器自动向量化后的算法,也就是比较编译器自己的向量化和我们手工向量化的速度差异了 。因为在同一个DEMO里 , 为了照顾AVX的代码,只能选择/arch:AVX选项 。

AVX图像算法优化系列一: 初步接触AVX。

文章插图
 本文可执行Demo下载地址:  https://files.cnblogs.com/files/Imageshop/SSE_Optimization_Demo.rar,菜单中蓝色字体显示的部分为已经使用AVX加速的算法 , 如果您的硬件中不支持AVX,可能这个DEMO你无法运行 。

推荐阅读