使用opencl快速交换字节序的方法

时间:2013-05-13 20:57:19

标签: buffer byte opencl endianness

我正在阅读和编写大量FITS和DNG图像,这些图像可能包含与我的平台和/或opencl设备不同的字节序数据。

目前我在必要时交换主机内存中的字节顺序,这非常慢,需要额外的步骤。

有没有一种快速方法可以将具有错误endianess的int / float / short缓冲区传递给opencl内核?

使用额外的内核运行只是为了修复endianess就行了;使用一些无头的自动修复 - 读/写操作将是完美的。

我知道变量属性((endian(host / device)))但是这对使用小端设备的小端平台上的大端FITS文件没有帮助。

我想到了像这样的解决方案(既未实施也未经过测试):

uint4 mask = (uint4) (3, 2, 1, 0);
uchar4 swappedEndianness = shuffle(originalEndianness, mask);
// to be applied on a float/int-buffer somehow

希望那里有更好的解决方案。

提前致谢, runtimeterror

2 个答案:

答案 0 :(得分:2)

不确定。因为你有一个uchar4 - 你可以简单地调用组件并将它们写回来。

output[tid] = input[tid].wzyx;
在SIMD架构上,swizzling的性能非常高,成本非常低,因此您应该能够将它与内核中的其他操作结合使用。

希望这有帮助!

答案 1 :(得分:1)

大多数处理器架构在使用指令完成适合其寄存器宽度的操作时表现最佳,例如32/64位宽度。当CPU / GPU执行这样的逐字节运算符时,对.wxyz使用下标uchar4,他们需要使用掩码从整数中检索每个字节,移位字节,然后使用整数add或或运算符到结果。对于字节顺序交换,处理器需要执行上面的整数和移位,添加/或4次,因为有4个字节。

最有效的方法如下

#define EndianSwap(n) (rotate(n & 0x00FF00FF, 24U)|(rotate(n, 8U) & 0x00FF00FF)

n可以是任何gentype,例如uint4变量。因为OpenCL不允许C ++类型重载,所以最好的选择是宏。