我有以下OpenCL内核,它将值从一个缓冲区复制到另一个缓冲区,可以选择将其取反('invert'arg可以为1或-1):-
__kernel void extraction(__global const short* src_buff, __global short* 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;
}
源缓冲区包含一个或多个“记录”,每个记录包含 N (record_len
)个短值。缓冲区中的所有记录的长度相等,并且record_len始终是32的倍数。
全局大小为2D(缓冲区中的记录数,记录长度),我选择它是因为它似乎最充分地利用了GPU并行处理,每个线程仅负责在一个记录中复制一个值。在缓冲区中。
(顺便说一句,本地工作大小设置为NULL,允许OpenCL自行确定值)。
在最近阅读了向量之后,我想知道是否可以使用它们来改善性能?我了解向量的概念,但是我不确定如何在实践中使用它们,部分原因是缺少好的示例。
我确信内核的性能已经相当合理了,所以这主要是出于好奇,看看使用向量(或其他更合适的方法)会产生什么不同。
冒个天真的风险,我可以简单地将两个缓冲区arg类型更改为short16
,并将2-D全局大小中的第二个值从“记录长度”更改为“记录长度” / 16英寸?这会导致每个内核线程在缓冲区之间复制一个16个short值的块吗?
答案 0 :(得分:2)
您的幼稚假设基本上是正确的,尽管您可能希望向编译器添加一个提示,指出该内核已针对向量类型(Section 6.7.2 of spec)进行了优化,但在您的情况下,您应该添加
属性(((vec_type_hint(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,并且record_len也应除以16。此外,如果要指定局部大小而不是将其设置为NULL,则还需要除以到16点。
不过,还有一些其他事情要考虑。
您可能会认为选择最大的向量大小应该可以提供最佳性能,尤其是对于这样一个简单的内核。但是以我的经验,这很少是最佳尺寸。您可以尝试向clGetDeviceInfo询问CL_DEVICE_PREFERRED_VECTOR_WIDTH_SHORT,但是对我来说,这很少是准确的(而且,它可能会给您1,这意味着编译器将尝试自动矢量化或该设备没有矢量硬件)。最好尝试使用不同的向量大小,然后查看最快的向量。
如果您的设备支持自动矢量化,并且您想尝试一下,则可能会帮助删除record_len参数并将其替换为get_global_size(1),以便编译器/驱动程序可以将record_len除以除以它选择的向量大小。我仍然建议这样做,假设record_len等于您为该尺寸指定的全局尺寸。
此外,您为本地大小参数提供了NULL,以便实现自动选择大小。可以保证选择合适的尺寸,但不一定会选择最佳尺寸。
最后,对于常规的OpenCL优化,您可能想看看NVidia硬件的NVIDIA OpenCL Best Practices Guide或AMD GPU硬件的AMD APP SDK OpenCL User Guide。 NVidia的版本是从2009年开始的,我不确定此后它们的硬件已发生了多少变化。请注意,尽管它实际上说:
CUDA体系结构是标量体系结构。因此,没有性能 从使用向量类型和指令中受益。这些仅用于 方便。
较早的AMD硬件(GCN之前的版本)受益于使用矢量类型,但是AMD建议不要在GCN设备上使用它们(请参见mogu's comment)。另外,如果您要定位CPU,请it will use AVX hardware if available。