OpenMP 基本使用和critical指令
MPI是可以针对分布式内存,在进程级别实现并行的API;OpenMP则是针对共享内存,在线程级别实现并行的API。
基本使用
不同于MPI的init和finalize,OpenMP用携带了parallel指令的预处理指令指示接下来的一个代码块被多个线程执行。
OpenMP预处理指令(携带)>OpenMP指令(携带)>OpenMP指令的子句。
隐式路障是OpenMP的一个特点,所有执行这个代码块的线程在同一个线程组中以隐式路障隐式同步。
1 #include<stdio.h> 2 #include<stdlib.h> 3 4 //检查是否定义了_OPENMP预处理宏,即编译器是否支持OpenMP 5 #ifdef _OPENMP 6 #include<p.h> //支持时包含OpenMP头文件 7 #endif 8 9 int main(int argc,char *argv[]) 10 //隐式路障:完成代码块的线程要等待其它所有线程完成此代码块 39 printf("路障解除了\n"); 40 return 0; 41 }输出
1 [lzh@hostlzh OpenMP]$ !gcc 2 gcc fopenmp o hello.o hello 3 [lzh@hostlzh OpenMP]$ ./hello.o 4 4 strtol()函数从主函数参数解析得的线程数:4 5 我是0/4 6 我是1/4 7 我是2/4 8 我是3/4 9 路障解除了 10 [lzh@hostlzh OpenMP]$critical指令
OpenMP里变量的作用域可以按照块内是否共享分为共享作用域和私有作用域。对于并行代码块而言,在块前声明的变量缺省作用域是共享的(不过这个”共享”当然不能穿透函数)。
某些地方未使用critical时可能存在的问题
当块内共同操作了共享的资源时,不对其做互斥保护就可能会在运行时出问题。因为只能保证一次汇编级的指令是原子的,甚至不能保证一条C语言语句在并发执行过程中不会发生线程的切换,在并行的情况下就更加危险了:
输出
1 [lzh@hostlzh OpenMP]$ !gcc 2 gcc fopenmp o test1.o test1 3 [lzh@hostlzh OpenMP]$ ./test1.o 15 4 a=5 5 [lzh@hostlzh OpenMP]$ ./test1.o 15 6 a=5 7 [lzh@hostlzh OpenMP]$ ./test1.o 15 8 a=5 9 [lzh@hostlzh OpenMP]$ ./test1.o 15 10 a=5 11 [lzh@hostlzh OpenMP]$ ./test1.o 15 12 a=5 13 [lzh@hostlzh OpenMP]$ ./test1.o 15 14 a=6 15 [lzh@hostlzh OpenMP]$ ./test1.o 15 16 a=5 17 [lzh@hostlzh OpenMP]$ ./test1.o 15 18 a=5才执行了这么几次就发生了出错,可见问题严重。
使用critical时
1 #include<stdio.h> 2 #include<stdlib.h> 3 #include<p.h> 4 5 int main(int argc,char *argv[]) 6 17 printf("a=%d\nb=%d\n",a,b);//最终输出看一下 18 return 0; 19 }输出
1 [lzh@hostlzh OpenMP]$ !gcc 2 gcc fopenmp o test1.o test1 3 [lzh@hostlzh OpenMP]$ ./test1.o 15 4 a=5 5 b=5 6 [lzh@hostlzh OpenMP]$ ./test1.o 15 7 a=5 8 b=5 9 [lzh@hostlzh OpenMP]$ ./test1.o 15 10 a=5 11 b=5 12 [lzh@hostlzh OpenMP]$ ./test1.o 15 13 a=5 14 b=5 15 [lzh@hostlzh OpenMP]$ ./test1.o 15 16 a=5 17 b=5 18 [lzh@hostlzh OpenMP]$ ./test1.o 15 19 a=5 20 b=5 21 [lzh@hostlzh OpenMP]$ ./test1.o 15 22 a=5 23 b=5 24 [lzh@hostlzh OpenMP]$ ./test1.o 15 25 a=5 26 b=5 27 [lzh@hostlzh OpenMP]$ ./test1.o 15 28 a=5 29 b=5 30 [lzh@hostlzh OpenMP]$ ./test1.o 15 31 a=5 32 b=5 33 [lzh@hostlzh OpenMP]$ ./test1.o 15 34 a=5 35 b=5 36 [lzh@hostlzh OpenMP]$ ./test1.o 15 37 a=5 38 b=5 39 [lzh@hostlzh OpenMP]$ ./test1.o 15 40 a=5 41 b=5 42 [lzh@hostlzh OpenMP]$ ./test1.o 15 43 a=5 44 b=6 45 [lzh@hostlzh OpenMP]$ ./test1.o 15 46 a=5 47 b=5 48 [lzh@hostlzh OpenMP]$ ./test1.o 15 49 a=5 50 b=5 51 [lzh@hostlzh OpenMP]$ ./test1.o 15 52 a=5 53 b=5 54 [lzh@hostlzh OpenMP]$可见受critical指令保护的a能够正常执行了,而不受保护的b仍然会发生前面的问题。
上一篇:显微镜的光源
OpenMP
pla文件怎么看,pla文件用什么打开?
pl1文件怎么看,pl1文件用什么打开?
pl文件怎么看,pl文件用什么打开?
pl0文件怎么看,pl0文件用什么打开?
pkt文件怎么看,pkt文件用什么打开?
pkm文件怎么看,pkm文件用什么打开?
pks文件怎么看,pks文件用什么打开?
pka文件怎么看,pka文件用什么打开?
pkh文件怎么看,pkh文件用什么打开?
pkg文件怎么看,pkg文件用什么打开?