使用向量类型提高OpenCL内核性能

使用向量类型提高OpenCL内核性能,opencl,gpu,Opencl,Gpu,我有以下OpenCL内核,它将值从一个缓冲区复制到另一个缓冲区,可以选择反转值(“反转”参数可以是1或-1):- 源缓冲区包含一个或多个“记录”,每个“记录”包含N个(record\u len)短值。缓冲区中的所有记录长度相等,记录长度始终是32的倍数 全局大小是2D(缓冲区中的记录数,记录长度),我选择它是因为它似乎充分利用了GPU并行处理,每个线程只负责在缓冲区中的一条记录中复制一个值 (顺便说一下,本地工作大小设置为NULL,允许OpenCL自行确定值) 在最近阅读了有关向量的内容后,我想

我有以下OpenCL内核,它将值从一个缓冲区复制到另一个缓冲区,可以选择反转值(“反转”参数可以是1或-1):-

源缓冲区包含一个或多个“记录”,每个“记录”包含N个(
record\u len
)短值。缓冲区中的所有记录长度相等,记录长度始终是32的倍数

全局大小是2D(缓冲区中的记录数,记录长度),我选择它是因为它似乎充分利用了GPU并行处理,每个线程只负责在缓冲区中的一条记录中复制一个值

(顺便说一下,本地工作大小设置为NULL,允许OpenCL自行确定值)

在最近阅读了有关向量的内容后,我想知道是否可以使用这些来提高性能?我理解向量的概念,但我不知道如何在实践中使用它们,部分原因是缺乏好的例子

我确信内核的性能已经相当合理了,所以这主要是出于好奇,看看使用向量(或其他更合适的方法)会有什么不同


冒着有点幼稚的风险,我是否可以简单地将两个缓冲区arg类型更改为
short16
,并将二维全局大小中的第二个值从“记录长度”更改为“记录长度/16”?这会导致每个内核线程在缓冲区之间复制一个包含16个短值的块吗?

您天真的假设基本上是正确的,尽管您可能希望向编译器添加一个提示,说明此内核针对向量类型()进行了优化,在您的情况下,您可以添加

属性((向量类型提示(short16)))

在内核函数之上。所以在你的例子中,你会

__attribute__((vec_type_hint(short16)))
__kernel void extraction(__global const short16* src_buff, __global short16* dest_buff, const int record_len, const int invert)
    {                                                                                                           
        int i = get_global_id(0); // Index of record in buffer                                              
        int j = get_global_id(1); // Index of value in record                                                       

        dest_buff[(i* record_len) + j] = src_buff[(i * record_len) + j] * invert;
    }
您的第二个全局维度应该除以16,您的记录长度也应该除以16,这是正确的。此外,如果要指定本地大小而不是将其设为NULL,则还需要将其除以16

有一些其他的事情要考虑。 您可能认为选择最大的向量大小应该可以提供最好的性能,特别是对于这样一个简单的内核。但根据我的经验,这很少是最理想的尺寸。您可以尝试要求CL_DEVICE_PREFERRED_VECTOR_WIDTH_SHORT,但对我来说,这很少是准确的(同时,它可能会给您1,这意味着编译器将尝试自动向量化,或者设备没有向量硬件)。最好尝试不同的向量大小,看看哪一个最快

如果您的设备支持自动矢量化,并且您想试一试,那么它可能有助于删除您的record_len参数并将其替换为,这样编译器/驱动程序就可以将record_len除以它选择的任何向量大小。无论如何,我建议这样做,假设record_len等于您给定的维度的全局大小

此外,还为localsize参数指定了NULL,以便实现自动选择大小。它保证选择一个合适的尺寸,但不一定会选择最合适的尺寸

最后,对于一般的OpenCL优化,您可能希望查看针对NVidia硬件的,或针对AMD GPU硬件的。英伟达一个是2009,我不知道他们的硬件有多少变化。请注意,它实际上说:

CUDA体系结构是一种标量体系结构。因此,没有性能 使用向量类型和指令的好处。这些应仅用于 方便


较旧的AMD硬件(前GCN)受益于使用矢量类型,但AMD建议不要在GCN设备上使用矢量类型(请参阅)。另外,如果你的目标是CPU,.

“不过AMD硬件确实使用矢量硬件。”@mogu我想我的新款HD-6970不如以前那么现代了。谢谢你的更正。我很高兴是这样,因为没有有效的方法从每个向量通道都有不同地址的本地内存执行加载,这一直困扰着我。
__attribute__((vec_type_hint(short16)))
__kernel void extraction(__global const short16* src_buff, __global short16* dest_buff, const int record_len, const int invert)
    {                                                                                                           
        int i = get_global_id(0); // Index of record in buffer                                              
        int j = get_global_id(1); // Index of value in record                                                       

        dest_buff[(i* record_len) + j] = src_buff[(i * record_len) + j] * invert;
    }