总结 Fortran 编写 OpenMP 并行程序的基本要点, 以供后续参考.
Question
- OpemMP 与 MPI 的区别
- 什么是 共享内存
- 如何进行 OpemMP 线程分配
- 如何调用 OpemMP 接口进行并行计算
- 如何优化 Cache 管理
- 如何进行 异构 编程
Introduction
- Open Multi-processing
- C, C++, Fortran
- Version
- Framework
- Program Layer: OpenMP library
- Systeme Layer: OpemMP Runtime library
- Heterogeneous 异构 CPU + GPU
Model
- Fork-Join Model
- Master Thread (initial thread)
- Parallerl Worker Thread (Synchronization)
- Difference
- MPI: Message Passing Interface
- OpenMP: Multi-thread
- Process vs. Thread
- 软件层面与硬件层面的线程含义不同
- 软件层面,进程有独立地址空间,一个进程下的线程共享地址空间
- 硬件层面,超线程 (hyper-threading) 将单个物理核心 (core) 抽象为多个逻辑核心 (thread), 不同的 core 会共享缓存,由此导致任务分配时的线程亲和性和线程绑定问题
Environment
Install
build-essential
会默认安装OpenMP 4.5(201511)
1 | echo | cpp -fopenmp -dM | grep -i open |
compile
- makefile
-openmp
- cmake
1 | # Find OpemMP |
Program
Directive
- 制导语句
- 线程数设置 (优先级由低到高)
- 未设置: 自动获取所有线程数
- 环境变量: OMP_NUM_THREADS
- 函数定义: omp_set_num_threads(int)
- 制导语句从句: num_threads(integer-expression)
- if 从句判断串并行
Shared-Variable
- 共享变量设置
- 共享变量在内存中只有一份
- 需确保共享访问不会冲突
- 并行区变量默认为共享变量
- 共享访问冲突处理
- 只读
- 枷锁
- 互斥
Private-Variable
- 私有变量
- 每个线程单独生成数据对象并分配内存
- 需重新初始化
Construct
- 从句
clause | Parallerl | for | Parallerl for |
---|---|---|---|
if | |||
num_threads | |||
default | |||
copyin | |||
reduction | |||
shared | |||
private | |||
firstprivate | |||
lastprivate | |||
schedule | |||
ordered | |||
collapse | |||
nowait |
-
section
-
同步语义
- barrier
- single
- master
- critical
- atomic
-
task
- 构造任务及依赖关系,动态调度执行
- 动态管理线程池 (thread pool) 和任务池 (task pool)
-
向量化
- 将循环转换为 SIMD 循环
False Sharing
- cache 命中问题
- 不同核心对同一 cache line 同时读写会造成冲突,导致该级缓存失效