加速图像处理的神器: Intel ISPC编译器 (四) 迁移图像旋转算法 - 从 ISPC双精度 到 ISPC单精度

前面把原始的C代码转成了ISPC可编译的C代码,其中image_rotate_double_ispc函数里面的数据都是基于double双精度来运算的。我的电脑是支持AVX/AVX2指令集的,所以一次可以并发做4个double浮点的运算,理论上可以提升4倍的算力。

通过ISPC的编译,实际获得了3.7倍的性能加速。

 

从上图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()代码对比

 

运行一下单精度计算版本的代码,运行时间: 781ms

 

和image_rotate_double_ispc版本的性能提升

1157ms/781ms = 1.48X

和原始C代码的性能比对

4294ms/781ms = 5.50X

 

5.5X虽然和理论的8X有很大的差距,但是已经很满意了,毕竟这段代码写的时候没有考虑任何内存访问的优化,现在能有这个性能提升很好很暴力!!!

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值