加速图像处理的神器: INTEL ISPC 编译器迁移图像旋转算法 - 从 ISPC双精度到 ISPC单精度
Posted 帅的发光发亮
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了加速图像处理的神器: INTEL ISPC 编译器迁移图像旋转算法 - 从 ISPC双精度到 ISPC单精度相关的知识,希望对你有一定的参考价值。
从 ISPC双精度到 ISPC单精度
前面把原始的C代码转成了ISPC可编译的C代码,其中image_rotate_double_ispc函数里面的数据都是基于double双精度来运算的。我的电脑是支持AVX/AVX2指令集的,所以一次可以并发做4个double浮点的运算,理论上可以提升4倍的算力。
通过ISPC的编译,实际获得了3.74X倍的性能加速。
从上图YMM寄存器的宽度和浮点数据的宽度来看,YMM寄存器可以一次做8个单精float型数据的计算。这次就来试试把image_rotate_double_ispc函数里面的计算全部改为单精浮点运算,看看性能有多少提升。
代码改动
- 把所有的double替换成float
- 定义float常量的后缀是f, 定义double常量的后缀是d
#define M_PI_F 3.1415926535f
export void image_rotate_float_ispc(uniform const uint8 srcImg[], uniform uint8 dstImg[], uniform float center_x,uniform float center_y, uniform int Width, uniform int Height, uniform float RotateDegree)
uniform float angle = (float)RotateDegree*M_PI_F / 180.0;
uniform float alpha = cos(angle);
uniform float beta = sin(angle);
uniform float m[6];
m[0] = alpha;
m[1] = -beta;
m[2] = (1.0 - alpha) * (float)center_x + beta * (float)center_y ;
m[3] = beta;
m[4] = alpha;
m[5] = (1.0 - alpha) * (float)center_y - beta * (float)center_x;
for (uniform int row = 0; row < Height; row++)
foreach (col = 0 ... Width)
float x, y;
int leftX, rightX, topY, bottomY;
float w00, w01, w10, w11;
float fxy;
x = m[0] * (float)col + m[1] * (float)row + m[2];
y = m[3] * (float)col + m[4] * (float)row + m[5];
leftX = floor(x);
topY = floor(y);
rightX = leftX + 1.0;
bottomY = topY + 1.0;
w11 = abs(x - leftX)*abs(y - topY);
w01 = abs(1.0 - (x - leftX))*abs(y - topY);
w10 = abs(x - leftX)*abs(1 - (y - topY));
w00 = abs(1.0 - (x - leftX))*abs(1.0 - (y - topY));
if ((int)leftX >= 0 && (int)rightX < Width && (int)topY >= 0 && (int)bottomY < Height)
fxy = (float)srcImg[topY*Width+ leftX]*w00 +
(float)srcImg[bottomY*Width+ leftX]*w01 +
(float)srcImg[topY*Width+ rightX]*w10 +
(float)srcImg[bottomY*Width+ rightX]*w11;
fxy = round(fxy);
if (fxy < 0)
fxy = 0;
if (fxy > 255)
fxy = 255;
dstImg[row*Width+ col] = (uint8)(fxy);
else
dstImg[row*Width + col] = 0;
;
;
代码对比
image_rotate_double_ispc()和image_rotate_float_ispc()
运行一下单精度计算版本的代码,运行时间: 761ms
性能提升
和image_rotate_double_ispc版本的性能提升
1148ms/761ms = 1.5X
和原始C代码的性能比对
4301ms/761ms = 5.65X
5.65X虽然和理论的8X有很大的差距,但是已经很满意了,毕竟这段代码写的时候没有考虑任何内存访问的优化,现在能有这个性能提升很好很暴力!!!
以上是关于加速图像处理的神器: INTEL ISPC 编译器迁移图像旋转算法 - 从 ISPC双精度到 ISPC单精度的主要内容,如果未能解决你的问题,请参考以下文章
加速图像处理的神器: INTEL ISPC编译器 迁移图像旋转算法 - ISPC单精度 从单核 到 多核
加速图像处理的神器: INTEL ISPC编译器 迁移图像旋转算法 - ISPC单精度 从单核 到 多核
加速图像处理的神器: INTEL ISPC编译器 迁移图像旋转算法 - ISPC单精度 从单核 到 多核
加速图像处理的神器: INTEL ISPC 编译器迁移图像旋转算法 - 从 ISPC双精度到 ISPC单精度