执行模型

NVSHMEM 程序由一组称为 PE 的 NVSHMEM 进程组成。虽然 NVSHMEM 没有要求,但在典型用法中,PE 使用单程序多数据 (SPMD) 模型执行。SPMD 要求每个 PE 使用相同的可执行文件;但是,PE 能够遵循不同的控制路径。PE 使用操作系统进程实现,并且在启用线程支持时,允许 PE 创建额外的线程。

PE 执行是松散耦合的,依赖于 NVSHMEM 操作在执行 PE 之间进行通信和同步。程序中的 NVSHMEM 阶段始于调用初始化例程 nvshmem_initnvshmem_init_thread,必须在使用任何其他 NVSHMEM 库例程之前执行此操作。当所有 PE 调用 nvshmem_finalize 或任何 PE 调用 nvshmem_global_exit 时,NVSHMEM 程序结束其 NVSHMEM 库的使用。nvshmem_finalize 调用期间,NVSHMEM 库必须完成所有挂起的通信,并使用跨 PE 的隐式集合同步释放所有与库关联的资源。在初始化之前或 nvshmem_finalize 之后调用任何 NVSHMEM 例程都会导致未定义的行为。在最终确定之后,后续的初始化调用也会导致未定义的行为。

NVSHMEM 程序的 PE 由唯一的整数标识。标识符是以单调递增的方式从零分配到小于 PE 总数的整数。PE 标识符用于 NVSHMEM 调用(例如,指定对称数据对象上的 putget 例程,集合同步调用)或使用 C 构造来指示 PE 的控制流。标识符在程序的 NVSHMEM 阶段期间是固定的。

NVSHMEM 操作的进度

NVSHMEM 模型假设计算和通信自然重叠。NVSHMEM 程序应展示通信的进展,无论是否使用 NVSHMEM 调用。考虑一个 PE 正在进行没有 NVSHMEM 调用的计算。其他 PE 应该能够与该计算绑定 PE 进行通信(例如,putgetatomic 等)并完成通信操作,而无需该 PE 发出任何显式的 NVSHMEM 调用。涉及该 PE 的单边 NVSHMEM 通信调用应进行,而无需考虑该 PE 何时下一次参与 NVSHMEM 调用。

调用 NVSHMEM 操作

指向非 const 数据的 NVSHMEM 例程的指针参数不得与同一 NVSHMEM 操作的其他参数在内存中重叠,除非是第 NVSHMEM_REDUCTIONS 节中描述的原位归约。否则,行为是未定义的。如果任何数据元素包含在相同的物理内存位置,则两个参数在内存中重叠。例如,考虑由 nvshmem_ptr 操作为 PE \(i\) 上的对称对象 \(A\) 返回的地址 \(a\)。将本地地址 \(a\) 和对象 \(A\) 的对称地址提供给以 PE \(i\) 为目标的 NVSHMEM 操作会导致未定义的行为。

提供给 NVSHMEM 例程的缓冲区正在使用,直到调用 PE 上的相应 NVSHMEM 操作完成。对正在使用的缓冲区的更新(包括通过本地和远程发出的 NVSHMEM 操作执行的更新)会导致未定义的行为。同样,仅当缓冲区作为 const 限定的参数提供给正在使用的 NVSHMEM 例程时,才允许从正在使用的缓冲区读取。否则,行为是未定义的。对于 AMO 正在使用的缓冲区,如第 原子性保证 节中所述,则有例外。有关 NVSHMEM 操作完成的信息,请参阅第 内存排序 节。

具有多个对称对象参数的 NVSHMEM 例程不要求这些对称对象位于同一对称内存段中。例如,位于对称数据段中的对象和位于对称堆中的对象可以作为参数提供给相同的 NVSHMEM 操作。