OpenACC kernels
▶ 使用 kernels 导语并行化 for 循环
● 一重循环
- #include <stdio.h>
- #include <time.h>
- #include <openacc.h>
- const int row = * * ;
- int main()
- {
- int a[row], b[row], c[row];
- for (int i = ; i < row; ++i) // 填充 a 和 b
- a[i] = b[i] = i;
- clock_t time = clock();
- #ifdef _OPENACC // 使用 OpenACC 时执行本段
- #pragma acc kernels
- for (int i = ; i < row; ++i) // c = a + b
- c[i] = a[i] + b[i];
- time = clock() - time;
- printf("\nTime with acc:%d ms\n", time);
- #else // 不用 OpenACC 时执行本段
- for (int 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>pgcc main.c -o main-no-acc.exe -Minfo // 编译,-Minfo 要求输出编译优化信息,没有额外输出
- D:\Code\OpenACC>pgcc main.c -o main.exe -Minfo -acc // 编译,-acc 要求使用 OpenACC
- main:
- , Generating implicit copyin(b[:row]) // 数据管理控制
- Generating implicit copyout(c[:row])
- Generating implicit copyin(a[:row])
- , Loop is parallelizable // 并行优化
- Generating Tesla code
- , #pragma acc loop gang, vector(128) /* blockIdx.x threadIdx.x */ // 使用默认 vector 尺寸,注释是自动生成的
- D:\Code\OpenACC>main-no-acc.exe
- Time without acc: ms
- D:\Code\OpenACC>main-acc.exe
- launch CUDA kernel file=D:\Code\OpenACC\main.c function=main line= device= threadid= num_gangs= num_workers= vector_length= grid= block=
- // 对代码第 16 行的 for 进行了并行优化,
- Time with acc: ms // 使用第 0 号设备(GPU)
- // 线程编号 1,使用 gang 65536 个,worker 1 个,vector 宽度 128
- // CUDA 配置为 gridDim.x = 65536,blockDim.x = 128Time
- // 每单元计算负载 = row / grid / block = 2
● 二重循环
- #include <stdio.h>
- #include <time.h>
- #include <openacc.h>
- const int row = * , col = ;
- int main()
- {
- int a[row][col], b[row][col], c[row][col];
- for (int i = ; i < row; i++) // 填充 a 和 b
- {
- for (int j = ; j < col; j++)
- a[i][j] = b[i][j] = i * j;
- }
- clock_t time = clock();
- #ifdef _OPENACC
- #pragma acc kernels
- for (int i = ; i < row; i++) // c = a + b
- {
- for (int 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
- for (int i = ; i < row; i++)
- {
- for (int 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>pgcc main.c -o main-no-acc.exe -Minfo
- D:\Code\OpenACC>pgcc main.c -o main-acc.exe -Minfo -acc
- main:
- , Generating implicit copyin(a[:row][:col])
- Generating implicit copyout(c[:row][:col])
- Generating implicit copyin(b[:row][:col])
- , Loop is parallelizable
- , Loop is parallelizable
- Generating Tesla code
- , #pragma acc loop gang, vector(4) /* blockIdx.y threadIdx.y */ // 高一层的循环使用的是 worker
- , #pragma acc loop gang, vector(32) /* blockIdx.x threadIdx.x */
- D:\Code\OpenACC>main-no-acc.exe
- Time without acc: ms
- D:\Code\OpenACC>main-acc.exe
- launch CUDA kernel file=D:\Code\OpenACC\main.c function=main line= device= threadid= num_gangs= num_workers= vector_length= grid=16x2048 block=32x4
- // 注意参数变化,仍有 num_gangs = grid,num_workers * vector_length = block
- Time with acc: ms // 每单元计算负载 = row * col / grid / block = 4
● 三重循环
- #include <stdio.h>
- #include <time.h>
- #include <openacc.h>
- const int row = , col = , page = ;
- int main()
- {
- int a[row][col][page], b[row][col][page], c[row][col][page];
- for (int i = ; i < row; i++) // 填充 a 和 b
- {
- for (int j = ; j < col; j++)
- {
- for (int k = ; k < page; k++)
- a[i][j][k] = b[i][j][k] = i * j + k;
- }
- }
- clock_t time = clock();
- #ifdef _OPENACC
- #pragma acc kernels
- for (int i = ; i < row; i++) // c = a + b
- {
- for (int j = ; j < col; j++)
- {
- for (int 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
- for (int i = ; i < row; i++)
- {
- for (int j = ; j < col; j++)
- {
- for (int 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>pgcc main.c -o main-no-acc.exe -Minfo
- D:\Code\OpenACC>pgcc main.c -o main-acc.exe -Minfo -acc
- main:
- , Generating implicit copyin(b[:row][:col][:page])
- Generating implicit copyout(c[:row][:col][:page])
- Generating implicit copyin(a[:row][:col][:page])
- , Loop is parallelizable
- , Loop is parallelizable
- , Loop is parallelizable
- Generating Tesla code
- , #pragma acc loop gang /* blockIdx.y */ // 最高层循环尝试调整 grid
- , #pragma acc loop gang, vector(4) /* blockIdx.z threadIdx.y */
- , #pragma acc loop gang, vector(32) /* blockIdx.x threadIdx.x */
- D:\Code\OpenACC>main-no-acc.exe
- Time without acc: ms
- D:\Code\OpenACC>main-acc.exe
- launch CUDA kernel file=D:\Code\OpenACC\main.c function=main line= device= threadid= num_gangs= num_workers= vector_length= grid=16x128x16 block=32x4
- // grid 变成了三维
- Time with acc: ms // 每单元计算负载 = row *col * page / grid / block = 4
- // row 改为 64,则 grid=16x128x16 block=32x4,计算负载 = 2
- // col 改为 128,则 grid=16x128x16 block=32x4,计算负载 = 2
- // page 改为 256,则 grid=8x128x32 block=32x4,计算负载 = 2
- // row 改为 32,则 grid=16x32x64 block=32x4,计算负载 = 1
● 在 ubuntu 上跑一重循环的代码,注意计时器单位是 μs
- cuan@CUAN:~/Temp$ pgcc -acc main.c -o main.exe
- cuan@CUAN:~/Temp$ pgcc main.c -o main-no-acc.exe
- cuan@CUAN:~/Temp$ ./main.exe
- Time with acc: us
- cuan@CUAN:~/Temp$ ./main-no-acc.exe
- Time without acc: us
OpenACC kernels的更多相关文章
- 7.OpenACC
OpenACC: openacc 可以用于fortran, c 和 c++程序,可以运行在CPU或者GPU设备. openacc的代码就是在原有的C语言基础上进行修改,通过添加:compiler di ...
- OpenACC 梯度下降法求解线性方程的优化
▶ 书上第二章,用一系列步骤优化梯度下降法解线性方程组.才发现 PGI community 编译器不支持 Windows 下的 C++ 编译(有 pgCC 命令但是不支持 .cpp 文件,要专业版才支 ...
- OpenACC 优化矩阵乘法
▶ 按书上的步骤使用不同的导语优化矩阵乘法 ● 所有的代码 #include <iostream> #include <cstdlib> #include <chrono ...
- OpenACC 与 CUDA 的相互调用
▶ 按照书上的代码完成了 OpenACC 与CUDA 的相互调用,以及 OpenACC 调用 cuBLAS.便于过程遇到了很多问题,注入 CUDA 版本,代码版本,计算能力指定等,先放在这里,以后填坑 ...
- OpenACC Julia 图形
▶ 书上的代码,逐步优化绘制 Julia 图形的代码 ● 无并行优化(手动优化了变量等) #include <stdio.h> #include <stdlib.h> #inc ...
- OpenACC 异步计算
▶ 按照书上的例子,使用 async 导语实现主机与设备端的异步计算 ● 代码,非异步的代码只要将其中的 async 以及第 29 行删除即可 #include <stdio.h> #in ...
- OpenACC 书上的范例代码(Jacobi 迭代),part 3
▶ 使用Jacobi 迭代求泊松方程的数值解 ● 使用 data 构件,强行要求 u0 仅拷入和拷出 GPU 各一次,u1 仅拷入GPU 一次 #include <stdio.h> #in ...
- OpenACC数据管理语句
▶ 书中第4章,数据管理部分的代码和说明 ● 代码,关于 copy,copyin,copyout,create #include <stdio.h> #include <openac ...
- OpenACC 书上的范例代码(Jacobi 迭代),part 2
▶ 使用Jacobi 迭代求泊松方程的数值解 ● 首次使用 OpenACC 进行加速,使用动态数组,去掉了误差控制 #include <stdio.h> #include <stdl ...
随机推荐
- (6)time&datetime(时间模块)
什么是时间模块 就是处理时间相关的功能 如用户注册的时间.统计程序运行的时间等 time 模块 计算机中有三种时间 1.时间戳 从1970年到今天,这个时间段中间经历的秒数 获取时间戳:time.t ...
- 【java规则引擎】《Drools7.0.0.Final规则引擎教程》第4章 4.2 ruleflow-group&salience
转载至:https://blog.csdn.net/wo541075754/article/details/75299888 ruleflow-group 在使用规则流的时候要用到ruleflow-g ...
- PostgREST docker-compose 试用
PostgREST 是一款很不错的直接将pg 数据库暴露为restapi ,使用了基于行级别安全访问控制, 比较全的restapi 查询以及集成了swagger openapi docker-comp ...
- 系列文章--jQuery教程
从零开始学习jQuery (一) 开天辟地入门篇 从零开始学习jQuery (二) 万能的选择器 从零开始学习jQuery (三) 管理jQuery包装集 从零开始学习jQuery (四) 使用jQu ...
- oracle之 11.2.0.4 bbed安装
一. bbed安装: 1.ORACLE 11G下安装BBED,需要从ORACLE 10G中复制三个包 sbbdpt.o .ssbbded.o 并将两个文件移到$ORACLE_HOME/rdbms/li ...
- c#中如何保存焦点控件?
对所有文本框添加焦点获得事件,头部再定义一个全局的object或者control的类型对象,在焦点获得事件中把当前控件对象赋值给之前定义的object或者control对象,操作的话就对这个全局量操作 ...
- Microsoft Dynamics CRM4.0 创建单据的时候,自动生成单据编号的通用方法
一.新建两个实体,具体如下: 单据流水号(new_maxbillcode) 显示名称 名称 类型 格式 最大长度 需求级别 IME模式 备注 名称 new_name nvarchar 文本 100 业 ...
- ExtJS中,将Grid表头中的全选复选框取消复选
今天发现公司产品用的EXTJS中使用Grid时,Grid表头中的全选复选框的选中状态不是很准确,就写了这个小扩展 在js中加入下面方法,在需要取消全选的地方调用即可,例:Ext.getCmp('gri ...
- "二阶“条件概率
公式: P(E|F)=P(E|GF)P(G|F)+P(E|GcF)P(Gc|F) 解释: 已知F发生,E发生的条件概率为P(E|F). 现在多考虑一个条件G,G可能发生也可能不发生. 若F已发生条件下 ...
- 【ActiveMQ入门-5】ActiveMQ学习-消息持久性
ActiveMQ中的消息持久性 ActiveMQ很好的支持了消息的持久性(Persistence).消息持久性对于可靠消息传递来说应该是一种比较好的方法,有了消息持久化,即使发送者和接受者不是 ...