Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/68.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C MPI#U屏障不';重新排序printf(stdout)消息似乎不起作用_C_Mpi - Fatal编程技术网

C MPI#U屏障不';重新排序printf(stdout)消息似乎不起作用

C MPI#U屏障不';重新排序printf(stdout)消息似乎不起作用,c,mpi,C,Mpi,下面是一个非常基本的MPI程序 或者类似的事情(问候和道别应该分组,但不能保证过程顺序) 以下是我的实际输出: Hello from 0 Goodbye from 0 Hello 2 from 0 Goodbye 2 from 0 Hello from 1 Goodbye from 1 Hello 2 from 1 Goodbye 2 from 1 我根本上误解了MPI_屏障应该做什么吗?据我所知,如果我只使用一次,那么它会给我预期的结果,但除此之外,它似乎什么也没做 我知道以前有人问过很多

下面是一个非常基本的MPI程序

或者类似的事情(问候和道别应该分组,但不能保证过程顺序)

以下是我的实际输出:

Hello from 0
Goodbye from 0
Hello 2 from 0
Goodbye 2 from 0
Hello from 1
Goodbye from 1
Hello 2 from 1
Goodbye 2 from 1
我根本上误解了MPI_屏障应该做什么吗?据我所知,如果我只使用一次,那么它会给我预期的结果,但除此之外,它似乎什么也没做

我知道以前有人问过很多类似的问题,但我看到的问题中的提问者误解了MPI_屏障的功能

问候和告别应该分组

不应该,在
printf
函数中有额外的(MPI异步)缓冲,另一个缓冲是
stdout
从多个MPI进程收集到单用户终端

printf
只打印到libc(glibc)的内存缓冲区中,有时会刷新到真实的文件描述符(
stdout
;使用
fflush
刷新缓冲区);而
fprintf(stderr,…)
通常比
stdout

远程任务由mpirun/mpiexec启动,通常使用
ssh
remoteshell,它执行
stdout
/
stderr
转发
ssh
(以及TCP)将缓冲数据,并且当来自
ssh
的数据通过mpirun/mpiexec或其他实体(多个数据流被多路复用为一个)显示在终端上时,可以重新排序

您得到的结果就像第一个进程中的4个字符串在其出口处被缓冲和刷新(所有字符串都被打印到
stdout
,通常有几千字节的缓冲区);第二个进程的另外4个字符串也被缓冲,直到退出。所有4个字符串都通过
ssh
或其他启动方法以单个“数据包”的形式发送到您的控制台,您的控制台仅以某种顺序显示4行的两个数据包,即“4行数据包来自\u id\u 0;4行数据包来自\u id\u 1”;或“4行数据包来自\u id\u 1;4行数据包来自\u id\u 0;”

MPI_屏障应该做什么

MPI\u Barrier
同步部分代码,但它不能在libc/glibc打印和文件I/O功能中禁用任何缓冲,也不能在
ssh
或其他远程shell中禁用任何缓冲

如果您的所有进程都在具有同步系统时钟的机器上运行(当您有一台机器时,它们将是,当集群上有
ntpd
时,它们应该是),您可以向每个
printf
添加时间戳字段,以检查实际顺序是否符合您的屏障(
gettimeofday
查找当前时间,并且没有额外的缓冲)。即使
printf
ssh
将对消息重新排序,也可以对时间戳输出进行排序

#include <mpi.h>
#include <sys/time.h>
#include <stdio.h>

void print_timestamped_message(int mpi_rank, char *s);
{
    struct timeval now;
    gettimeofday(&now, NULL);
    printf("[%u.%06u](%d): %s\n", now.tv_sec, now.tv_usec, mpi_rank, s);
}

int main(int argc, char * argv[]) {
    int rank;
    int size;

    MPI_Init(&argc, &argv);
    MPI_Comm_rank(MPI_COMM_WORLD, &rank);
    MPI_Comm_size(MPI_COMM_WORLD, &size);

    MPI_Barrier(MPI_COMM_WORLD);
    print_timestamped_message(rank, "First Hello");
    MPI_Barrier(MPI_COMM_WORLD);
    print_timestamped_message(rank, "First Goodbye");
    MPI_Barrier(MPI_COMM_WORLD);
    print_timestamped_message(rank, "Second Hello");
    MPI_Barrier(MPI_COMM_WORLD);
    print_timestamped_message(rank, "Second Goodbye");
    MPI_Finalize();
    return 0;
}
#包括
#包括
#包括
无效打印时间戳消息(int mpi等级,字符*s);
{
现在构造timeval;
gettimeofday(&now,NULL);
printf(“[%u.%06u](%d):%s\n”,now.tv\u sec,now.tv\u usec,mpi\u rank,s);
}
int main(int argc,char*argv[]){
整数秩;
整数大小;
MPI_Init(&argc,&argv);
MPI通信等级(MPI通信世界和等级);
MPI_通信大小(MPI_通信世界和大小);
MPI_屏障(MPI_通信世界);
打印带有时间戳的消息(排名,“第一你好”);
MPI_屏障(MPI_通信世界);
打印带有时间戳的消息(排名,“第一次再见”);
MPI_屏障(MPI_通信世界);
打印带有时间戳的消息(排名,“第二你好”);
MPI_屏障(MPI_通信世界);
打印带有时间戳的消息(排名,“第二再见”);
MPI_Finalize();
返回0;
}

我认为关于
gettimeofday
的假设在许多分布式系统上都不成立。NTP绝对不够精确。如果您必须进行一些排序,只需在每个屏障上增加一个计数器。祖兰,屏障有多快,在典型集群中NTP有多精确?屏障通常为10-100 us(),NTP在理想条件下有1ms左右()。@Zulan,我想你是对的。我已将我的问题标记为重复。
Hello from 0
Goodbye from 0
Hello 2 from 0
Goodbye 2 from 0
Hello from 1
Goodbye from 1
Hello 2 from 1
Goodbye 2 from 1
#include <mpi.h>
#include <sys/time.h>
#include <stdio.h>

void print_timestamped_message(int mpi_rank, char *s);
{
    struct timeval now;
    gettimeofday(&now, NULL);
    printf("[%u.%06u](%d): %s\n", now.tv_sec, now.tv_usec, mpi_rank, s);
}

int main(int argc, char * argv[]) {
    int rank;
    int size;

    MPI_Init(&argc, &argv);
    MPI_Comm_rank(MPI_COMM_WORLD, &rank);
    MPI_Comm_size(MPI_COMM_WORLD, &size);

    MPI_Barrier(MPI_COMM_WORLD);
    print_timestamped_message(rank, "First Hello");
    MPI_Barrier(MPI_COMM_WORLD);
    print_timestamped_message(rank, "First Goodbye");
    MPI_Barrier(MPI_COMM_WORLD);
    print_timestamped_message(rank, "Second Hello");
    MPI_Barrier(MPI_COMM_WORLD);
    print_timestamped_message(rank, "Second Goodbye");
    MPI_Finalize();
    return 0;
}