我构建了一个用于两个矩阵的元素乘法的内核,但至少在我的配置中,我的OpenCL内核只有在每个矩阵大于2GB时才会更快。所以我想知道,如果是因为我的天真内核(见下文),或者因为元素操作的本质,这意味着元素操作不会因使用GPU而获得。
感谢您的投入!
内核:
KERNEL_CODE = """
// elementwise multiplication: C = A .* B.
__kernel void matrixMul(
__global float* C,
__global float* A,
__global float* B,
int width, int height)
{
// ID
int x = get_global_id(0);
int y = get_global_id(1);
// Multiplying
C[y * height + x ] = A[y * height + x] * B[y * height + x];
}
"""
P.S。我看到一些专家认为,CUDA与OpenCL的不同之处在于同一个问题都可以回答,并且可以自由地从标题和标签中删除它。
答案 0 :(得分:9)
那种操作有N个FLOP,但有3N内存事务,所以它将完全受内存带宽限制。没有数据重用的余地,因此加速参考CPU版本的上限是GPU与CPU带宽的比率。这个数字很少超过10倍,并且可以通过将数据移入和移出GPU内存的成本迅速侵蚀。一般来说,这种操作最好与其他O(N)操作“融合”以提高性能。您通常不会在单个内核中计算Hadamard产品,而是在一个内核中作为一系列O(N)操作的一部分进行计算。所以,不,这不是加速的好选择,即使内核是最佳的。
你的内核肯定不是。你为每个FLOP做3个IOP,这是一个巨大的惩罚。你肯定可以做些改进的事情,但是什么事情将完全取决于它将在哪种硬件上运行。
答案 1 :(得分:2)
说到元素操作:这取决于设备。例如,NVidia GPU使用标量处理器(带标量指令),不需要矢量化。相反,ATI具有5d(或4d)VLIW处理器,因此对矢量化至关重要。但是,它有时可以由编译器执行,而不是直接在代码中使用矢量数据类型,但在优化ATI的GPU时首先要做的事情。
尽管如此,正如talonmies指出的那样,上面的算法几乎不受内存带宽限制,你只能为它使用GPU来等待很多加速。
答案 2 :(得分:0)
您发布的内核应至少与CPU一样快。但是你根本没有使用合并的内存访问!
这会扼杀你的表现。
然而,正如@talonmies所说。这不是GPU的好例子。你在记忆副本中浪费了所有的时间。