GPU 中的并行性 - CUDA / OpenCL
Posted
技术标签:
【中文标题】GPU 中的并行性 - CUDA / OpenCL【英文标题】:Parallelism in GPU - CUDA / OpenCL 【发布时间】:2012-01-26 01:41:50 【问题描述】:我对 CUDA 中的并行性或 GPU 上的 OpenCL 代码有一般性问题。我使用 NVIDIA GTX 470。
我简要阅读了 Cuda 编程指南,但没有找到相关答案,因此在这里提问。
我有一个调用 CUDA 内核的***函数(对于同一个内核,我有一个 OpenCL 版本)。这个***函数本身在我的主函数的“for循环”中被调用了3次,用于3个不同的数据集(图像数据R、G、B) 并且实际的小码还对图像/帧中的所有像素进行了处理,因此它有 2 个“for 循环”。
我想知道这里利用了什么样的并行性——任务级并行性还是数据并行性?
所以我想了解的是,这个 CUDA 和 C 代码是否为 codelet 和***代码中的不同功能/功能创建多个线程并在 并行并利用任务并行性。如果是,谁创建它,因为代码中没有明确包含或链接的线程库。
或
它为不同的“for循环”迭代创建线程/任务,这些迭代是独立的,从而实现数据并行。 如果它执行这种并行性,它是否只是通过注意到不同的 for 循环迭代没有依赖关系并因此可以并行调度来利用这一点?
因为我没有看到任何特殊的编译器构造/内在函数(openMP 中的并行 for 循环)告诉编译器/调度程序并行调度此类 for 循环/函数?
任何阅读材料都会有所帮助。
【问题讨论】:
【参考方案1】:GPU 上的并行性是 SIMT(单指令多线程)。对于 CUDA 内核,您指定一个块网格,其中每个块都有 N 个线程。 CUDA 库可以解决所有问题,CUDA 编译器 (nvcc) 生成由 GPU 执行的 GPU 代码。 CUDA 库告诉 GPU 驱动程序以及 GPU 上的线程调度程序应该有多少线程执行内核((块数)x(线程数))。在您的示例中,***函数(或主机函数)仅执行异步并立即返回的内核调用。不需要线程库,因为 nvcc 会创建对驱动程序的调用。
一个示例内核调用如下所示:
helloworld<<<BLOCKS, THREADS>>>(/* maybe some parameters */);
OpenCL 遵循相同的范例,但您在运行时编译您的内核(如果它们没有预编译)。指定执行内核的线程数,其余的由 lib 完成。
学习 CUDA (OpenCL) 的最佳方法是查看 CUDA Programming Guide (OpenCL Programming Guide) 并查看 GPU Computing SDK 中的示例。
【讨论】:
【参考方案2】:我想知道这里利用了什么样的并行性——任务级并行性还是数据并行性?
主要是数据并行,但也涉及一些任务并行。
在您的图像处理示例中,内核可能会对单个输出像素进行处理。您将指示 OpenCL 或 CUDA 运行与输出图像中的像素一样多的线程。然后它会安排这些线程在您的目标 GPU/CPU 上运行。
高度数据并行。编写内核是为了完成单个工作项,而您安排了数百万个工作项。
任务并行性的出现是因为您的主机程序仍在 CPU 上运行,而 GPU 正在运行所有这些线程,因此它可以继续处理其他工作。这通常是为下一组内核线程准备数据,但它可能是一个完全独立的任务。
【讨论】:
【参考方案3】:如果您启动多个内核,它们将不会自动并行化(即没有 GPU 任务并行性)。但是,内核调用在主机端是异步的,因此主机代码将在内核执行时继续并行运行。
要获得任务并行性,您必须手动完成 - 在 Cuda 中,这个概念称为流,在 OpenCL 命令队列中。在没有显式创建多个流/队列并将每个内核调度到自己的队列的情况下,它们将按顺序执行(有一个 OpenCL 功能允许队列乱序运行,但我不知道是否有任何实现支持它。 ) 但是,如果每个数据集都足够大以利用所有 GPU 内核,那么并行运行内核可能不会带来太多好处。
如果您的内核中有实际的 for 循环,它们本身不会被并行化,并行性来自指定网格大小,这将导致该网格中的每个元素并行调用内核(因此,如果您在内核中有 for 循环,它们将由每个线程完整执行)。换句话说,您应该在调用内核时指定网格大小,并在内核内部使用 threadIdx/blockIdx (Cuda) 或 getGlobalId() (OpenCL) 来识别在该特定线程中要处理的数据项。
一本对学习 OpenCL 很有帮助的书是OpenCL Programming Guide,但OpenCL spec 也值得一看。
【讨论】:
以上是关于GPU 中的并行性 - CUDA / OpenCL的主要内容,如果未能解决你的问题,请参考以下文章