我在一个到处使用image2d_t
对象的图像处理代码库上工作。它们的形状(宽度和高度)都有正式声明,这样程序员就可以使用内置的边界检查等等。
为了加速可分离的二维卷积,我想暂时转置图像,所以两个一维卷积沿着线访问内存。但由于所有image2d_t
缓冲区具有相同的形状,我需要重塑其中的2个,而不是重新分配它们(如果我需要realloc +转置,那么加速加起来几乎没有)。
是否有办法在image2d_t
对象中切换宽度和高度属性?
转换image2d_t
对象是没有意义的。
image2d_t
对象表示纹理记忆。纹理存储器是一种特殊类型的存储器,它是硬件优化的情况下,经纱/波前线程访问元素在附近的2D位置(x和y)。
我所说的"附近的2D位置"是指不一定在同一水平线(x)上,也不一定在离散的像素位置上。
GPU硬件对"纹理采样"有特殊的支持——允许你在非离散的位置"采样"纹理,并获得插值的像素值。
纹理内存实现的确切方式取决于供应商,但一般的想法是让2D区域瓷砖驻留在内存的同一物理行中。
使用纹理记忆有意义的例子:
-
计算机图形学中的纹理映射。对象中的相邻像素从输入图像中的相邻2D位置采样其颜色。
-
图像处理中的图像变换——缩放、旋转、扭曲和不扭曲图像。在任意计算位置对输入图像进行"采样"并将样本写入目标缓冲区/图像的情况。
对于大多数图像处理应用,纹理记忆没有意义。
许多图像处理算法以已知的模式访问内存,使用线性内存(opencl缓冲区)可以更好地优化内存,并且开销更小。
关于你的具体问题:
是否有一种方法来切换image2d_t的宽度和高度属性对象?
。Image2d_t对象是"不可变的"。然而,如果你用适当的标志分配它们并将它们作为__write_only
传递给内核,它们的内容可以改变。
我建议您切换到使用缓冲区对象。转换它们是可以有效地做到的,网上有一些很好的例子。