Cuda 核结构与并行结构的区别

Cuda 核结构与并行结构的区别,cuda,gpu,gpgpu,openacc,Cuda,Gpu,Gpgpu,Openacc,我研究了很多文章和OpenACC手册,但仍然不理解这两种结构的主要区别 OpenACC指令和GPU内核只是表示同一事物的两种方式——一段可以并行运行的代码 当对现有应用程序进行改造以利用GPU和/或希望让编译器处理与内存管理等问题相关的更多细节时,OpenACC可能是最佳选择。这可以加快编写应用程序的速度,并带来潜在的性能成本 当从头开始编写GPU应用程序和/或需要更细粒度的控制时,内核可能是最好的。这可能会延长应用程序的编写时间,但可能会提高性能 我认为新接触GPU的人可能会倾向于使用Open

我研究了很多文章和OpenACC手册,但仍然不理解这两种结构的主要区别

OpenACC指令和GPU内核只是表示同一事物的两种方式——一段可以并行运行的代码

当对现有应用程序进行改造以利用GPU和/或希望让编译器处理与内存管理等问题相关的更多细节时,OpenACC可能是最佳选择。这可以加快编写应用程序的速度,并带来潜在的性能成本

当从头开始编写GPU应用程序和/或需要更细粒度的控制时,内核可能是最好的。这可能会延长应用程序的编写时间,但可能会提高性能


我认为新接触GPU的人可能会倾向于使用OpenACC,因为它看起来更熟悉。但我认为实际上最好换一种方式,从编写内核开始,然后,有可能转向OpenACC以节省一些项目的时间。原因是OpenACC是一个应用程序。因此,尽管OpenACC可能会让GPU的细节看起来像是抽象出来的,但它们仍然存在。因此,在不了解后台情况的情况下使用OpenACC编写GPU代码可能会令人沮丧,在尝试编译时会出现奇怪的错误消息,并导致应用程序性能低下。

kernels
指令是更一般的情况,如果您编写过GPU,您可能会想到这一情况(例如CUDA)之前的内核。
内核
简单地指示编译器处理一段代码,并生成任意数量、任意“维度”的“内核”,将按顺序执行,以并行化/将特定的代码段卸载到加速器。
并行
构造允许更细粒度地控制编译器如何尝试在加速器上构建工作结构,例如通过指定并行化的特定维度。例如,工作人员和组的数量作为
parallel
指令的一部分,s通常是常量(因为通常只隐含一个底层“内核”),但可能不是
kernels
指令上的常量(因为它可能转换为多个底层“内核”)

关于这一具体问题的详细论述载于

引述文章摘要:
“OpenACC内核和并行结构都试图解决相同的问题,识别循环并行性并将其映射到机器并行性。内核结构更隐式,使编译器能够根据目标加速器的要求更自由地查找和映射并行性。并行结构更显式t、 并且需要程序员进行更多的分析,以确定何时是合法和适当的。”

并行构造

  • 定义应编译以在加速器设备上并行执行的程序区域

  • parallel loop指令是程序员的一种断言,即并行化受影响的循环既安全又可取。这取决于程序员是否正确识别代码中的并行性,并删除代码中可能不安全的任何并行化内容。如果程序员错误地断言该循环可能是无效的然后,生成的应用程序可能会产生不正确的结果

  • 并行结构允许更细粒度地控制编译器如何尝试在加速器上构建工作结构,因此它不会严重依赖编译器自动并行代码的能力

  • 当并行循环用于访问相同数据的两个后续循环时,编译器可能会也可能不会在主机和设备之间的两个循环之间来回复制数据

  • 更有经验的并行程序员可能已经在代码中识别了并行循环,他们可能会发现并行循环方法更可取

  • e、 g

    #pragma acc并行
    {
    #pragma-acc环
    
    对于(i=0;我的答案似乎是回答“使用或不使用OpenACC的原因是什么”的问题,而忽略了OP的问题,该问题与区分要求OpenACC编译器为某个区域生成GPU代码的两种稍有不同的方式有关。此外,引用链接文章在某种程度上,所有非琐碎的抽象都是漏洞百出的"因此,这是一个深度有限的批评。我建议最好假设这张海报知道如何编程GPU,并且事实上,对这两种语言结构之间的语法和功能差异感兴趣。我可能确实回答了错误的问题。我不知道OpenACC也有一个内核概念。我认为它是就像所有指令一样,比如OpenMP。@RogerDahl-
    kernels
    是一个由OpenACC标准定义的指令。它还包括
    parallels
    指令。在GCC中
    parallel
    实现得更好。据我所知,GCC中
    kernel
    不支持
    缩减。
    
    #pragma acc parallel
    {
        #pragma acc loop
        for (i=0; i<n; i++) 
             a[i] = 3.0f*(float)(i+1);
        #pragma acc loop
        for (i=0; i<n; i++) 
             b[i] = 2.0f*a[i];
    }
    
    #pragma acc kernels
    {
       for (i=0; i<n; i++)
           a[i] = 3.0f*(float)(i+1);
       for (i=0; i<n; i++)
            b[i] = 2.0f*a[i];
    }