我刚刚开始学习 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 集的图像是一个非常简单的应用程序。每个点都完全独立于其他点,因此您可以为每个点启动一个线程并获得巨大的加速。迭代的公式本身是一个简单的二次函数。我在教程中使用它作为示例,该教程可以在我的博客上找到 这里, ,只需计算数字,甚至无需制作图像,使其变得更加简单。几乎任何令人尴尬的并行(参见维基百科条目)问题都是一个好的开始。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top