Fortran OpenMP 并行编程要点总结

总结 Fortran 编写 OpenMP 并行程序的基本要点, 以供后续参考.

Question

  • OpemMP 与 MPI 的区别
  • 什么是 共享内存
  • 如何进行 OpemMP 线程分配
  • 如何调用 OpemMP 接口进行并行计算
  • 如何优化 Cache 管理
  • 如何进行 异构 编程

Introduction

  1. Open Multi-processing
  2. C, C++, Fortran
  3. Version
  4. Framework
    1. Program Layer: OpenMP library
    2. Systeme Layer: OpemMP Runtime library
  5. Heterogeneous 异构 CPU + GPU

Model

  1. Fork-Join Model
    1. Master Thread (initial thread)
    2. Parallerl Worker Thread (Synchronization)
  2. Difference
    1. MPI: Message Passing Interface
    2. OpenMP: Multi-thread
  3. Process vs. Thread
    1. 软件层面与硬件层面的线程含义不同
    2. 软件层面,进程有独立地址空间,一个进程下的线程共享地址空间
    3. 硬件层面,超线程 (hyper-threading) 将单个物理核心 (core) 抽象为多个逻辑核心 (thread), 不同的 core 会共享缓存,由此导致任务分配时的线程亲和性和线程绑定问题

Environment

Install

  • build-essential 会默认安装 OpenMP 4.5(201511)
1
echo | cpp -fopenmp -dM | grep -i open

compile

  1. makefile

-openmp

  1. cmake
1
2
3
4
5
# Find OpemMP
find_package(OpenMP)
add_compile_options(-Wunknown-pragmas)
# link OpenMP
target_link_libraries()

Program

Directive

  1. 制导语句
  2. 线程数设置 (优先级由低到高)
    1. 未设置: 自动获取所有线程数
    2. 环境变量: OMP_NUM_THREADS
    3. 函数定义: omp_set_num_threads(int)
    4. 制导语句从句: num_threads(integer-expression)
    5. if 从句判断串并行

Shared-Variable

  • 共享变量设置
    • 共享变量在内存中只有一份
    • 需确保共享访问不会冲突
    • 并行区变量默认为共享变量
  • 共享访问冲突处理
    • 只读
    • 枷锁
    • 互斥

Private-Variable

  • 私有变量
    • 每个线程单独生成数据对象并分配内存
    • 需重新初始化

Construct

  • 从句
clause Parallerl for Parallerl for
if √\surd √\surd
num_threads √\surd √\surd
default √\surd √\surd
copyin √\surd √\surd
reduction √\surd √\surd √\surd
shared √\surd √\surd √\surd
private √\surd √\surd √\surd
firstprivate √\surd √\surd √\surd
lastprivate √\surd √\surd
schedule √\surd √\surd
ordered √\surd √\surd
collapse √\surd √\surd
nowait √\surd
  • section

  • 同步语义

    • barrier
    • single
    • master
    • critical
    • atomic
  • task

    • 构造任务及依赖关系,动态调度执行
    • 动态管理线程池 (thread pool) 和任务池 (task pool)
  • 向量化

    • 将循环转换为 SIMD 循环

False Sharing

  • cache 命中问题
  • 不同核心对同一 cache line 同时读写会造成冲突,导致该级缓存失效

Heterogeneous (GPU)

Reference

0%