让我们举个例子:
我想要同时制作向量点积(这不是我的情况,这只是一个例子)所以我有 2 个大输入向量和一个大小相同的大输出向量。可用的工作项小于这些向量的大小。如果工作项小于向量的大小,我如何在 opencl 中制作这个点积?这可能吗?或者我只是想弄点花招?
就像是:
for(i = 0; i < n; i++){
output[i] = input1[i]*input2[i];
}
n > 可用的工作项
让我们举个例子:
我想要同时制作向量点积(这不是我的情况,这只是一个例子)所以我有 2 个大输入向量和一个大小相同的大输出向量。可用的工作项小于这些向量的大小。如果工作项小于向量的大小,我如何在 opencl 中制作这个点积?这可能吗?或者我只是想弄点花招?
就像是:
for(i = 0; i < n; i++){
output[i] = input1[i]*input2[i];
}
n > 可用的工作项
如果通过“可用工作项”表示您正在运行由 给出的最大值CL_DEVICE_MAX_WORK_ITEM_SIZES
,则您始终可以将内核多次入队以获取数组的不同范围。
根据您的实际工作量,让每个工作项执行更多工作可能更明智。在最简单的情况下,您可以使用 SIMD 类型,如float4
、float8
、float16
等,并一次性对大块进行操作。与往常一样,尝试不同的方法并衡量每种方法的性能是无可替代的。
分而治之的数据。如果您将工作组大小保持为全局工作大小的整数除数,那么您可以在每次内核启动时同时启动 N 个工作组,或者其中 k 个。所以你应该只启动 N/k 个内核,每个内核都有 k*workgroup_size 工作项和内核内缓冲区的正确寻址。
当您有部分点积的每个工作组的部分总和(具有多个组内减少步骤)时,您可以简单地在 CPU 或数据将要传输的任何设备上对它们求和。