char*数据读取的优化

清涧煎饼 2015-05-21 01:41:18
我们现在需要读取一张4K 大小 char*类型图像中的任何位置(x,y) 大小为16*16数据,线程之间是并行读取的,测试发现这个地方由于图像数据是global型的,因此读取数据耗时比较严重,现在想进行一定的优化,不知道有什么好的办法没?

本人起初做了__global int* piTemp = (__global int*)(pchImg + y*width + x);
然后使用piTemp指针一次读取四个字节来加速,但是由于数据对齐的原因会报错;
后来改为了 __global int* piTemp = (__global int*)(pchImg + y*width + ((x>>2)<<2));
这样虽然读取快了,但是有数据偏移,导致结果不准确。

不知道各位在char*图像数据的读取中有什么好的建议和方法?
...全文
656 7 打赏 收藏 转发到动态 举报
写回复
用AI写文章
7 条回复
切换为时间正序
请发表友善的回复…
发表回复
zenny_chen 2015-06-05
  • 打赏
  • 举报
回复
引用 6 楼 shihufeng 的回复:
我现在在做4k图像的运动估计和补偿,现在计算量不大,看着ALU busy为7%,而 memory busy为 70%左右,所以这里耗时严重,现在每帧处理的速度为12ms左右,通过上面简单转换类型的话可以达到4ms,但是这里会有误差,担心误差累积后出错。 所以想找到一个读取速度优化的方法? 能有建议吗?
对于: __global int* piTemp = (__global int*)(pchImg + y*width + x); 您尝试使用这种方式:

__global uchar* piTemp = (__global uchar*)(pchImg + y*width + x);

int x0 = piTemp[0];
int x1 = piTemp[1];
int x2 = piTemp[2];
int x3 = piTemp[3];

这样在一个工作项内既有计算量以掩盖访存延迟,而且也能有效防止数据对齐而引发的错误。
清涧煎饼 2015-06-05
  • 打赏
  • 举报
回复
引用 4 楼 zenny_chen 的回复:
[quote=引用 3 楼 shihufeng 的回复:] 我的数据是单通道8bit的,不想花时间和内存将其转换为int型。 现在是每次去读一个char像素值都要占用一次带宽(128bit),而有效信息只有8bit,浪费严重。 __global int* piTemp = (__global int*)(pchImg + y*width + x); 这个式子中x的偏移不为4的整数倍时会发生转换失败的。
因为字节没对齐,所以可能会发生转换失败。我个人建议,由于你数据量不大,即便就每个工作项取8比特,一般来说也能充分利用GPU的硬件资源,尤其是当前比较新的架构的GPU。所以,这里索性用单字节访问,您可以试试。我感觉性能不比4字节一取要差到哪里。[/quote] 谢谢你的回答! 我现在在做4k图像的运动估计和补偿,现在计算量不大,看着ALU busy为7%,而 memory busy为 70%左右,所以这里耗时严重,现在每帧处理的速度为12ms左右,通过上面简单转换类型的话可以达到4ms,但是这里会有误差,担心误差累积后出错。 所以想找到一个读取速度优化的方法? 能有建议吗?
zenny_chen 2015-06-02
  • 打赏
  • 举报
回复
引用 3 楼 shihufeng 的回复:
我的数据是单通道8bit的,不想花时间和内存将其转换为int型。 现在是每次去读一个char像素值都要占用一次带宽(128bit),而有效信息只有8bit,浪费严重。 __global int* piTemp = (__global int*)(pchImg + y*width + x); 这个式子中x的偏移不为4的整数倍时会发生转换失败的。
因为字节没对齐,所以可能会发生转换失败。我个人建议,由于你数据量不大,即便就每个工作项取8比特,一般来说也能充分利用GPU的硬件资源,尤其是当前比较新的架构的GPU。所以,这里索性用单字节访问,您可以试试。我感觉性能不比4字节一取要差到哪里。
清涧煎饼 2015-06-01
  • 打赏
  • 举报
回复
引用 2 楼 zenny_chen 的回复:
如果你的图像格式是RGBA8888的话,那么这种取法肯定就有问题了。你如果要用int类型,那么把pchImg也变为int*就行了,不需要自己去转类型。如果你要转类型,由于pchImg原本是char*类型,所以pchImg + y*width + x这种定位肯定就不正确了,你得用: pchImg + ( y * width + x) * 4才行。
我的数据是单通道8bit的,不想花时间和内存将其转换为int型。 现在是每次去读一个char像素值都要占用一次带宽(128bit),而有效信息只有8bit,浪费严重。 __global int* piTemp = (__global int*)(pchImg + y*width + x); 这个式子中x的偏移不为4的整数倍时会发生转换失败的。
zenny_chen 2015-05-28
  • 打赏
  • 举报
回复
如果你的图像格式是RGBA8888的话,那么这种取法肯定就有问题了。你如果要用int类型,那么把pchImg也变为int*就行了,不需要自己去转类型。如果你要转类型,由于pchImg原本是char*类型,所以pchImg + y*width + x这种定位肯定就不正确了,你得用: pchImg + ( y * width + x) * 4才行。
清涧煎饼 2015-05-21
  • 打赏
  • 举报
回复
有没有人帮忙提个意见?

602

社区成员

发帖
与我相关
我的任务
社区描述
异构开发技术
社区管理员
  • OpenCL和异构编程社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧