和MPI支持在分布式内存机器上运行不一样,OPENMP只能在共享内存机器上运行。这一局限性带来的好处就是编程时相对好处理一点。对于天然并行的代码可以不做过多处理就能并行,而MPI则需要消息传递。另外,MPI的消息传递会带来带宽(系统和网络)上的要求,一旦并行节点数增多则会阻塞。这点也是OPENMP的一个优势。

并行开始及结束声明:

Fortran 77/90:
!$OMP PARALLEL
代码区
!$OMP END PARALLEL
C/C++:
#pragma omp parallel
{
代码区
}

某个循环区块的并行

Fortran 77/90:
!$OMP DO [clause ...]
SCHEDULE (type [,chunk])
ORDERED
PRIVATE (list)
FIRSTPRIVATE (list)
LASTPRIVATE (list)
SHARED (list)
REDUCTION (operator | intrinsic : list)
COLLAPSE (n)
do循环
!$OMP END DO [ NOWAIT ]
C/C++:
#pragma omp for [clause ...] newline
schedule (type [,chunk])
ordered
private (list)
firstprivate (list)
lastprivate (list)
shared (list)
reduction (operator: list)
collapse (n)
nowait
for循环

schedule方法里有不同调度模式,一般性对于简单循环,由于任务大小都是一致的,static方法分配就很好。对于任务大小不一致的,可以考虑dynamic或者guided。

另外,在变量访问上有private和shared两种方式,第一种是将变量设置为某个thread独有的,这对于循环变量i,j,k这种是必需的。即使不设定,程序也会自动默认循环变量为private,其他变量为shared方式。

对于fortran来说,还有一个独有的方式叫做workshare

!$OMP WORKSHARE
FORALL statements
FORALL constructs
WHERE statements
WHERE constructs等等
!$OMP END WORKSHARE [ NOWAIT ]

在不能多线程计算的程序代码块,可以用这种方式声明只能有一个thread进行计算

Fortran 77/90:
!$OMP SINGLE [clause ...]
PRIVATE (list)
FIRSTPRIVATE (list)

代码区
!$OMP END SINGLE [ NOWAIT ]
C/C++:
#pragma omp single [clause ...] newline
private (list)
firstprivate (list)
nowait

{代码区}

代码编译的时候,需要加上-openmp(ifort)或者-fopenmp(gfortran),并且需要通过OMP_NUM_THREADS控制线程数目,对于存在大数组的程序,需要ulimit -s unlimited;export OMP_STACKSIZE=200000调大栈大小来消除segment fault (gfortran是GOMP_STACKSIZE,intel fortran是KMP_STACKSIZE)要彻底消除这个问题,可以通过将所有数组改成allocatable放到堆上来解决。

例子

Fortran 77/90:
PROGRAM HELLO
use omp_lib
integer tid
!$OMP PARALLEL PRIVATE(TID)
TID = OMP_GET_THREAD_NUM()
PRINT *, 'Hello World from thread = ', TID
!$OMP END PARALLEL
END
C/C++:
# include <cstdlib>
# include <iostream>
# include <ctime>
# include "omp.h"

using namespace std;

int main ( int argc, char *argv[] );

int main ( int argc, char *argv[] )

{
int this_thread;
#pragma omp parallel private(this_thread)
{
this_thread=omp_get_thread_num();
cout <<this_thread<<" thread is ok\n";
}
return 0;
}



教程

https://computing.llnl.gov/tutorials/openMP/

http://bisqwit.iki.fi/story/howto/openmp/

手册
http://openmp.org/mp-documents/OpenMP3.1-CCard.pdf

http://openmp.org/mp-documents/OpenMP3.1-FortranCard.pdf