OpenACC读书笔记(二)

简介: OpenACC中常用的一些导语与子语 : #pragma acc kernels 如同上一篇代码所显示,在代码前之间加上,编译器发现这一指令时会自动将接下来代码中可以改动的改成并行#include<stdio.h>#define N 256int main(){ int i,a[N],b[N],c[N]; for(i=0;i&lt

OpenACC中常用的一些导语与子语 :
#pragma acc kernels
如同上一篇代码所显示,在代码前之间加上,编译器发现这一指令时会自动将接下来代码中可以改动的改成并行

#include<stdio.h>
#define N 256
int main()
{
    int i,a[N],b[N],c[N];
    for(i=0;i<N;i++)
    {
        a[i]=0;
        b[i]=c[i]=i;
    }
    #pragma acc kernels
    for(i=0;i<N;i++)
    {
        a[i]=b[i]+c[i];
    }
    printf("a[N-1]=%d \n",a[N-1]);
    return 0;

}

一重循环嵌套启用一个或多个gangs和相应的vectors来实现多线程,
二重循环嵌套和三重循环嵌套时增加gangs和works来实现多线程;
如果想看经过编译后的代码,可以在编译的时候选用选项nollvm和keepgpu
pgcc -acc -Minfo -ta=tesla:nollvm,keepgpu test.c
可能得到中间代码文件 test.n001.gpu ,其中tesla为显卡的架构
#pragma acc loop
用loop相对于前面的kernel,可以更加准确地指导编译器的并行化工作
loop导语直接跟着循环语句
loop在使用时会自动检测数据的依赖性,当数据相互依赖时会将数据串行运行如下面例子:

#include<stdio.h>
#define N 1024
int main()
{
    int i,a[N],b[N],c[N];
    for(i=0;i<N;i++)
    {
        a[i]=0;
        b[i]=c[i]=i;
    }
    #pragma acc kernels
    {
        #pragma acc loop
        for(i=0;i<N;i++)
            a[i]=b[i]+c[i];
        #pragma acc loop
        for(i=0;i<N;i++)
            b[i]=b[i-1];
    }
    printf("b[2]=%d\n",b[2]);
    return 0;
}

显然第一个loop下面的循环中的数据不是相互依赖的可以转化为并行,
第二个loop下面的循环中数据是相互依赖的,所以只能以串行的方式进行
最后返回值为:

b[2]=0;

independent子语告诉编译器该循环的迭代步是相互独立的,强制允许生成并行代码

#include<stdio.h>
#define N 1024
int main()
{
    int i,a[N],b[N],c[N];
    for(i=0;i<N;i++)
    {
        a[i]=0;
        b[i]=c[i]=i;
    }
    #pragma acc kernels
    {
        #pragma acc loop
        for(i=0;i<N;i++)
            a[i]=b[i]+c[i];
        #pragma acc loop independent
        for(i=0;i<N;i++)
            b[i]=b[i-1];
    }
    printf("b[2]=%d\n",b[2]);
    return 0;

编译器将不检测循环内数据的依赖性而选择并行处理,最终结果为:

b[2]=1

用independent子语时编译器可能会误解原程序想表达的意思,所以要注意;
reduction子语:
reduction子语常用语一些计算的求和,乘积等,以求和为例:
s=ni=1ai=s1+s2=n1i=1ai+ni=n1+1ai
将数据分成两部分相加,最后再赋给s,相乘也一样
在c/c++中reduction子语试用于int,float,doubl,complex,char,wchar_t,适用于:+,*,max,min,&,|,%,&&,||
用法如下面例子:

#include<stdio.h>
#define N 101
int main()
{
    int a[N],i,ired;
    for(i=0;i<N;i++)
        a[i]=i;
    ired=0;
    #pragma acc parallel
    {
    #pragma acc loop reduction(+;ired)
    for(i=0;i<N;i++)
        ired+=a[i];
    }
    printf("ired=%d\n",ired);
    return 0;
}

在reduction(;)第一个参数为数学符号,第二个参数为最后赋予值的变量
这里写图片描述

目录
相关文章
|
5月前
|
存储 程序员 存储控制器
【读书笔记】汇编语言(第四版)第二章 寄存器
【读书笔记】汇编语言(第四版)第二章 寄存器
|
5月前
|
存储 编译器 芯片
【读书笔记】汇编语言(第四版)第一章 基础知识
【读书笔记】汇编语言(第四版)第一章 基础知识
第五章 汇编语言程序设计【微机原理】2
第五章 汇编语言程序设计【微机原理】2
257 0
第五章 汇编语言程序设计【微机原理】2
第五章 汇编语言程序设计【微机原理】1
第五章 汇编语言程序设计【微机原理】1
95 0
|
存储 程序员 编译器
读书笔记Pt.1——《深入理解计算机系统》
信息就是上下文+位🤔 什么意思?比如我们一个最简单的hello world 程序,生命周期是从一个.c文件(源文件)开始的,源文件实际上是0和1组成的位序列,8个位为一组。
读书笔记Pt.1——《深入理解计算机系统》
|
存储 Unix 芯片
读书笔记Pt.2——《深入理解计算机系统》
存储设备的层次结构🤔 实际上,每个计算机系统中的存现虎设备都被组织成了一个存储器层次结构,想象一下网一个又大又慢的设备之间插入一个又小又快的存储设备,就是这种层次结构现在已经成为了一个普遍的概念,如下:
读书笔记Pt.2——《深入理解计算机系统》