[并行与分布式程序设计]MPI+Pthreads混合编程 (以及MPI提高内容目录)
其他
2020-06-27 10:07:58
阅读次数: 0
多线程混合编程
MPI 和 线程
- MPI编程中, 每个节点是一个进程, 一个进程中可以存在许多线程
- MPI描述了进程(独立的地址空间)间并行
- 线程并行则是提供了一个进程内的共享内存模型
- 多核集群常见的编程方法
- 纯MPI
- 节点内和跨节点都采用MPI实现进程并行
- 节点内MPI内部是采用共享内存来通信
- MPI + OpenMP
- MPI + Pthreads
- 后两种方式成为混合编程
MPI + Pthreads混合编程
- 在纯MPI编程中, 每个MPI进程由单一程序计数器
- 在MPI + pthreads混合编程中, 可以有多个线程同时执行
- 所有线程共享所有MPI对象 (通信域, 请求, …)
- MPI可能需要采取措施确保MPI栈的状态一致的
MPI四种线程安全级别
- MPI丁磊四级线程安全级别, 这其实是应用程序向MPI做出的承诺
- MPI_THREAD_SINGLE: 应用中只有一个线程
- MPI_THREAD_FUNNELED: 多线程, 但只有主线程会进行MPI调用 (调用MPI_Init_thread的那个线程)
- MPI_THREAD_SERIALIZED: 多线程, 但同一时刻只有一个线程会进行MPI调用
- MPI_THREAD_MULTIPLE: 多线程, 且任何下次呢好难过任何时候都会进行MPI调用(有一些限制避免竞争条件)
- 线程安全级别是递增顺序的
- 如果一个应用工作在FUNNELED模式, 他也工作在SERIALIZED模式
- MPI定义了一个MPI_Init的替代API
- MPI_Init_thread(requested, previded)
- 应用给出他希望的级别, MPI实现返回他支持的级别
MPI_THREAD_SINGLE
MPI_THREAD_FUNNELED
- 因为安全级别递增, 如果返回的安全级别小于目标级别, 则不能使用
MPI_THREAD_SERIALIZED
MPI_THREAD_MULTIPLE
线程和MPI
- 并不要求一个MPI实现支持高于MPI_THREAD_SINGLE的级别: 即, 不要求实现是线程安全的
- 一个完全线程安全的实现会支持 MPI_THREAD_MULTIPLE
- 一个调用MPI_Init ( 而非MPI_Init_thread )的程序应假定实现只支持MPI_THREAD_SINGLE
- 一个未调用MPI_Init_thread的多线程MPI程序是一个错误的程序(很常见的错误)
MPI_THREAD_MULTIPLE规范
- 序: 当多个线程并发调用MPI_API时, 结果就像以某种顺序串行执行调用一样
- 序 是 每个线程内维持的
- 程序员必须确保在相同通信域, 窗口或文件上的组灿做在线程间正确排序
- 例如: 不能在相同通信域上由一个线程调用广播操作, 而同时另一个线程调用归约操作 (因为在MPI中他们都是同一个进程单位)
- 当一个应用内的线程进行冲突的MPI调用时, 程序员应负责防止竞争条件
- 例如: 一个线程访问一个info对象, 儿童诗另一个线程在释放它
- 阻塞: 阻塞MPI调用只会阻塞调用线程, 而不会组织其他线程的运行, 也不会阻止他们调用MPI函数
MPI_THREAD_MULTIPLE中的序: 组通信错误例子
MPI_THREAD_MULTIPLE中的序: RMA错误例子
- RMA: 远程存储访问
- 不同线程可能锁住相同进程, 导致对相同的目标, 在第一个锁解锁之前有多个锁锁住
MPI_THREAD_MULTIPLE 中的序: 对象管理错误例子
MPI_THREAD_MULTIPLE中的阻塞调用: 正确例子
MPI_THREAD_FUNNELED实现Jacobi迭代
一个实际的例子
- 一个非常简单的多线程MPI程序锁死
- 2个进程
- 每个进程2个线程
- 两个线程都与其他进程的线程通信
自定义数据类型, 单边通信, 进程组和通信域, 非阻塞组通信、拓扑、邻居组通信, MPI新标准
- 一些另外的并行编程架构
转载自blog.csdn.net/weixin_40996518/article/details/106529130