我刚刚开始学习OpenCL。我试图了解将函数/算法移动到GPU时所期望的性能提升。
大多数教程中给出的最基本的内核是一个内核,它接受两个数字数组并将相应索引处的值相加并将它们添加到第三个数组中,如下所示:
__kernel void
add(__global float *a,
__global float *b,
__global float *answer)
{
int gid = get_global_id(0);
answer[gid] = a[gid] + b[gid];
}
__kernel void
sub(__global float* n,
__global float* answer)
{
int gid = get_global_id(0);
answer[gid] = n[gid] - 2;
}
__kernel void
ranksort(__global const float *a,
__global float *answer)
{
int gid = get_global_id(0);
int gSize = get_global_size(0);
int x = 0;
for(int i = 0; i < gSize; i++){
if(a[gid] > a[i]) x++;
}
answer[x] = a[gid];
}
我假设你永远无法证明在GPU上计算这一点,内存传输会减轻在CPU上计算这个数量的时间(我可能会对此错误,因此这个问题)。
我想知道的是,当使用OpenCL内核而不是CPU时,您期望显着加速的最简单的例子是什么?
答案 0 :(得分:6)
如果您有足够大的矩阵集,您打算执行线性代数运算,或者您基本上对每个元素执行相同的操作,我会认为这是一个简单的例子。矩阵乘法,加法,fft,卷积等等。如果没有做太多工作,你会看到一点加速。现在如果你想看到100倍的加速比,那么你需要深入研究内存管理,并了解幕后发生的事情。
开始使用,我建议从pycuda开始,因为它非常简单,因为它提供了非常高的抽象级别,并且可以让你快速进入。当你准备好进一步潜水时,请查看伊利诺伊大学http://courses.ece.illinois.edu/ece498/al/使用cuda的并行计算课程。
答案 1 :(得分:3)
取决于琐碎的定义。在我看来,它将是矩阵矩阵产品,因为它具有O(3)/O(2)
计算内存比率。
具有相似比率的算法可能会受益于在GPU上的竞争。
答案 2 :(得分:2)
虽然你的内核显然非常简单,但它可以是一个有用的例子,它完全受内存限制,因为对于每个元素,你有两次读取和一次写入,并且只有一次算术运算。有一些指令来计算地址等,但与访问内存的成本相比,所有这些都几乎没有任何内容。
假设数据已经在GPU上,即使对于这个简单的内核,你也可以从GPU的内存带宽中受益。
当然,GPU依赖于您有足够的线程来隐藏内存延迟,因此您的本地工作组大小应该相当大(例如256或512)并且您的全局工作组大小应该非常大(例如数十万) )为了这个有效,但这就是重点!
答案 3 :(得分:1)
我知道问题很老但是......我发现Mandelbrot集的计算对于GPU来说是非常理想的。你有一个复杂的输入向量(float2)和一个标量输出(int),你平均每个输入向量将有几百个操作。
它可以用作一个很好的示例应用程序,因为它......
此致 斯蒂芬
答案 4 :(得分:0)
矩阵乘法后我会说图像卷积(如模糊,去噪等)。 查看AMD's tutorial。
答案 5 :(得分:0)
什么是“最微不足道的”是一个意见问题,但我想说计算Mandelbrot集的图像是使用GPU的非常简单的应用程序。每个点完全独立于每个点,因此您可以为每个点启动一个线程并获得极大的加速。迭代的公式本身是一个简单的二次函数。我在一个可以在我的博客here上找到的教程中使用它作为一个例子,只计算数字甚至没有制作图像使其更简单。几乎任何令人尴尬的平行(参见维基百科条目)问题都是一个好的开始。