zoukankan      html  css  js  c++  java
  • 并行编程——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

  • 相关阅读:
    Rainmeter 雨滴桌面 主题分享
    行人检測之HOG特征(Histograms of Oriented Gradients)
    const和readonly差别
    ADB命令解析
    Java实现 蓝桥杯VIP 算法训练 接水问题
    Java实现 蓝桥杯VIP 算法训练 星际交流
    Java实现 蓝桥杯VIP 算法训练 星际交流
    Java实现 蓝桥杯VIP 算法训练 星际交流
    Java实现 蓝桥杯VIP 算法训练 星际交流
    Java实现 蓝桥杯VIP 算法训练 星际交流
  • 原文地址:https://www.cnblogs.com/sickboy/p/2411348.html
Copyright © 2011-2022 走看看