Cuda gpu上的强伸缩性
我想研究一下我的并行GPU代码(用OpenACC编写)的强大伸缩性。至少据我所知,使用GPU进行强扩展的概念比使用CPU时更加模糊。建议修复问题大小并增加GPU的数量。但是,我相信GPU中有一些很强的缩放,例如流多处理器(英伟达开普勒架构)中的缩放。 OpenACC和CUDA的目的是显式地将硬件抽象给并行程序员,将其约束为具有组(线程块)、工作者(扭曲)和向量(SIMT线程组)的三级编程模型。据我所知,CUDA模型旨在提供其线程块的可伸缩性,线程块是独立的,并映射到SMX。因此,我认为有两种方法可以研究GPU的强伸缩性:Cuda gpu上的强伸缩性,cuda,parallel-processing,gpgpu,openacc,Cuda,Parallel Processing,Gpgpu,Openacc,我想研究一下我的并行GPU代码(用OpenACC编写)的强大伸缩性。至少据我所知,使用GPU进行强扩展的概念比使用CPU时更加模糊。建议修复问题大小并增加GPU的数量。但是,我相信GPU中有一些很强的缩放,例如流多处理器(英伟达开普勒架构)中的缩放。 OpenACC和CUDA的目的是显式地将硬件抽象给并行程序员,将其约束为具有组(线程块)、工作者(扭曲)和向量(SIMT线程组)的三级编程模型。据我所知,CUDA模型旨在提供其线程块的可伸缩性,线程块是独立的,并映射到SMX。因此,我认为有两种方法
我的问题是:我关于在GPU上进行强扩展的思路是否正确/相关?如果是这样的话,在OpenACC中有没有一种方法可以完成上面的第2步呢?对于占用一个完整的SMX,我建议使用共享内存作为占用的限制资源。编写一个占用所有32kB共享内存的内核,该块将占用整个SMX,因为SMX没有其他块的资源。然后,您可以将块从1扩展到13(对于K20c),调度器将(希望)将每个块调度到不同的SMX。然后,您可以先将每个块的therads扩展到192,以使每个CUDA核心繁忙,然后再进一步使warp调度程序满意。GPU通过延迟隐藏提供性能。所以你必须从1个块移动到N个块。您可以通过使用更少的共享内存来实现这一点。再次放大翘曲以覆盖延迟隐藏
我从未接触过OpenACC,如果你真的想完全控制你的实验代码,请使用CUDA而不是OpenACC。您无法看到OpenACC编译器内部以及它如何处理代码中使用的pragmas GPU具有强大的可伸缩性,但不一定按照您的思维方式,这就是为什么您只能找到关于对多个GPU进行强大可伸缩性的信息。使用多核CPU,您可以轻松地确定要在多少个CPU核上运行,这样您就可以修复工作并调整内核间的线程化程度。使用GPU,SMs之间的分配将自动处理,完全不受您的控制。这是设计上的,因为这意味着一个编写良好的GPU代码将具有很强的伸缩性,可以填充您扔给它的任何GPU(或GPU),而无需任何程序员或用户干预 您可以在少量OpenACC帮派/CUDA线程块上运行,并假设14个帮派将在14个不同的SMs上运行,但这有几个问题。首先,1组/螺纹块不会使单个开普勒SMX饱和。无论有多少线程,无论占用率如何,每个SM都需要更多的块才能充分利用硬件。第二,您不能真正保证硬件会选择这样安排块。最后,即使您在现有设备上找到每个SM的最佳块数或组数,它也无法扩展到其他设备。GPU的诀窍是尽可能多地公开并行性,以便可以从具有1 SM的设备扩展到具有100 SM的设备(如果有的话),或者扩展到多个设备 如果您想试验在固定工作量下改变OpenACC组的数量对性能的影响,您可以使用
num\u-gangs
子句(如果您使用parallel
区域)或gang
子句(如果您使用kernels
)。由于您试图强制循环的特定映射,因此最好使用并行
,因为这是更具规定性的指令。您希望执行的操作如下所示:
#pragma acc parallel loop gang vector num_gangs(vary this number) vector_length(fix this number)
for(i=0; i<N; i++)
do something
#pragma acc并行循环组向量数组(更改此数字)向量长度(修复此数字)
对于(i=0;i“您无法看到OpenACC编译器内部以及它对代码中使用的pragmas所做的操作。”使用PGI OpenACC编译器,您可以指定保留生成的中间文件。PGI OpenACC编译器将相关源代码转换为中间CUDA C/C++文件。如果保留这些文件,您可以准确地看到正在生成的CUDA内核。OpenACC是一个功能丰富的规范,可以让您控制GPU你可以在CUDA中达到的水平。回答很好,谢谢!你为什么不使用worker
和num_-workers
子句?如果最内层循环上有足够的向量并行性,那么在Nvidia GPU上通常不需要worker。我看到worker有用的时候是当最内层循环不包含太多的并行性,因此添加辅助并行性将乘以并行性以填充threadblock。