我正在使用OpenCL来优化Raspberry Pi GPU(视频核IV)中的某些代码。 我正在使用VC4CL实现,该实现的最大工作组大小为12。
但是,使用简单的内核(例如将两个数组相加),GPU的性能要比CPU的性能差很多。
例如,对于以下内核:
#define GLOBAL_SIZE 12
#define LOCAL_SIZE 1
#define WIDTH 12*12*12
#define NTIMES 1000
__attribute__ ((reqd_work_group_size(LOCAL_SIZE, LOCAL_SIZE, LOCAL_SIZE)))
__kernel void int_sum(global const uint* A, global const uint* B, global uint* C)
{
int g_id0 = get_global_id(0);
int g_id1 = get_global_id(1);
int g_id2 = get_global_id(2);
int index = g_id0 + g_id1 * GLOBAL_SIZE + g_id2 * GLOBAL_SIZE * GLOBAL_SIZE;
for(int k = 0; k < NTIMES; k++)
C[index + k * WIDTH] = A[index + k * WIDTH] + B[index + k * WIDTH];
}
将两个数组的1e6位置相加,CPU的性能要好得多... 我尝试将工作组更改为一维,并尝试使用其他组合,例如(6x6x6->全局大小,2x2x2->局部大小)。 有什么暗示我可能做错了吗?
谢谢。
答案 0 :(得分:1)
我对这个特定的GPU不熟悉,但是有一些事情在您的代码中可能会引起危险:
C[index + k * WIDTH] = A[index + k * WIDTH] + B[index + k * WIDTH];
发出3个整数乘法。我会将偏移量保留在变量中,并在每次迭代时将其添加到变量中,而无需乘法。C[i] = A[i] + B[i]
计算i = 0..1000*12*12*12
。如此精确地编写内核并在一维提交1728000个工作项怎么样?这样可以节省所有复杂的索引计算。 如果您可以从驱动程序中获得任何反馈,则GPU受其约束(ALU,内存负载,线程调度等),这将在选择寻找加速方法的位置方面大有帮助。
答案 1 :(得分:1)
除了其他人在评论中所说的以外,according to the RPi's OpenCL implementation author, GPU的“内存访问速度”(CPU-GPU内存副本?)比CPU慢得多。因此,像数组和之类的“算术轻”内核将受到内存带宽的限制,并且可能比CPU上慢得多。此外,理论上的GPU GFlops并不比GPU的高(24 vs 6)。
除非您有一些非常计算量很大的内核也可以完全向量化,否则您可能会发现使用GPU根本不值得。