▶ 使用 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. 谈ObjC对象的两段构造模式

    前言 Objective-c语言在申请对象的时,需要使用两段构造(Two Stage Creation)的模式.一个对象的创建,需要先调用alloc方法或allocWithZone方法,再调用init ...

  2. C条件编译

    #include <stdio.h> void main() { #ifdef AAA printf("find AAA defined\n"); #else prin ...

  3. 我的nginx iis 负载均衡学习(环境搭建)

    1,下载并安装nginx 比较简单 2,进行网站的配置 我使用了我的IIS 站点中已经拥有的两个站点 3,进行nginx 的配置 配置如下: 在server 节点之前添加如下的配置: upstream ...

  4. nyoj 某种序列

    某种序列 时间限制:3000 ms  |  内存限制:65535 KB 难度:4   描述 数列A满足An = An-1 + An-2 + An-3, n >= 3 编写程序,给定A0, A1 ...

  5. mysql的一些 参数查询

    1 查询 事务 超时时间: SHOW GLOBAL VARIABLES LIKE 'innodb_lock_wait_timeout'; (默认innodb引擎事务的超时时间) 2 查询事务隔离级别 ...

  6. django model 插入数据方法

    需要插入的数据表结构如下: class UserInfo(models.Model): user_id =models.AutoField(primary_key=True) user_name=mo ...

  7. Nginx 下部署 HTTPS 与安全调优

    什么是 HTTPS?# HTTPS(全称:Hyper Text Transfer Protocol over Secure Socket Layer),是以安全为目标的HTTP通道,简单讲是HTTP的 ...

  8. HBase常用指令

    disable 'smsFlow'drop 'smsFlow'create 'smsFlow','info','partition'count 'smsFlow'scan 'smsFlow' trun ...

  9. vuex基本熟悉与使用

    vuex的入门与使用讲解 官网:https://vuex.vuejs.org/zh/guide/state.html 定义:Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式.它采用集中式 ...

  10. 【linux】Linux软连接和硬链接

    1.Linux链接概念 Linux链接分两种,一种被称为硬链接(Hard Link),另一种被称为符号链接(Symbolic Link).默认情况下,ln命令产生硬链接. [硬连接] 硬连接指通过索引 ...