▶ 使用 kernels 导语并行化 for 循环

● 同一段代码,使用 kernels,parallel 和 parallel + loop 进行对比

 #include <stdio.h>
#include <time.h>
#include <openacc.h> const int row = ; int main()
{
int i, j, k, a[row], b[row], c[row];
clock_t time;
for (i = ; i < row; i++)
a[i] = b[i] = i; #ifdef _OPENACC
time = clock();
#pragma acc kernels     // 使用 kernels 或 parallel 或 parallel + loop
// #pragma acc parallel
// #pragma acc loop
for (i = ; i < row; i++)
c[i] = a[i] + b[i];
time = clock() - time;
printf("\nTime with acc:%d ms\n", time);
#else
time = clock();
for (i = ; i < row; i++)
c[i] = a[i] + b[i];
time = clock() - time;
printf("\nTime without acc:%d ms\n", time);
#endif
getchar();
return ;
}

● 输出结果

D:\Code\OpenACC\OpenACCProject\OpenACCProject>pgcc -acc -Minfo main.c -o main_acc_kernels.exe       // kernels
main:
, Generating implicit copyin(b[:row])
Generating implicit copyout(c[:row])
Generating implicit copyin(a[:row])
, Loop is parallelizable
Accelerator kernel generated
Generating Tesla code
, #pragma acc loop gang, vector(128) /* blockIdx.x threadIdx.x */ D:\Code\OpenACC\OpenACCProject\OpenACCProject>pgcc -acc -Minfo main.c -o main_acc_parallel.exe // parallel
main:
, Accelerator kernel generated
Generating Tesla code
, #pragma acc loop vector(128) /* threadIdx.x */
, Generating implicit copyout(c[:row])
Generating implicit copyin(b[:row],a[:row])
, Loop is parallelizable D:\Code\OpenACC\OpenACCProject\OpenACCProject>pgcc -acc -Minfo main.c -o main_acc_parallel_loop.exe // parallel + loop
main:
, Accelerator kernel generated
Generating Tesla code
, #pragma acc loop gang, vector(128) /* blockIdx.x threadIdx.x */
, Generating implicit copyout(c[:row])
Generating implicit copyin(b[:row],a[:row]) D:\Code\OpenACC\OpenACCProject\OpenACCProject>main_acc_kernels.exe
launch CUDA kernel file=C:/Program Files (x86)/Windows Kits//Include/10.0.16299.0/ucrt\time.h function=main
line= device= threadid= num_gangs= num_workers= vector_length= grid= block= // 多个 gang,自动配置,线程网格全都是一维的 Time with acc: ms D:\Code\OpenACC\OpenACCProject\OpenACCProject>main_acc_parallel.exe
launch CUDA kernel file=C:/Program Files (x86)/Windows Kits//Include/10.0.16299.0/ucrt\time.h function=main
line= device= threadid= num_gangs= num_workers= vector_length= grid= block= // 一个 gang,gang冗余模式 Time with acc: ms D:\Code\OpenACC\OpenACCProject\OpenACCProject>main_acc_parallel_loop.exe
launch CUDA kernel file=C:/Program Files (x86)/Windows Kits//Include/10.0.16299.0/ucrt\time.h function=main
line= device= threadid= num_gangs= num_workers= vector_length= grid= block= // 多个 gang,gang分裂模式 Time with acc: ms

● 二重循环,考虑是否在内层循环中使用 loop 导语

 #include <stdio.h>
#include <time.h>
#include <openacc.h> const int row = , col = ; int main()
{
int i, j, k, a[row][col], b[row][col], c[row][col];
clock_t time;
for (i = ; i < row; i++)
{
for (j = ; j < col; j++)
a[i][j] = b[i][j] = i + j;
} #ifdef _OPENACC
time = clock();
#pragma acc parallel
#pragma acc loop
for (i = ; i < row; i++)
{
// #pragma acc loop
for (j = ; j < col; j++)
c[i][j] = a[i][j] + b[i][j];
}
time = clock() - time;
printf("\nTime with acc:%d ms\n", time);
#else
time = clock();
for (i = ; i < row; i++)
{
for (j = ; j < col; j++)
c[i][j] = a[i][j] + b[i][j];
}
time = clock() - time;
printf("\nTime without acc:%d ms\n", time);
#endif
getchar();
return ;
}

● 输出结果

D:\Code\OpenACC\OpenACCProject\OpenACCProject>pgcc -acc -Minfo main.c -o main_acc_loop1.exe // 仅使用外层 loop
main:
, Accelerator kernel generated
Generating Tesla code
, #pragma acc loop gang /* blockIdx.x */
, #pragma acc loop vector(128) /* threadIdx.x */
, Generating implicit copyin(a[:row][:col])
Generating implicit copyout(c[:row][:col])
Generating implicit copyin(b[:row][:col])
, Loop is parallelizable D:\Code\OpenACC\OpenACCProject\OpenACCProject>pgcc -acc -Minfo main.c -o main_acc_loop2.exe // 内外都使用 loop,优化结果完全相同
main:
, Accelerator kernel generated
Generating Tesla code
, #pragma acc loop gang /* blockIdx.x */
, #pragma acc loop vector(128) /* threadIdx.x */
, Generating implicit copyin(a[:row][:col])
Generating implicit copyout(c[:row][:col])
Generating implicit copyin(b[:row][:col])
, Loop is parallelizable D:\Code\OpenACC\OpenACCProject\OpenACCProject>main_acc_loop1.exe
launch CUDA kernel file=C:/Program Files (x86)/Windows Kits//Include/10.0.16299.0/ucrt\time.h function=main
line= device= threadid= num_gangs= num_workers= vector_length= grid= block= Time with acc: ms D:\Code\OpenACC\OpenACCProject\OpenACCProject>main_acc_loop2.exe
launch CUDA kernel file=C:/Program Files (x86)/Windows Kits//Include/10.0.16299.0/ucrt\time.h function=main
line= device= threadid= num_gangs= num_workers= vector_length= grid= block= // 优化结果完全相同 Time with acc: ms

● 三重循环,无论仅使用外循环 loop、外中循环 loop,还是外中内循环 loop,获得的编译和运行结果都是相同的,只放上来一个进行讨论

 #include <stdio.h>
#include <time.h>
#include <openacc.h> const int row = , col = , page = ; int main()
{
int i, j, k, a[row][col][page], b[row][col][page], c[row][col][page];
clock_t time;
for (i = ; i < row; i++)
{
for (j = ; j < col; j++)
{
for (k = ; k < page; k++)
a[i][j][k] = b[i][j][k] = i + j + k;
}
} #ifdef _OPENACC
time = clock();
#pragma acc parallel
#pragma acc loop
for (i = ; i < row; i++)
{
//#pragma acc loop
for (j = ; j < col; j++)
{
//#pragma acc loop
for (k = ; k<page; k++)
c[i][j][k] = a[i][j][k] + b[i][j][k];
}
}
time = clock() - time;
printf("\nTime with acc:%d ms\n", time);
#else
time = clock();
for (i = ; i < row; i++)
{
for (j = ; j < col; j++)
{
for (k = ; k<page; k++)
c[i][j][k] = a[i][j][k] + b[i][j][k];
}
}
time = clock() - time;
printf("\nTime without acc:%d ms\n", time);
#endif
getchar();
return ;
}

● 输出结果

D:\Code\OpenACC\OpenACCProject\OpenACCProject>pgcc -acc -Minfo main.c -o main_acc_loop.exe
main:
, Accelerator kernel generated
Generating Tesla code
, #pragma acc loop gang /* blockIdx.x */ // 并行化了外层循环和内层循环,但是用中间层使用的是串行
, #pragma acc loop seq
, #pragma acc loop vector(128) /* threadIdx.x */
, Generating implicit copyout(c[:row][:col][:page])
Generating implicit copyin(b[:row][:col][:page],a[:row][:col][:page])
, Loop is parallelizable
, Loop is parallelizable D:\Code\OpenACC\OpenACCProject\OpenACCProject>main_acc_loop1.exe
launch CUDA kernel file=C:/Program Files (x86)/Windows Kits//Include/10.0.16299.0/ucrt\time.h function=main
line= device= threadid= num_gangs= num_workers= vector_length= grid= block= Time with acc: ms

OpenACC parallel的更多相关文章

  1. 7.OpenACC

    OpenACC: openacc 可以用于fortran, c 和 c++程序,可以运行在CPU或者GPU设备. openacc的代码就是在原有的C语言基础上进行修改,通过添加:compiler di ...

  2. OpenACC 云水参数化方案

    ▶ 书上第十三章,用一系列步骤优化一个云水参数化方案.用于熟悉 Fortran 以及 OpenACC 在旗下的表现 ● 代码,文件较多,放在一起了 ! main.f90 PROGRAM main US ...

  3. OpenACC 绘制曼德勃罗集

    ▶ 书上第四章,用一系列步骤优化曼德勃罗集的计算过程. ● 代码 // constants.h ; ; ; ; const double xmin=-1.7; ; const double ymin= ...

  4. OpenACC 优化矩阵乘法

    ▶ 按书上的步骤使用不同的导语优化矩阵乘法 ● 所有的代码 #include <iostream> #include <cstdlib> #include <chrono ...

  5. OpenACC 简单的原子操作

    ▶ OpenACC 的原子操作,用到了 C++ 的一个高精度计时器 ● 代码,直接的原子操作 #include <iostream> #include <cstdlib> #i ...

  6. OpenACC Julia 图形

    ▶ 书上的代码,逐步优化绘制 Julia 图形的代码 ● 无并行优化(手动优化了变量等) #include <stdio.h> #include <stdlib.h> #inc ...

  7. OpenACC 异步计算

    ▶ 按照书上的例子,使用 async 导语实现主机与设备端的异步计算 ● 代码,非异步的代码只要将其中的 async 以及第 29 行删除即可 #include <stdio.h> #in ...

  8. OpenACC 计算圆周率(简单版)

    ▶ 书上的计算圆周率的简单程序,主要是使用了自定义函数 #include <stdio.h> #include <stdlib.h> #include <math.h&g ...

  9. OpenACC 计算构建内的自定义函数

    ▶ 使用 routine 构件创建的自定义函数,在并行调用上的差别 ● 代码,自定义一个 sqab 函数,使用内建函数 fabsf 和 sqrtf 计算一个矩阵所有元素绝对值的平方根 #include ...

随机推荐

  1. jsp内置对象request 和response

    1.request对象主要用于处理客户端的请求 request对象常用方法 一.String  request.getParameter(String name)             根据页面表单 ...

  2. MySQL · 特性分析 · 优化器 MRR & BKA【转】

    MySQL · 特性分析 · 优化器 MRR & BKA 上一篇文章咱们对 ICP 进行了一次全面的分析,本篇文章小编继续为大家分析优化器的另外两个选项: MRR & batched_ ...

  3. 使用python生成词云

    什么是词云呢? 词云就是一些关键词组成的一个图片.大家在网上经常看到,下面看一些例子: 那用python生成一个词云的话怎么办呢,首先要有一些词,咱们随便找个吧,用see you again的歌词好了 ...

  4. Flask视图函数与普通函数的区别,响应对象Response

    视图函数与普通函数看似没什么区别,其实他们的返回值上有着很大的区别. from flask import Flask app = Flask(__name__) @app.route('/hello' ...

  5. Flask请求处理流程(request)[待续]

    WSGI简介 WSGI(全称Web Server Gateway Interface),是为 Python 语言定义的Web服务器和Web应用程序之间的一种简单而通用的接口,它封装了接受HTTP请求. ...

  6. 轻松理解execl系列函数

    execl函数功能如下:启动一个可执行文件,并且对他进行传送参数.一些原型如下 #include <unistd.h> extern char **environ; int execl(c ...

  7. 关于Jquery 插件开发,写的很清楚了。。。

    转自:http://blog.jobbole.com/30550/ 本文由 伯乐在线 - 戴嘉华 翻译.未经许可,禁止转载!英文出处:Extraordinarythoughts.欢迎加入翻译小组. 如 ...

  8. maven学习(1)-简介与安装

    一.Maven 简介 Maven 官网:http://maven.apache.org/ 二.Maven 安装与配置 Maven 下载:http://maven.apache.org/download ...

  9. 杂项-自动化测试工具:Selenium(浏览器自动化测试框架)

    ylbtech-杂项-自动化测试工具:Selenium(浏览器自动化测试框架) Selenium 是一个用于Web 应用程序测试的工具.Selenium 测试直接运行在浏览器中,就像真正的用户在操作一 ...

  10. 超链接中 utm_source, utm_medium 等参数的含义是什么?

    作者:张溪梦 Simon链接:https://www.zhihu.com/question/48724061/answer/122730629来源:知乎著作权归作者所有.商业转载请联系作者获得授权,非 ...