c++ - 应用程序缓冲区和系统缓冲区有什么区别

标签 c++ parallel-processing buffer mpi

许多MPI教程中有一些术语含义模糊,例如“Application Buffer”和“System Buffer”。我不明白他们之间的区别。我也想知道他们在哪里?我认为应用程序缓冲区是接收或发送节点内部的内存。那么如果是,系统缓冲区是什么?

最佳答案

在 MPI 的上下文中,应用程序缓冲区(通常称为 用户缓冲区)是保存要发送的信息或要接收信息的地方的缓冲区。应用程序缓冲区是传递给 MPI 通信调用的内容,例如

MPI_Send(buf, len, type, ...);
//       ^^^
//    app. buffer

一旦 MPI_Send 被调用,就会构造一条消息,并根据各种标准通过互连发送,互连可以是任何类型的连接机制,例如 InfiniBand、Internet 套接字、共享内存,等,实际传输可能涉及许多中间步骤,或在内部缓冲以供以后传输。 内部缓冲区(也称为系统缓冲区)是 MPI 运行时系统的一部分并由其管理,并且对应用程序代码不可见。系统缓冲区不一定是在内核或应用程序空间之外的其他地方分配的。相反,对于许多 MPI 实现和互连,这些缓冲区在程序地址空间中分配并计入程序内存使用量。

也可以通过 MPI_Bsend 调用或其非阻塞变体 MPI_Ibsend 使用显式分配的中间缓冲区。它要求用户首先分配一个缓冲区,然后通过调用 MPI_Buffer_attach 将其交给 MPI 运行时。从那一刻起,这个缓冲区的内容就完全由 MPI 运行时系统管理。

应用程序和系统缓冲区之间的区别对于操作完成 的概念很重要。当 MPI 不再需要访问应用程序缓冲区时,MPI 操作被视为完成。例如:

buf[] = some content;
MPI_Send(buf, len, ...);
// once MPI_Send returns, the buffer can be reused
buf[0] = 1;
MPI_Send(buf, 1, ...);

对于非阻塞调用,操作在后台继续,必须小心不要在异步操作完成之前修改应用程序缓冲区:

MPI_Request req;
buf[] = some content;
MPI_Isend(buf, len, ...,  &req);
buf[0] = 1;                  // DATA RACE: buf might still be in use by
MPI_Send(buf, 1, ...);       // the operation initiated by MPI_Isend

在这种情况下正确使用 buf 应该是这样的:

MPI_Request req;
buf[] = some content;
MPI_Isend(buf, len, ...,  &req);
// Do something that does not involve changing buf
// ...
// ...
// Make sure the operation is complete before continuing
MPI_Wait(&req, MPI_STATUS_IGNORE);
// buf is now free for reuse
buf[0] = 1;
MPI_Send(buf, 1, ...);

关于c++ - 应用程序缓冲区和系统缓冲区有什么区别,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27008373/

相关文章:

c# - 在 UI 线程中从 c++ 回调到 vb6

C++ 为特定模板特化添加重载方法

C++ - 无法将 istringstream 定义移出循环

从缓冲区到 JSON 的 Javascript

C++ 数组编译时错误

swift - 使用 GCD 并行处理数组

Bash:子进程访问变量

c# - 将两个并行任务的结果合并到一个列表中

c++ - 使用 fstream tellg 读取流的一部分直到结束

java - Node 缓冲区打印问题