• 并行编程——OPENMP


    和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

  • 相关阅读:
    (转载)构建public APIs与CORS
    SpringMVC 参数注入
    java删除文件夹
    idea 自动提示生成 serialVersionUID
    JSP自定义tag
    gradle中使用嵌入式(embedded) tomcat, debug 启动
    spring in action 4th --- quick start
    Date, TimeZone, MongoDB, java中date的时区问题
    spring boot 添加拦截器
    HTTP status code
  • 原文地址:https://www.cnblogs.com/sickboy/p/2411348.html
Copyright © 2020-2023  润新知