▶ 使用 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. jQuery插件制作方法详解

        jQuery插件制作方法详解   jquery插件给我的感觉清一色的清洁,简单.如Jtip,要使用它的功能,只需要在你的元素的class上加 上Jtip,并引入jtip.js及其样式即可以了. ...

  2. 脸部识别JavaScript类库Tracking.js

    作者 王文刚 发布于 2014年8月10日 |   对Web开发者而言,开源的JavaScript库Tracking.js正在使计算机视觉和增强现实技术变得简单, 使用它可以展示效果类似Kinect或 ...

  3. smarty学习——变量调节器(过滤器)

    变量调节器用于变量,自定义函数和字符串. 请使用 | 符号和调节器名称应用调节器.变量调节器由赋予的参数值决定其行为.参数由:符号分开. 比如进行大写转换的: upper demo: <br&g ...

  4. 转 微软Sysinternals Suite工具13年12月版下载

    Sysinternals Suite 是微软出品的一套集成数十个绿色软件的系统工具包.Sysinternals Suite 和IT之家的魔方电脑大师设计一样,里面的各个小工具组件都可以单独拿出来运行, ...

  5. zz 史上最全--各银行借记卡的年费、小额管理费、转账费等!

    史上最全--各银行借记卡的年费.小额管理费.转账费等! 发布时间:2015-01-14 17:28:10 还在迷茫借记卡自费的菜主儿们~菜菜特别整理关于各银行借记卡.存折账户等的年费.小额管理费.转账 ...

  6. 【转】每天一个linux命令(12):more命令

    原文网址:http://www.cnblogs.com/peida/archive/2012/11/02/2750588.html more命令,功能类似 cat ,cat命令是整个文件的内容从上到下 ...

  7. Mac 上 java 究竟在哪里,本文彻底让你搞清楚!

    Mac下当你在[终端]输入java -version时,是执行的哪里的java呢,which java命令可以看到,就是[/usr/bin/java] [/usr/bin/java]只是个替身,实际指 ...

  8. R(5): sql 数据处理

    sqldf程序包是R语言中实用的数据管理辅助工具,但最新版本的包在处理中文时出现乱码,待解决 Usage:  sqldf(x, stringsAsFactors = FALSE,  row.names ...

  9. 转-使用 CefSharp 在 C# App 中嵌入 Chrome 浏览器

    使用 CefSharp 在 C# App 中嵌入 Chrome 浏览器 2016-09-23    分类:.NET开发.编程开发.首页精华0人评论 分享到:更多3 本文由码农网 – 小峰原创翻译,转载 ...

  10. FileStream 和StreamWriter 一起用时

    StreamWriter  Flush 即可. FileStream Flush 无用.