MPI-3 中的共享内存操作

上一篇中我们介绍了 MPI-3 中增强的单边通信方法,下面我们将介绍 MPI-3 中共享内存操作。

当前硬件的发展趋势是向着多核(众核)的大(共享)内存方向发展,单台计算节点上的核数越来越多,内存也越来越大。在此情况下,共享内存并行编程模式的优势也越来越显著。经常采用的并行编程模式有 POSIX 线程和 OpenMP。MPI-1 和 MPI-2 标准没有提供共享内存机制,各个进程拥有独立的内存空间,在 MPI-1 中某个进程只能通过显式的消息传递来读取或更改其它进程的数据,MPI-2 引进了单边通信的方法,允许某个进程以远端内存访问(RMA)的方式获取或者更新其它进程开放窗口内的数据,但在本质上各个进程之间的内存空间并不共享,各个进程之间不能以一种常规的加载与存储 (load and store) 的方式直接操作其它进程的内存空间,即使这些内存空间可能存在于同一台节点上。各进程间显式的消息传递和远端内存访问操作都可能需要额外的内存复制,从而降低运算性能和增大内存消耗。为了获得更高的运算性能和降低内存消耗,通常会在 MPI 程序中混合共享内存的机制,如 POSIX 线程或 OpenMP 等。这种集成 MPI 和其它外部编程模型的编程方式会增加编程的复杂性,甚至可能会导致死锁,数据丢失或其它错误结果等。

MPI-3 定义了一种共享内存机制,多个进程可以通过一种共享内存窗口将自己的部分内存空间暴露给其它进程。这是一种可移植的共享内存机制,各进程间共享的内存可以由 CPU 通过直接的 load/store 指令进行获取,就像 POSIX 线程和 OpenMP 等其它共享内存机制一样。这就允许我们在一个统一的编程模型下进行通常的 MPI 操作和共享内存操作,避免混合进外部的共享内存编程模型及其所带来的各种问题,降低编程的复杂度,提高程序的可移植性,且容易与已经存在的 MPI 程序集成。

线程,标准 MPI 和 MPI-3 共享内存的内存共享模型分别如下图所示:

线程环境下的完全共享内存
标准 MPI 无共享内存
MPI-3 共享内存

共享内存窗口只能创建在能够共享内存的进程(如处在同一节点上的进程)上,不处在同一个共享内存窗口上的进程之间只能使用标准的 MPI 通信机制,如消息传递或远端内存访问等进行相互之间的数据操作。下图给出这一编程模型的示意图:

节点内共享内存

方法接口

下面给出 MPI-3 共享内存相关方法接口。

MPI.Comm.Split_type(self, int split_type, int key=0, Info info=INFO_NULL)

根据 split_type 将与当前 comm 相关联的组分解为不相交的子组,并为每个子组创建一个相关联的通信子返回。每个组内进程的 rank 按照 key 参数所指定的方式定义,新通信域中各个进程的顺序编号根据 key 的大小决定,即 key 越小,则相应进程在原来通信域中的顺序编号也越小,若两个进程的 key 相同,则根据这两个进程在原来通信域中的顺序号决定新的编号。该方法是一个集合操作,该通信子内的所有进程的 split_type 参数必须都相同或者为 MPI.UNDEFINED,但是可以提供不同的 key 值。指定 split_type 值为 MPI.UNDEFINED 的进程将返回 MPI.COMM_NULL。MPI 标准定义的 split_type 值只有 MPI.COMM_TYPE_SHARED,表示将当前通信子中的进程分解为可以共享内存(比如进程都在在同一台节点上)的子通信子。各 MPI 实现可能会定义额外的 split_type 值。

MPI.Win.Allocate_shared(type cls, Aint size, int disp_unit=1, Info info=INFO_NULL, Intracomm comm=COMM_SELF)

分配指定大小的共享内存并创建和返回用于单边通信的窗口对象。注意调用该方法的通信子包含的所有进程必须能够操作同一块共享内存(比如说所有进程都处在同一台节点上),否则会出错。在组内通信子 comm 所指定的通信子范围内所有进程上执行集合操作。每个进程所返回的窗口对象会包含一块分配好的 size 大小的共享内存(可以被该通信子内的所有进程访问)。每个进程的 size 可以不同,甚至可以为 0。disp_unit 指定在远端内存访问操作中的地址单位,即 origin 所指定的位置在 target 一侧要以 target 进程所指定的 diap_unit 为单位计算。通常如果采用相同类型创建窗口,则统一将 disp_unit 设置成 1 即可。如果有的进程需要以组合数据类型(type)给出缓冲区,则可能需要指定 disp_unit 为 sizeof(type)。info 对象用于为 MPI 环境提供优化所需的辅助信息。默认情况下,各个进程分配的内存会是一块整体的连续内存区。但是如果设置 info 的 key alloc_shared_noncontig 为 "true",则会分配不连续的内存块。

注意:虽然每个进程可以分配不同大小的内存区域,但是为了提高程序的性能,如果要分配连续的共享内存,通常让单个进程分配此完整的连续内存区,其它进程设置 size 为 0,然后将此连续内存(虚拟地)分配给各个进程。

MPI.Win.Shared_query(self, int rank)

该方法查询 rank 为 rank 的进程通过 MPI.Win.Allocate_shared 方法所分配的内存区在当前进程的地址等信息。对内存中的同一块内存区,该方法对不同的进程可能会返回不同的(虚拟)地址。该方法只能由 flavor 为 MPI.WIN_FLAVOR_SHARED 的窗口对象调用,否则会产生 MPI.ERR_RMA_FLAVOR 错误。该方法会返回由内存缓冲区和偏移单位组成的二元 tuple。当 rank 参数设置成 MPI.PROC_NULL 时,会返回分配内存非 0 的 rank 最小的那个进程的内存缓冲区和偏移单位组成的二元 tuple。

例程

下面给出使用例程。

# shm.py

"""
Demonstrates the usage of MPI-3 shared memory operation.

Run this with 4 processes like:
$ mpiexec -n 4 -host node1,node2 python shm.py
"""

import numpy as np
from mpi4py import MPI


comm = MPI.COMM_WORLD
rank = comm.Get_rank()

# split the 4 processes into 2 sub-comms, each can share memory
shm_comm = comm.Split_type(MPI.COMM_TYPE_SHARED)
shm_rank = shm_comm.rank

itemsize = MPI.INT.Get_size()
if shm_rank == 0:
    nbytes = 10 * itemsize
else:
    nbytes = 0

# on rank 0 of shm_comm, create the contiguous shared block
win = MPI.Win.Allocate_shared(nbytes, itemsize, comm=shm_comm)

# create a numpy array whose data points to the shared mem
buf, itemsize = win.Shared_query(MPI.PROC_NULL)
# create a numpy array from buf
buf = np.array(buf, dtype='B', copy=False)
ary = np.ndarray(buffer=buf, dtype='i', shape=(10,))

# in process rank 1 of shm_comm:
# write the numbers 0, 1, 2, 3, 4 to the first 5 elements of the array
if shm_comm.rank == 1:
    ary[:5] = np.arange(5, dtype='i')

# wait in process rank 0 of shm_comm until process 1 has written to the array
shm_comm.Barrier()

# check that the array is actually shared and process 0 can see
# the changes made in the array by process 1 of shm_comm
if shm_comm.rank == 0:
    print ary


# show non-contiguous shared memory allocation
if shm_rank == 0:
    nbytes = 4 * itemsize
else:
    nbytes = 6 * itemsize

info = MPI.Info.Create()
info.Set('alloc_shared_noncontig', 'true')
win = MPI.Win.Allocate_shared(nbytes, itemsize, comm=comm, info=info)
info.Free()

运行结果如下:

$ mpiexec -n 4 -host node1,node2 python shm.py
[0 1 2 3 4 0 0 0 0 0]
[0 1 2 3 4 0 0 0 0 0]

以上介绍了 MPI-3 中共享内存操作,在下一篇中我们将介绍 MPI 中多线程的使用。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 159,117评论 4 362
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,328评论 1 293
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,839评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,007评论 0 206
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,384评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,629评论 1 219
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,880评论 2 313
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,593评论 0 198
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,313评论 1 243
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,575评论 2 246
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,066评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,392评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,052评论 3 236
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,082评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,844评论 0 195
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,662评论 2 274
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,575评论 2 270

推荐阅读更多精彩内容

  • 在上一篇中我们介绍了 MPI-3 中引进的非阻塞通信子复制和组集合通信子创建方法,下面我们将介绍 MPI-3 中增...
    自可乐阅读 3,042评论 0 0
  • 在上一篇中我们简要地介绍了 mpi4py 中的单边通信概念,下面我们将介绍单边通信的相关操作。 创建/释放窗口对象...
    自可乐阅读 1,233评论 0 2
  • 在上一篇中我们介绍了 mpi4py 中的单边通信相关操作,下面我们将介绍单边通信的同步操作。 单边通信(远端内存访...
    自可乐阅读 1,566评论 0 0
  • 假设你很幸运地获得了某个竞争激烈的热门词语的高自然排名,我首先恭喜你。但不要把这个排名视为理所当然,很多不受控制的...
    大米老师阅读 275评论 0 1
  • 居家有妙招 分享1️ 爱家又喜欢亲力亲为的家庭煮妇洗妇们,有没有带橡胶手套做家务因为手出汗,手套和手粘腻在一起,不...
    灿烂jx阅读 1,050评论 1 11