Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Cuda gpu上的强伸缩性_Cuda_Parallel Processing_Gpgpu_Openacc - Fatal编程技术网

Cuda 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编写)的强大伸缩性。至少据我所知,使用GPU进行强扩展的概念比使用CPU时更加模糊。建议修复问题大小并增加GPU的数量。但是,我相信GPU中有一些很强的缩放,例如流多处理器(英伟达开普勒架构)中的缩放。 OpenACC和CUDA的目的是显式地将硬件抽象给并行程序员,将其约束为具有组(线程块)、工作者(扭曲)和向量(SIMT线程组)的三级编程模型。据我所知,CUDA模型旨在提供其线程块的可伸缩性,线程块是独立的,并映射到SMX。因此,我认为有两种方法可以研究GPU的强伸缩性:

  • 修复问题大小,并将线程块大小和每个块的线程数设置为任意常量。缩放螺纹块的数量(网格大小)
  • 给定有关底层硬件的其他知识(例如CUDA计算能力、最大扭曲/多处理器、最大线程块/多处理器等),设置线程块大小和每个块的线程数,以便一个块占用整个SMX。因此,在线程块上的缩放相当于在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。