gpt4 book ai didi

c++ - MPI2/MPI3 : MPI_allgather vs MPI one sided communication considering synchronization

转载 作者:太空宇宙 更新时间:2023-11-04 13:48:23 24 4
gpt4 key购买 nike

我正在使用 MPI-2 编写一个优化程序,其中我需要一个等长的 std::vectorstd::vector(概念上) ,在所有进程之间共享。此 vector 包含针对当前发现的问题的最佳 k 解决方案,并在每次许多 MPI 进程之一找到新的最佳解决方案时更新。每个过程寻找新解决方案所花费的时间通常相差很大。

我的问题是,考虑到同步和等待中的性能问题,我是否应该在每次找到新的最佳解决方案时使用 MPI 集合,例如 MPI_allgather;或者我应该使用 MPI-2 中的单向通信来维护所有进程之间的“共享” vector 。

特别是,如果我使用 MPI_allgather,进程是否会提前空闲并等待与其他进程的某种同步?

我有一些 MPI 点对点通信(更新:以及 UPC)的工作经验,但在实际编码中没有使用过集体或单向通信。我搜索了 SO 并找到了有关 MPI_allgathers 的相关问题/答案,例如Distribute a structure using MPI_Allgather , 以及关于单向通信 Creating a counter that stays synchronized across MPI processes .但是我很难说出这两种方法之间的确切区别。

谢谢,

---更新---

特别是,我在底部有来自 Creating a counter that stays synchronized across MPI processes 的代码示例,它使用单面维护单个 int“共享”。我试图使它适应泛型类型,但不知道如何让它工作,因为我无法理解原始代码以及为什么它维护一个数组 data,以及我如何概括MPI_Accumulate 到用户函数(比如简单地用新 vector 替换旧 vector )。

template//注意:T 只能是原始类型(不能是指针、ref 或 struct),例如 int 和 double。结构 mpi_array { typedef std::vector vector ; MPI_双赢; int hostrank;
内部等级;
整数大小;
vector 值;
vector *hostvals;};


单边通信计数器代码:

#include <mpi.h>
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>

struct mpi_counter_t {
MPI_Win win;
int hostrank ;
int myval;
int *data;
int rank, size;
};

struct mpi_counter_t *create_counter(int hostrank) {
struct mpi_counter_t *count;

count = (struct mpi_counter_t *)malloc(sizeof(struct mpi_counter_t));
count->hostrank = hostrank;
MPI_Comm_rank(MPI_COMM_WORLD, &(count->rank));
MPI_Comm_size(MPI_COMM_WORLD, &(count->size));

if (count->rank == hostrank) {
MPI_Alloc_mem(count->size * sizeof(int), MPI_INFO_NULL, &(count->data));
for (int i=0; i<count->size; i++) count->data[i] = 0;
MPI_Win_create(count->data, count->size * sizeof(int), sizeof(int),
MPI_INFO_NULL, MPI_COMM_WORLD, &(count->win));
} else {
count->data = NULL;
MPI_Win_create(count->data, 0, 1,
MPI_INFO_NULL, MPI_COMM_WORLD, &(count->win));
}
count -> myval = 0;

return count;
}

int increment_counter(struct mpi_counter_t *count, int increment) {
int *vals = (int *)malloc( count->size * sizeof(int) );
int val;

MPI_Win_lock(MPI_LOCK_EXCLUSIVE, count->hostrank, 0, count->win);

for (int i=0; i<count->size; i++) {

if (i == count->rank) {
MPI_Accumulate(&increment, 1, MPI_INT, 0, i, 1, MPI_INT, MPI_SUM,
count->win);
} else {
MPI_Get(&vals[i], 1, MPI_INT, 0, i, 1, MPI_INT, count->win);
}
}

MPI_Win_unlock(0, count->win);
count->myval += increment;

vals[count->rank] = count->myval;
val = 0;
for (int i=0; i<count->size; i++)
val += vals[i];

free(vals);
return val;
}

void delete_counter(struct mpi_counter_t **count) {
if ((*count)->rank == (*count)->hostrank) {
MPI_Free_mem((*count)->data);
}
MPI_Win_free(&((*count)->win));
free((*count));
*count = NULL;

return;
}

void print_counter(struct mpi_counter_t *count) {
if (count->rank == count->hostrank) {
for (int i=0; i<count->size; i++) {
printf("%2d ", count->data[i]);
}
puts("");
}
}

int test1() {
struct mpi_counter_t *c;
int rank;
int result;

c = create_counter(0);

MPI_Comm_rank(MPI_COMM_WORLD, &rank);
result = increment_counter(c, 1);
printf("%d got counter %d\n", rank, result);

MPI_Barrier(MPI_COMM_WORLD);
print_counter(c);
delete_counter(&c);
}


int test2() {
const int WORKITEMS=50;

struct mpi_counter_t *c;
int rank;
int result = 0;

c = create_counter(0);

MPI_Comm_rank(MPI_COMM_WORLD, &rank);
srandom(rank);

while (result < WORKITEMS) {
result = increment_counter(c, 1);
if (result <= WORKITEMS) {
printf("%d working on item %d...\n", rank, result);
sleep(random() % 10);
} else {
printf("%d done\n", rank);
}
}

MPI_Barrier(MPI_COMM_WORLD);
print_counter(c);
delete_counter(&c);
}

int main(int argc, char **argv) {

MPI_Init(&argc, &argv);

test1();
test2();

MPI_Finalize();
}

最佳答案

您担心某些进程可能会先于其他进程进入 MPI_ALLGATHER 是有效的,但在任何具有同步的应用程序中总是如此,而不仅仅是那些明确使用集体通信的应用程序。

但是,您似乎对单边操作的作用有误解。他们不提供并行全局地址空间 (PGAS) 模型,其中所有内容都为您同步。相反,它们只是为您提供了一种直接寻址远程进程内存的方法。每个进程的内存仍然是独立的。此外,如果您要从一个点到另一个点升级到 MPI 的其余部分,我不会将您自己限制在 MPI-2 函数上。 MPI-3 中有一些新内容也改善了集体和单方面(尤其是后者)。

综上所述,如果您除了点对点之外从未使用过任何东西,那么单面对您来说将是一个巨大的飞跃。无论如何,您可能想要进行更多的中间步骤并首先检查 collectives。如果你对自己的表现还是不满意,你可以看一下片面的章节,但它非常复杂,大多数人通常最终会使用一些位于片面之上的东西而不是直接使用它(比如一些 PGAS 语言)。

关于c++ - MPI2/MPI3 : MPI_allgather vs MPI one sided communication considering synchronization,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24700168/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com