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

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

  1. #include <stdio.h>
  2. #include <time.h>
  3. #include <openacc.h>
  4.  
  5. const int row = ;
  6.  
  7. int main()
  8. {
  9. int i, j, k, a[row], b[row], c[row];
  10. clock_t time;
  11. for (i = ; i < row; i++)
  12. a[i] = b[i] = i;
  13.  
  14. #ifdef _OPENACC
  15. time = clock();
  16. #pragma acc kernels     // 使用 kernels 或 parallel 或 parallel + loop
  17. // #pragma acc parallel
  18. // #pragma acc loop
  19. for (i = ; i < row; i++)
  20. c[i] = a[i] + b[i];
  21. time = clock() - time;
  22. printf("\nTime with acc:%d ms\n", time);
  23. #else
  24. time = clock();
  25. for (i = ; i < row; i++)
  26. c[i] = a[i] + b[i];
  27. time = clock() - time;
  28. printf("\nTime without acc:%d ms\n", time);
  29. #endif
  30. getchar();
  31. return ;
  32. }

● 输出结果

  1. D:\Code\OpenACC\OpenACCProject\OpenACCProject>pgcc -acc -Minfo main.c -o main_acc_kernels.exe // kernels
  2. main:
  3. , Generating implicit copyin(b[:row])
  4. Generating implicit copyout(c[:row])
  5. Generating implicit copyin(a[:row])
  6. , Loop is parallelizable
  7. Accelerator kernel generated
  8. Generating Tesla code
  9. , #pragma acc loop gang, vector(128) /* blockIdx.x threadIdx.x */
  10.  
  11. D:\Code\OpenACC\OpenACCProject\OpenACCProject>pgcc -acc -Minfo main.c -o main_acc_parallel.exe // parallel
  12. main:
  13. , Accelerator kernel generated
  14. Generating Tesla code
  15. , #pragma acc loop vector(128) /* threadIdx.x */
  16. , Generating implicit copyout(c[:row])
  17. Generating implicit copyin(b[:row],a[:row])
  18. , Loop is parallelizable
  19.  
  20. D:\Code\OpenACC\OpenACCProject\OpenACCProject>pgcc -acc -Minfo main.c -o main_acc_parallel_loop.exe // parallel + loop
  21. main:
  22. , Accelerator kernel generated
  23. Generating Tesla code
  24. , #pragma acc loop gang, vector(128) /* blockIdx.x threadIdx.x */
  25. , Generating implicit copyout(c[:row])
  26. Generating implicit copyin(b[:row],a[:row])
  27.  
  28. D:\Code\OpenACC\OpenACCProject\OpenACCProject>main_acc_kernels.exe
  29. launch CUDA kernel file=C:/Program Files (x86)/Windows Kits//Include/10.0.16299.0/ucrt\time.h function=main
  30. line= device= threadid= num_gangs= num_workers= vector_length= grid= block= // 多个 gang,自动配置,线程网格全都是一维的
  31.  
  32. Time with acc: ms
  33.  
  34. D:\Code\OpenACC\OpenACCProject\OpenACCProject>main_acc_parallel.exe
  35. launch CUDA kernel file=C:/Program Files (x86)/Windows Kits//Include/10.0.16299.0/ucrt\time.h function=main
  36. line= device= threadid= num_gangs= num_workers= vector_length= grid= block= // 一个 gang,gang冗余模式
  37.  
  38. Time with acc: ms
  39.  
  40. D:\Code\OpenACC\OpenACCProject\OpenACCProject>main_acc_parallel_loop.exe
  41. launch CUDA kernel file=C:/Program Files (x86)/Windows Kits//Include/10.0.16299.0/ucrt\time.h function=main
  42. line= device= threadid= num_gangs= num_workers= vector_length= grid= block= // 多个 gang,gang分裂模式
  43.  
  44. Time with acc: ms

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

  1. #include <stdio.h>
  2. #include <time.h>
  3. #include <openacc.h>
  4.  
  5. const int row = , col = ;
  6.  
  7. int main()
  8. {
  9. int i, j, k, a[row][col], b[row][col], c[row][col];
  10. clock_t time;
  11. for (i = ; i < row; i++)
  12. {
  13. for (j = ; j < col; j++)
  14. a[i][j] = b[i][j] = i + j;
  15. }
  16.  
  17. #ifdef _OPENACC
  18. time = clock();
  19. #pragma acc parallel
  20. #pragma acc loop
  21. for (i = ; i < row; i++)
  22. {
  23. // #pragma acc loop
  24. for (j = ; j < col; j++)
  25. c[i][j] = a[i][j] + b[i][j];
  26. }
  27. time = clock() - time;
  28. printf("\nTime with acc:%d ms\n", time);
  29. #else
  30. time = clock();
  31. for (i = ; i < row; i++)
  32. {
  33. for (j = ; j < col; j++)
  34. c[i][j] = a[i][j] + b[i][j];
  35. }
  36. time = clock() - time;
  37. printf("\nTime without acc:%d ms\n", time);
  38. #endif
  39. getchar();
  40. return ;
  41. }

● 输出结果

  1. D:\Code\OpenACC\OpenACCProject\OpenACCProject>pgcc -acc -Minfo main.c -o main_acc_loop1.exe // 仅使用外层 loop
  2. main:
  3. , Accelerator kernel generated
  4. Generating Tesla code
  5. , #pragma acc loop gang /* blockIdx.x */
  6. , #pragma acc loop vector(128) /* threadIdx.x */
  7. , Generating implicit copyin(a[:row][:col])
  8. Generating implicit copyout(c[:row][:col])
  9. Generating implicit copyin(b[:row][:col])
  10. , Loop is parallelizable
  11.  
  12. D:\Code\OpenACC\OpenACCProject\OpenACCProject>pgcc -acc -Minfo main.c -o main_acc_loop2.exe // 内外都使用 loop,优化结果完全相同
  13. main:
  14. , Accelerator kernel generated
  15. Generating Tesla code
  16. , #pragma acc loop gang /* blockIdx.x */
  17. , #pragma acc loop vector(128) /* threadIdx.x */
  18. , Generating implicit copyin(a[:row][:col])
  19. Generating implicit copyout(c[:row][:col])
  20. Generating implicit copyin(b[:row][:col])
  21. , Loop is parallelizable
  22.  
  23. D:\Code\OpenACC\OpenACCProject\OpenACCProject>main_acc_loop1.exe
  24. launch CUDA kernel file=C:/Program Files (x86)/Windows Kits//Include/10.0.16299.0/ucrt\time.h function=main
  25. line= device= threadid= num_gangs= num_workers= vector_length= grid= block=
  26.  
  27. Time with acc: ms
  28.  
  29. D:\Code\OpenACC\OpenACCProject\OpenACCProject>main_acc_loop2.exe
  30. launch CUDA kernel file=C:/Program Files (x86)/Windows Kits//Include/10.0.16299.0/ucrt\time.h function=main
  31. line= device= threadid= num_gangs= num_workers= vector_length= grid= block= // 优化结果完全相同
  32.  
  33. Time with acc: ms

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

  1. #include <stdio.h>
  2. #include <time.h>
  3. #include <openacc.h>
  4.  
  5. const int row = , col = , page = ;
  6.  
  7. int main()
  8. {
  9. int i, j, k, a[row][col][page], b[row][col][page], c[row][col][page];
  10. clock_t time;
  11. for (i = ; i < row; i++)
  12. {
  13. for (j = ; j < col; j++)
  14. {
  15. for (k = ; k < page; k++)
  16. a[i][j][k] = b[i][j][k] = i + j + k;
  17. }
  18. }
  19.  
  20. #ifdef _OPENACC
  21. time = clock();
  22. #pragma acc parallel
  23. #pragma acc loop
  24. for (i = ; i < row; i++)
  25. {
  26. //#pragma acc loop
  27. for (j = ; j < col; j++)
  28. {
  29. //#pragma acc loop
  30. for (k = ; k<page; k++)
  31. c[i][j][k] = a[i][j][k] + b[i][j][k];
  32. }
  33. }
  34. time = clock() - time;
  35. printf("\nTime with acc:%d ms\n", time);
  36. #else
  37. time = clock();
  38. for (i = ; i < row; i++)
  39. {
  40. for (j = ; j < col; j++)
  41. {
  42. for (k = ; k<page; k++)
  43. c[i][j][k] = a[i][j][k] + b[i][j][k];
  44. }
  45. }
  46. time = clock() - time;
  47. printf("\nTime without acc:%d ms\n", time);
  48. #endif
  49. getchar();
  50. return ;
  51. }

● 输出结果

  1. D:\Code\OpenACC\OpenACCProject\OpenACCProject>pgcc -acc -Minfo main.c -o main_acc_loop.exe
  2. main:
  3. , Accelerator kernel generated
  4. Generating Tesla code
  5. , #pragma acc loop gang /* blockIdx.x */ // 并行化了外层循环和内层循环,但是用中间层使用的是串行
  6. , #pragma acc loop seq
  7. , #pragma acc loop vector(128) /* threadIdx.x */
  8. , Generating implicit copyout(c[:row][:col][:page])
  9. Generating implicit copyin(b[:row][:col][:page],a[:row][:col][:page])
  10. , Loop is parallelizable
  11. , Loop is parallelizable
  12.  
  13. D:\Code\OpenACC\OpenACCProject\OpenACCProject>main_acc_loop1.exe
  14. launch CUDA kernel file=C:/Program Files (x86)/Windows Kits//Include/10.0.16299.0/ucrt\time.h function=main
  15. line= device= threadid= num_gangs= num_workers= vector_length= grid= block=
  16.  
  17. 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. IO练习--按字节截取字符串

    * 在Java中字符串“abcd”和字符串“ab你好”都是4个字符, * 但是字节数不同,因为GBK中一个汉字占两个字节 * 定义一个方法用来按字节数截取字符串. * 如:对于“ab你好”,取3个字节 ...

  2. BC32(hdu5182~5185)

    恩……又是一个悲伤的故事,然后BC做出来一题,因为自己傻逼,可能紧张,也可能是其他,反正没看全题目就敲,敲完WA,WA完改,改完WA,没了……大概五十几分钟WA了五法,然后问了才知道没看全,就这样,后 ...

  3. 用C#通过反射实现动态调用WebService 告别Web引用(转载)

    我们都知道,调用WebService可以在工程中对WebService地址进行WEB引用,但是这确实很不方便.我想能够利用配置文件灵活调用WebService.如何实现呢? 用C#通过反射实现动态调用 ...

  4. graphEdit

    目的 实现支持算法流程图 参考代码 c# DSGraphEdit - CodeProject NetworkView: A WPF custom control for visualizing and ...

  5. [C#]画图全攻略(饼图与柱状图)(转)

    http://blog.chinaunix.net/uid-15481846-id-2769484.html 首先建立一个c#的类库.   打开vs.net,建立一个名为Insight_cs.WebC ...

  6. bzoj 4484 [Jsoi2015]最小表示——bitset

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=4484 每个点上存一下它到每个点的连通性.用 bitset 的话空间就是 \( \frac{n ...

  7. golang init函数

    init函数有一下几点特性: init函数在main执行之前,自动被调用执行的,不能显示调用 每个包的init函数在包被引用时,自动被调用 每个包可以有多个init函数 同一个文件中可定义多个init ...

  8. 温习《PHP 核心技术与最佳实践》这本书

    再次看这本书,顺手提炼了一下大致目录,以便后续看见目录就知道大概讲的些什么内容 PHP 核心技术与最佳实践 1.面向对象思想的核心概念 1.1 面向对象的『形』与『本』 1.2 魔术方法的应用 1.2 ...

  9. 【python】实例-创建文件并通过键盘输入字符

    import os lnend=os.linesep ##windows行结束符号是“\r\n” FileName=raw_input("please input filename:&quo ...

  10. iPhone激活策略说明

    本帖最后由 苏州汇东 于 2014-7-2 19:13 编辑 奉告各位封釉 千万不要泄露机器序列号IMEI号 远程ID真的可以上  只要机器上没有ID 就可以远程上任何ID 我这可以远程上ID 也帮忙 ...