GPU中的并行性&CUDA/OpenCL

GPU中的并行性&CUDA/OpenCL,cuda,opencl,Cuda,Opencl,我有一个关于CUDA或GPU上OpenCL代码并行性的一般问题。我使用NVIDIA GTX 470 我在Cuda编程指南中简要阅读了一下,但没有找到相关的答案,因此在这里提问 我有一个调用CUDA内核的顶级函数(对于同一个内核,我有它的OpenCL版本)。对于3个不同的数据集(图像数据R、G、B),这个顶级函数本身在我的主函数的“for循环”中被调用了3次 而实际的codelet也对图像/帧中的所有像素进行处理,因此它有2个“for循环” 我想知道的是,这里利用了什么样的并行性——任务级并行还是

我有一个关于CUDA或GPU上OpenCL代码并行性的一般问题。我使用NVIDIA GTX 470

我在Cuda编程指南中简要阅读了一下,但没有找到相关的答案,因此在这里提问

我有一个调用CUDA内核的顶级函数(对于同一个内核,我有它的OpenCL版本)。对于3个不同的数据集(图像数据R、G、B),这个顶级函数本身在我的主函数的“for循环”中被调用了3次 而实际的codelet也对图像/帧中的所有像素进行处理,因此它有2个“for循环”

我想知道的是,这里利用了什么样的并行性——任务级并行还是数据并行

所以我想了解的是,这个CUDA和C代码是否在codelet和顶级代码中为不同的功能创建了多个线程,并在 并行和利用任务并行。如果是,是谁创建的,因为代码中没有明确包含或链接的线程库

它为独立的不同“for循环”迭代创建线程/任务,从而实现数据并行性。 如果它实现了这种并行性,它是否仅仅通过注意到不同的for循环迭代没有依赖性,因此可以并行调度来利用这种并行性

因为我没有看到任何特殊的编译器构造/内部函数(与openMP中的循环并行),它会告诉编译器/调度器并行地为循环/函数调度这些构造/内部函数


任何阅读材料都会有所帮助。

GPU上的并行性是SIMT(单指令多线程)。对于CUDA内核,可以指定一个块网格,其中每个块有N个线程。CUDA库完成所有操作,CUDA编译器(nvcc)生成GPU代码,由GPU执行。CUDA库告诉GPU驱动程序以及GPU上的线程调度程序应该执行内核的线程数((块数)x(线程数))。在您的示例中,顶级函数(或宿主函数)只执行异步的内核调用,并立即返回。不需要线程库,因为nvcc创建对驱动程序的调用

内核调用示例如下所示:

helloworld<<<BLOCKS, THREADS>>>(/* maybe some parameters */);
helloworld(/*可能是一些参数*/);
OpenCL遵循相同的范例,但是您可以在运行时编译您的内核(如果它们没有预编译的话)。指定要执行内核的线程数,其余由lib执行

学习CUDA(OpenCL)的最好方法是查看()和中的示例

我想知道的是,这里利用了什么样的并行性——任务级并行还是数据并行

主要是数据并行,但也涉及一些任务并行

在图像处理示例中,内核可能会对单个输出像素进行处理。您可以指示OpenCL或CUDA运行与输出图像中像素数量相同的线程。然后它会安排这些线程在目标GPU/CPU上运行

数据高度并行。内核是为完成单个工作项而编写的,您可以调度数百万个工作项


任务并行性的出现是因为您的主机程序仍在CPU上运行,而GPU正在运行所有这些线程,因此它可以继续进行其他工作。通常这是为下一组内核线程准备数据,但这可能是一个完全独立的任务。

如果启动多个内核,它们将不会自动并行化(即没有GPU任务并行性)。但是,内核调用在主机端是异步的,因此在内核执行时,主机代码将继续并行运行

要获得任务并行性,您必须手工完成——在Cuda中,这个概念称为streams,在OpenCL命令队列中。如果不显式创建多个流/队列并将每个内核调度到自己的队列,它们将按顺序执行(OpenCL有一个允许队列无序运行的功能,但我不知道是否有任何实现支持它),如果每个数据集足够大,可以利用所有GPU内核,那么并行运行内核可能不会带来太多好处

如果内核中有实际的for循环,它们本身就不会被并行化,并行性来自于指定网格大小,这将导致内核为该网格中的每个元素被并行调用(因此,如果内核中有for循环,则每个线程将完全执行它们)。换句话说,您应该在调用内核时指定网格大小,并且在内核内部使用threadIdx/blockIdx(Cuda)或getGlobalId()(OpenCL)来标识要在该特定线程中处理的数据项

学习OpenCL的一本有用的书是,但也值得一看