JincResize 代码重构(2)
指令集优化
Generation
(更多内容可查看使用 AVX 系列指令集进行向量化,也可看一下这篇很欢乐的文章 GCC 神坑:-march=native)
对于 GCC 编译器,在编译命令中加入-march=native
选项,可调用本地的库,使用 AVX 指令集优化。
Functions
(Doc 在这里,直接搜索想查的函数即可)
(另外也可看一下Intel AVX を使用して SIMD 演算を試してみる - その2 -,但函数参数不如上面的 Doc 详细)
_mm_malloc(size_t size, size_t align)
:对齐的问题
_mm256_load_ps
:float 类型输入
_mm256_load_pd
:double 类型输入
__m256d _mm256_mul_pd(__m256d, __m256d)
:256 位双精度乘法
Type
(来自インテル® アドバンスト・ベクトル・エクステンション (インテル® AVX) 組込み関数の詳細)
__m256
:容纳 8 个 32 位单精度浮点数值
__m256d
:容纳 4 个 64 位双精度浮点数值
实际代码
这部分代码来自 luglio,我只是做了一点适配,因为我现在还没有把 JincResize 的中间数据从 double 改为 float。
对齐的问题
1 |
|
_mm_malloc
相比一般的malloc
,增加了一个用于数据对齐的参数。具体在这里(数据对齐有助于实现向量化)有讲。
虽然我现在还不能完全理解这个概念,但经过测试,对于JincResize现有的代码,把上面的64
写成32
,和没有 AVX 优化的速度几乎一样。
数据类型
1 |
|
看一下两个函数的声明
1 |
|
注意到第二个参数类型分别是__m256
、__m256d
,所以有了上述区别。
代码细节的整理
(2020.3.2 完成 2020.3.8 补记)
删去冗余代码
之前没注意,可以直接获取特定平面尺寸的啊(commit 83eb7f)。
把乘方换成乘法
嗯,就是求平方嘛,直接乘多好,用pow()
更慢。
说起来虽然是这么一个小改动,但速度提升真是明显(从 r5 到 r6 的 25% 速度提升,AVX优化贡献的可能还不如这里多)。毕竟是在计算量最大的四重循环内,微小的改动就能有大的影响。
经过从 r5 到 r6 的修改,以及对卷积的认识,算是把 JincResize 代码重新认识了一遍,哪里是速度敏感的,怎么样让代码简洁一点,也有了体会。