Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/63.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.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时,接收速度要慢得多_C_Multithreading_Mpi_Hpc - Fatal编程技术网

C 在子线程而不是父线程中调用MPI时,接收速度要慢得多

C 在子线程而不是父线程中调用MPI时,接收速度要慢得多,c,multithreading,mpi,hpc,C,Multithreading,Mpi,Hpc,在下面的代码中,我尝试接收具有两个活动线程的MPI消息。将0作为命令行参数传递,父线程将使用MPI_Recv,子线程将发送它。传递1将导致子级使用MPI_Recv,父级发送。随着消息的大小变得越来越大,我看到两种情况下的时间有很大的不同。你知道为什么会这样吗 #include <stdio.h> #include <mpi.h> #include <time.h> #include <unistd.h> #include <sys/time.

在下面的代码中,我尝试接收具有两个活动线程的MPI消息。将0作为命令行参数传递,父线程将使用MPI_Recv,子线程将发送它。传递1将导致子级使用MPI_Recv,父级发送。随着消息的大小变得越来越大,我看到两种情况下的时间有很大的不同。你知道为什么会这样吗

#include <stdio.h>
#include <mpi.h>
#include <time.h>
#include <unistd.h>
#include <sys/time.h>
#include <stdlib.h>
#include <pthread.h>
pthread_t _comm_thread;
#define KILO 1024
#define MILLION 1000000
#define START_TIMER(timer) { gettimeofday(&(timer), NULL); }

#define STOP_TIMER(timer) { gettimeofday(&(timer), NULL); }
#define TIME_DIFF(timer1, timer2, total) { \
  long long sec_diff = 0; \
  long long usec_diff = 0; \
  sec_diff = (timer2).tv_sec - (timer1).tv_sec; \
  usec_diff = (timer2).tv_usec - (timer1).tv_usec; \
  (total) += (sec_diff * MILLION) + usec_diff; \
}
short done_flag = 0;
short finished = 0;
int num_messages = 500;
int payload_sizes[] = {1, 2, 4 , 8, 16,32,64,128,256,512,1024,2*KILO,4*KILO,8*KILO,16*KILO,32*KILO,64*KILO,128*KILO,256*KILO,512*KILO,KILO*KILO};
// int payload_sizes[] = {KILO*KILO};
int num_payload_sizes = 21;
int loops=0;

void* receive(void* args){

    int my_proc;
    MPI_Comm_rank(MPI_COMM_WORLD,&my_proc);
    long long total;
    struct timeval start, stop;

    if( my_proc==0 ){

        int i;
        char buffer [KILO*KILO];    
        for(i=0;i<num_payload_sizes;++i)
        {
            done_flag = 0;
            total = 0;
            int j;
            START_TIMER(start)
            for(j=0;j<num_messages;++j)
            {
                MPI_Send(buffer,payload_sizes[i],MPI_BYTE,1,0,MPI_COMM_WORLD);      
            }
            STOP_TIMER(stop)
            TIME_DIFF(start,stop,total)
            printf("Payload size: %d : time : %lld usec\n",payload_sizes[i],(total)/num_messages);
        }

    }
    else{

    int cnt=0;
    char* buffer;

    while(1){

        MPI_Status stat;
        int size;
        MPI_Probe(MPI_ANY_SOURCE,MPI_ANY_TAG,MPI_COMM_WORLD,&stat); 
        MPI_Get_count(&stat,MPI_BYTE,&size);
        buffer = (char *)malloc(size);
        MPI_Recv(buffer,size,MPI_BYTE,0,0,MPI_COMM_WORLD,MPI_STATUS_IGNORE);        
        cnt++;
        if(cnt == num_messages){
            loops++;
            cnt =0;
        }
        if(loops == num_payload_sizes){
            free(buffer);
            break;      
        }
        free(buffer);
        }
    }
    pthread_exit(0);
}

void * nothing(void *args){

    pthread_exit(0);

}

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

    int provided;
    if(argc != 2){
        printf("Please pass as argument 0 to run the MPI_Recv in parent or 1 to run it in the child\n");
        return -1;
    }

    int choice = atoi(argv[1]);
    MPI_Init_thread( NULL, NULL, MPI_THREAD_SERIALIZED,&provided);
    if( provided!= MPI_THREAD_SERIALIZED){
        printf("MPI_THREAD_SERIALIZED is not provided\n");
        return -1;
    }
    if( choice == 0){

        pthread_create( &_comm_thread, NULL, nothing, NULL);
        receive(NULL);
    }else if(choice == 1){

        pthread_create( &_comm_thread, NULL, receive, NULL);
    }else{ 
        printf("Must choose 0 or 1\n");
        return -1;
    }

    pthread_join(_comm_thread,NULL);
    MPI_Finalize();

    return 0;
}
#包括
#包括
#包括
#包括
#包括
#包括
#包括
pthread_t_comm_线程;
#定义千1024
#定义百万1000000
#定义开始计时器(计时器){gettimeofday(&(计时器),NULL);}
#定义停止计时器(计时器){gettimeofday(&(计时器),NULL);}
#定义时间差(计时器1、计时器2、总计){\
长-长秒之差=0\
长-长usec_diff=0\
秒差=(timer2.tv秒-(timer1.tv秒)\
usec_diff=(timer2).tv_usec-(timer1).tv_usec\
(总额)+=(百万分之二)+usec\
}
short-done_标志=0;
短完成=0;
int num_消息=500;
int payload_size[]={1,2,4,8,16,32,641282565121024,2*KILO,4*KILO,8*KILO,16*KILO,32*KILO,64*KILO,128*KILO,256*KILO,512*KILO,KILO*KILO};
//int payload_size[]={KILO*KILO};
int num_payload_size=21;
int循环=0;
作废*接收(作废*参数){
int my_proc;
MPI通信等级(MPI通信世界和我的进程);
长总;
结构timeval启动、停止;
if(my_proc==0){
int i;
字符缓冲区[KILO*KILO];

对于(i=0;这不是一般的MPI问题,而是特定于给定实现的性能问题。您运行的是哪个库(供应商和版本)?这个问题不清楚。查看一些数字会很有用。这里有大约成千上万个关于并行程序计时的问题,因此基本的错误度量(在这个问题中不明显)或错误理解(在这个问题中不明显缺席)会导致回答与你的错误测量/误解大致相同。。。