首页 OpenACC编程例子-小小河-20130113

OpenACC编程例子-小小河-20130113

举报
开通vip

OpenACC编程例子-小小河-20130113 OpenACC 编程例子 小小河 2013 年 1 月 13 日 1. 条件编译宏变量_OPENACC 这个宏是可以当做整型变量输出,无法当作字符串输出 /* macro.c */ #include int main() { printf("_OPENACC = %d\n", _OPENACC); return 0; } 程序输出为 _OPENACC = 20111111 这个宏的定义方式等价为 #define _OPENACC 20111111 ...

OpenACC编程例子-小小河-20130113
OpenACC 编程例子 小小河 2013 年 1 月 13 日 1. 条件编译宏变量_OPENACC 这个宏是可以当做整型变量输出,无法当作字符串输出 /* macro.c */ #include int main() { printf("_OPENACC = %d\n", _OPENACC); return 0; } 程序输出为 _OPENACC = 20111111 这个宏的定义方式等价为 #define _OPENACC 20111111 2. 有数据依赖的 kernels loop 导语 #include 1 // export PGI_ACC_NOTIFY=1 2 // export PGI_ACC_TIME=1 3 // compile: pgcc -acc -Minfo t3-1.c 4 // run: ./t3-1.exe 5 6 #define n 1000 7 8 int main() 9 { 10 int i; 11 int *a, *b, *c; 12 a = (int*)malloc(n*sizeof(int)); 13 b = (int*)malloc(n*sizeof(int)); 14 c = (int*)malloc(n*sizeof(int)); 15 for(i = 0; i < n; i++) 16 { 17 a[i] = 0; 18 b[i] = c[i] = i; 19 } 20 #pragma acc kernels loop 21 for(i=0; i 2 #define n 1000 3 int main() 4 { 5 int i; 6 int *restrict a, *restrict b, *restrict c; 7 a = (int*)malloc(n*sizeof(int)); 8 b = (int*)malloc(n*sizeof(int)); 9 c = (int*)malloc(n*sizeof(int)); 10 for(i = 0; i < n; i++) 11 { 12 a[i] = 0; 13 b[i] = c[i] = i; 14 } 15 #pragma acc kernels loop 16 for(i=0; i #define n 1000 int main() { int i; int *a, *b, *c; a = (int*)malloc(n*sizeof(int)); b = (int*)malloc(n*sizeof(int)); c = (int*)malloc(n*sizeof(int)); for(i = 0; i < n; i++) { a[i] = 0; b[i] = c[i] = i; } #pragma acc kernels loop independent for(i=0; i #define n 1000 int main() { int i, a[n], b[n], c[n]; for(i = 0; i < n; i++) { a[i] = 0; b[i] = c[i] = i; } #pragma acc kernels loop for(i=0; i 1 #define N 1000 2 3 int main() 4 { 5 int a[N],i; 6 for(i=0; i< N; i++) a[i] = -1; 7 8 #pragma acc kernels loop 9 for(i=0; i #define N 1000 int main() { int a[N]; #pragma acc declare copy(a) int i; for(i=0; i< N; i++) a[i] = -1; #pragma acc kernels loop for(i=0; i 说明 关于失联党员情况说明岗位说明总经理岗位说明书会计岗位说明书行政主管岗位说明书 设备上的数据没有复制到主机端,需要使用 update 导语同步一下数据。将代码中 //#pragma acc update host(a) 的注释去掉,就以得到正确的结果 PGI$ ./datreg2.exe a[1] = 2 8. Declare 导语执行时机 #include #define N 1000 int main() { int a[N]; #pragma acc declare copy(a) int i; for(i=0; i< N; i++) a[i] = -10; #pragma acc kernels loop for(i=0; i 检测 工程第三方检测合同工程防雷检测合同植筋拉拔检测方案传感器技术课后答案检测机构通用要求培训 declare 导语复制数据的时机。如果数据复制发生在可执行语句之后, 那么最终的输出是 a[1] = 10;如果数据复制发生在可执行语句之前,那么 declare copy(a)的 执行结果就是设备端 a 所有元素的值皆为 0,经过 kernels 构件,a 所有元素的值被更新为 20,程序的最终输出是 a[1] = 20。 编译运行此程序,得到输出 PGI$ ./datreg2.exe a[1] = 20 从而得知,declare 导语的执行时机为可执行语之前。 9. acc_device_t 类型枚举变量 在 openacc.h 中有如下定义 typedef enum{ acc_device_none = 0, acc_device_default = 1, acc_device_host = 2, acc_device_not_host = 3, acc_device_nvidia = 4 }acc_device_t; 使用运行时库函数 acc_get_num_devices 时,可以设定的参数有 5 个,查询 nVidia 设备时, 使用 acc_get_num_devices(acc_device_nvidia) 比 openacc 标准 excel标准偏差excel标准偏差函数exl标准差函数国标检验抽样标准表免费下载红头文件格式标准下载 多定义了一个 acc_device_nvidia,其它 PGI 编译器目前仅支持 nVidia 编译器。 10. Parallel 区域不支持 IO 语句 #include 1 int main() 2 { 3 int a[10], i; 4 for(i=0; i<10; i++) 5 a[i] = i+10; 6 #pragma acc parallel 7 printf("a[0]=%d\n",a[0]); 8 return 0; 9 } 10 编译时将会报错 8, Accelerator restriction: unsupported call to 'printf' 这是因为不能在加速器上直接输入输出,所有输出操作必须绕道主机。 11. 在 kernels 区域中使用分支语句 program t1 implicit none integer a(1000), b(1000) integer i a(:) = 1 do i = 1,1000 b(i)= i enddo !$acc kernels do i = 1,1000 if(b(i)== 1) then a(i) = 100 else a(i) = 0 endif enddo !$acc end kernels print*, "a = ", a(1:4) endprogram Kernels 区域的 if-else-endif 语句导致两个执行路径,在设备上运行时,会破坏 GPU 的合并访 问,效率降低至原来的 50%,计算速度与 IO 速度都下降。如果循环次数特别多(远超 1000 次),那么加速比仍然很可观。 12. 数据子语 1. 子数组范围指定方式 子数组指定下标范的 方法 快递客服问题件处理详细方法山木方法pdf计算方法pdf华与华方法下载八字理论方法下载 有多种形式。 对fortran, 假设定义了 integer A(100,10); 那么可以下列多种形式: arr(下界 1:上界 1,下界 2:上界 2),标准形式,同时给出所有维度的上界和下界; A(:,:) 包含 A的所有元素,与 A等价; A(:,1) 包含 A的第 1列中所有元素; A(1:,1)包含 A 的第 1 列中所有元素,因为省略了第一个维度的上界,同时知道这个数组 声明时的上界为 100,所以认为上界就是 100;它等价于 A(1:100,1)和 A(:,1); A(:100,1)包含 A的第 1列中所有元素,这里省略了第 1个维度的下界,编译器就认为下 界是 1;它等价于 A(1:100,1)和 A(:,1); A(:,:2)等价于 A(:,1:2); program t2 1 implicit none 2 3 integer A(100,10) 4 integer lin, col 5 A = 0 6 print*, "A(1:2,1:2)=" , A(1:2,1:2) 7 8 !$acc kernels loop copy(A) 9 do lin = 1, 100 10 A(lin,1) = 1 11 enddo 12 print*, "A(1:2,1:2)=" , A(1:2,1:2) 13 14 !$acc kernels loop copy(A(:,:)) 15 do lin = 1, 100 16 A(lin,1) = 2 17 enddo 18 print*, "A(1:2,1:2)=" , A(1:2,1:2) 19 20 ! only copy the first column 21 !$acc kernels loop copy(A(:,1)) 22 do lin = 1, 100 23 A(lin,1) = 3 24 enddo 25 print*, "A(1:2,1:2)=" , A(1:2,1:2) 26 27 ! only copy the first column 28 !$acc kernels loop copy(A(1:,1)) 29 do lin = 1, 100 30 A(lin,1) = 4 31 enddo 32 print*, "A(1:2,1:2)=" , A(1:2,1:2) 33 34 ! only copy the first column 35 !$acc kernels loop copy(A(:100,1)) 36 do lin = 1, 100 37 A(lin,1) = 5 38 enddo 39 print*, "A(1:2,1:2)=" , A(1:2,1:2) 40 41 ! only copy the first column 42 !$acc kernels loop copy(A(:,:2)) 43 do lin = 1, 100 44 A(lin,1) = 6 45 enddo kernels loop copy(A(:,:2)) 46 print*, "A(1:2,1:2)=" , A(1:2,1:2) 47 48 endprogram 49 编译信息 PGI$ pgf90 -acc -Minfo d2.f90 t2: 6, Memory zero idiom, array assignment replaced by call to pgf90_mzero4 9, Generating present_or_copy(a(:,:)) Generating compute capability 1.0 binary Generating compute capability 2.0 binary 10, Loop is parallelizable Accelerator kernel generated 10, !$acc loop gang, vector(128) ! blockidx%x threadidx%x CC 1.0 : 7 registers; 24 shared, 4 constant, 0 local memory bytes CC 2.0 : 9 registers; 0 shared, 40 constant, 0 local memory bytes 15, Generating present_or_copy(a(:,:)) Generating compute capability 1.0 binary Generating compute capability 2.0 binary 16, Loop is parallelizable Accelerator kernel generated 16, !$acc loop gang, vector(128) ! blockidx%x threadidx%x CC 1.0 : 7 registers; 24 shared, 4 constant, 0 local memory bytes CC 2.0 : 9 registers; 0 shared, 40 constant, 0 local memory bytes 22, Generating present_or_copy(a(:,:1)) Generating compute capability 1.0 binary Generating compute capability 2.0 binary 23, Loop is parallelizable Accelerator kernel generated 23, !$acc loop gang, vector(128) ! blockidx%x threadidx%x CC 1.0 : 7 registers; 24 shared, 4 constant, 0 local memory bytes CC 2.0 : 9 registers; 0 shared, 40 constant, 0 local memory bytes 29, Generating present_or_copy(a(0:,:1)) Generating compute capability 1.0 binary Generating compute capability 2.0 binary 30, Loop is parallelizable Accelerator kernel generated 30, !$acc loop gang, vector(128) ! blockidx%x threadidx%x CC 1.0 : 7 registers; 24 shared, 4 constant, 0 local memory bytes CC 2.0 : 9 registers; 0 shared, 40 constant, 0 local memory bytes 36, Generating present_or_copy(a(:,:1)) Generating compute capability 1.0 binary Generating compute capability 2.0 binary 37, Loop is parallelizable Accelerator kernel generated 37, !$acc loop gang, vector(128) ! blockidx%x threadidx%x CC 1.0 : 7 registers; 24 shared, 4 constant, 0 local memory bytes CC 2.0 : 9 registers; 0 shared, 40 constant, 0 local memory bytes 43, Generating present_or_copy(a(:,:2)) Generating compute capability 1.0 binary Generating compute capability 2.0 binary 44, Loop is parallelizable Accelerator kernel generated 44, !$acc loop gang, vector(128) ! blockidx%x threadidx%x CC 1.0 : 7 registers; 24 shared, 4 constant, 0 local memory bytes CC 2.0 : 9 registers; 0 shared, 40 constant, 0 local memory bytes 运行结果 PGI$ ./d2.exe A(1:2,1:2)= 0 0 0 0 A(1:2,1:2)= 1 1 0 0 A(1:2,1:2)= 2 2 0 0 A(1:2,1:2)= 3 3 0 0 A(1:2,1:2)= 4 4 0 0 A(1:2,1:2)= 5 5 0 0 A(1:2,1:2)= 6 6 0 0 由运行结果可以看出,设上的赋值语都被正确执行。 对 C 和 C++,标准方法为 arr[下界:长度] 如果声明 int A[100]; 那么,A[:2]等价于 A[0], A[1],因为下界省略,默认为 0;A[2:]等价于 A[2:98],表示元素 A[2], A[3],...,A[99],因长度省略了,默认长度为声明的上界减去下界,即 100-2. 验证小程序 #include int main() { int A[100]; int i; #pragma acc kernels loop copy(A) for(i=0; i<100; i++) A[i] = 1; printf("A[0:1]=%d\t%d\n",A[0],A[1]); #pragma acc kernels loop copy(A[:]) for(i=0; i<100; i++) A[i] = 2; printf("A[0:1]=%d\t%d\n",A[0],A[1]); #pragma acc kernels loop copy(A[:2]) for(i=0; i<2; i++) A[i] = 3; printf("A[0:2]=%d\t%d\t%d\n",A[0],A[1],A[2]); } 2. C 中动态分配数组中指定子数组 对动态分配的数组,需要显式地指明数组的长度。因为数组是动态分配的,编译器难以确定 数组的上界,从而不能算出默认长度。 int N = 1000; int restrict* p = (int*)malloc(N*sizeof(int)); 如果在数据子语中使用 copy(p)、copy(p[1:])、copy(p[:])等,编译器都会报错,错误信 息类似为 Cannot determine bounds for array p;copy(p[:N/2])无报错。 总结起来,动态分配的数组,可以省略下界,但不能省略长度。 验证小程序 #include 1 int main() 2 { 3 int N = 1000; 4 int restrict* p = (int*)malloc(N*sizeof(int)); 5 int i; 6 7 for(i=0; i 关于书的成语关于读书的排比句社区图书漂流公约怎么写关于读书的小报汉书pdf 面同意,禁止任何形式的商业使用。商业使用形式包括但不限于出版、复制、 传播、展示、引用、编辑。 4. 本文档允许以学术研究、技术交流为目
本文档为【OpenACC编程例子-小小河-20130113】,请使用软件OFFICE或WPS软件打开。作品中的文字与图均可以修改和编辑, 图片更改请在作品中右键图片并更换,文字修改请直接点击文字进行修改,也可以新增和删除文档中的内容。
该文档来自用户分享,如有侵权行为请发邮件ishare@vip.sina.com联系网站客服,我们会及时删除。
[版权声明] 本站所有资料为用户分享产生,若发现您的权利被侵害,请联系客服邮件isharekefu@iask.cn,我们尽快处理。
本作品所展示的图片、画像、字体、音乐的版权可能需版权方额外授权,请谨慎使用。
网站提供的党政主题相关内容(国旗、国徽、党徽..)目的在于配合国家政策宣传,仅限个人学习分享使用,禁止用于任何广告和商用目的。
下载需要: 免费 已有0 人下载
最新资料
资料动态
专题动态
is_727773
暂无简介~
格式:pdf
大小:974KB
软件:PDF阅读器
页数:17
分类:互联网
上传时间:2013-01-13
浏览量:36