题
我刚刚开始学习 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 时,您期望显着加速的最简单的示例是什么?
解决方案
,如果你有足够大的矩阵组打算上执行线性代数运算,或者你基本上每个元素执行相同的操作,我会认为这是一个简单的例子。矩阵乘法,加法,FFT的,卷积,等你会看到一个有点加速的没有做大量的工作。现在,如果你想看到的100倍的速度提升,那么你需要深入到内存管理,并知道这是怎么回事幕后公平一点。
入门,我建议用pycuda开始,因为它是非常简单上手,因为它提供了一个抽象非常高的水平,将让你非常迅速蹿英寸检查出使用CUDA从伊利诺伊 HTTP的大学并行计算这个过程://courses.ece。 illinois.edu/ece498/al/ 当您准备在进一步深入。
其他提示
取决于琐碎的定义。在我看来,这将是矩阵矩阵产品,因为它有O(3)/O(2)
计算内存比例。
表现出相似比的算法,有可能从正在GPU竞争受益。
虽然你的内核显然是很琐碎也可以是一个有用的例子,它是完全绑定的内存,因为每个元素有两个读和一个写,只有一个算术运算。有一些指令来计算地址等,但与访问存储器的成本相比,这一切相当于几乎没有什么。
假设数据已经在GPU上,可以从GPU的非常高的带宽中受益的内存,即使这个简单的内核。
当然,GPU的依赖,你有足够的线程来隐藏内存延迟,所以当地的工作组大小应该是相当大的(比如256或512)和全局工作组大小应该是非常大(例如几十万)这是有效的,但是这是一种点的!
我知道这个问题很老了但是......我发现 Mandelbrot 集的计算对于 GPU 来说是相当最优的。您有一个复杂的输入向量 (float2) 和一个标量输出 (int),并且每个输入向量平均有数百次操作。
它可以用作一个很好的示例应用程序,因为它......
- 有一个二维输入数据集(计算图像)
- 您可以解释波前以及为什么二维处理在某些情况下是有益的
- 演示矢量数据类型
- 生成一张可由人眼快速验证的图片(调试)
- 可以通过以下方式轻松扩展:颜色映射(__constant),float4 处理而不是 float2(优化),生成 int4 (R,G,B,A) 输出向量(优化)。减少步长 (RGBA) => (RGB)
- 所需的数学知识是可以接受的(简单的公式)
问候,Stefan
矩阵乘法我要说后图像卷积(如模糊,去噪等)。 请查看 AMD的教程。
什么是“最微不足道”是一个见仁见智的问题,但我想说,使用 GPU 计算 Mandelbrot 集的图像是一个非常简单的应用程序。每个点都完全独立于其他点,因此您可以为每个点启动一个线程并获得巨大的加速。迭代的公式本身是一个简单的二次函数。我在教程中使用它作为示例,该教程可以在我的博客上找到 这里, ,只需计算数字,甚至无需制作图像,使其变得更加简单。几乎任何令人尴尬的并行(参见维基百科条目)问题都是一个好的开始。