2013-02-08 10 views
0

나는 측정하려고하는 실행 시간이있는 mpi 프로그램이 있습니다. 따라서 gettimeofday에 2 번의 호출을 추가하면 모든 작업이 중단됩니다. 웬일인지, gettimeofday에 대한 두 번째 호출이 있으면 충돌 만 발생합니다. 245gettimeofday가 MPI를 충돌합니까?

여기에 종료 코드로 종료 코드

struct timeval starttime; 
    struct timeval endtime; 

    gettimeofday(&starttime, NULL); 

    int numDarts = 1000000000; 
    int numWorkers = 2; 

    char* args[1]; 
    if(argc >= 2) 
    { 
     numWorkers = atoi(argv[1]); 
    } 
    if(argc >= 3) 
     numDarts = atoi(argv[2]); 

    MPI_Init(&argc, &argv); 
    MPI_Comm_size(MPI_COMM_WORLD, &world_size); 

    printf("world size = %i\n", world_size); 
    if (world_size != 1) 
     printf("Top heavy with management\n"); 

    int numDartsWorker = numDarts/numWorkers; 
    int numDartsMaster = numDarts/numWorkers + (numDarts % numWorkers); //the master computes the leftover 
    args[0] = malloc(256 * sizeof(char)); 
    sprintf(args[0], "%i", numDartsWorker); 
    // printf("argument passing to workers: %s\n", args[0]); 
    /* 
    * Now spawn the workers. Note that there is a run-time determination 
    * of what type of worker to spawn, and presumably this calculation must 
    * be done at run time and cannot be calculated before starting 
    * the program. If everything is known when the application is 
    * first started, it is generally better to start them all at once 
    * in a single MPI_COMM_WORLD. 
    */ 
    // printf("About to call MPI_Comm_spawn with %i workers...\n", numWorkers); 
    int resultLen = 0; 

    //the master counts as a worker, hence the -1 
    MPI_Comm_spawn("piworker", args, numWorkers-1, MPI_INFO_NULL, 0, MPI_COMM_SELF, 
        &everyone, MPI_ERRCODES_IGNORE); 

    double pisum = 0; 
    double myresult = dboard(numDartsMaster); 
    printf("parent result is %.9f\n", myresult); 

    int rc = MPI_Reduce(&myresult, &pisum, 1, MPI_DOUBLE, MPI_SUM, MPI_ROOT, everyone); 

    if (rc != MPI_SUCCESS) 
     printf("failure on mpi_reduce\n"); 

    free(args[0]); 
    /* 
    * Parallel code here. The communicator "everyone" can be used 
    * to communicate with the spawned processes, which have ranks 0,.. 
    * MPI_UNIVERSE_SIZE-1 in the remote group of the intercommunicator 
    * "everyone". 
    */ 
    //receive the results 
    int i=1; 
    MPI_Status status; 

    double avgpi = pisum; 
    avgpi += myresult; //include master's average in the result. 
    avgpi /= numWorkers; 

    printf("startTime = %d secs, %d microsecs\n", starttime.tv_sec); 


// gettimeofday(&endtime, NULL); 

// double totalTime = ((double)endtime.tv_sec + (double)endtime.tv_usec/1000000.0f) - 
//     ((double)starttime.tv_usec + (double)starttime.tv_usec/1000000.0f); 

// printf("Total time: %.8f\n", totalTime); 
    printf("With %i workers, %i darts, estimated value of pi is: %.9f\n", numWorkers, numDarts, avgpi); 

     MPI_Finalize(); 


    return 0; 
} 

에게있다 : task0 : 오류 : N32

MPI 응용 프로그램 순위 0 MPI_Finalize (전에 사망) 신호 (11) 의 srun과 : 여기에 내가받을 메시지입니다 gettimeofday에 대한 두 번째 호출 바로 전에 printf 호출을했습니다. 두 번째 호출이 주석 처리 된 경우 아무것도 출력하지 않으며, 그렇지 않으면 충돌이 발생합니다. 이 예제에서 gettimeofday를 주석 처리했지만, 이는 mpi의 충돌을 일으키는 호출입니다. 주석을 제거하면 언급 한 오류 메시지가 다시 나타나기 시작합니다.

누군가 gettimeofday가이 작업을 수행하는 이유에 대한 통찰력이 있는지 궁금합니다. 코드에서

+0

메모리를 어딘가에 버렸기 때문에이 작업이 수행되며 gettimeofday가 이로 인해 충돌을 유발합니다. gettimeofday가 아닌 버퍼 오버 플로우를 찾는 데 중점을 둡니다. – nos

+0

감사합니다. – NickLokarno

+0

'gettimeofday()'에 대한 주석 처리 된 호출 바로 전에'printf()'를 호출하면 하나의 인수가 누락됩니다. 형식 문자열에 두 개의 '% d'자리 표시자가 있지만 단일 값만 begin 전달됩니다. 이로 인해 스택 손상이 발생할 수 있습니다. MPI는 편리한 MPI_Wtime() 함수를 제공합니다. MPI_Wtime()은 과거의 고정 소수점 이후로 경과 된 시간 (초)의 (상대적으로) 정확한 부동 소수점 값을 반환합니다. –

답변

1

, 이후이

//the master counts as a worker, hence the -1 
MPI_Comm_spawn("piworker", args, numWorkers-1, MPI_INFO_NULL, 0, MPI_COMM_SELF, 
       &everyone, MPI_ERRCODES_IGNORE); 

에서와 스레드 (들)의 산란이며

free(args[0]); 

같이 해제 인수이 예상되어 있습니까? 이 메모리가 없어도 개별 스레드에 영향을 미치지 않을까요?

+0

Nop, 메모리에 영향을주지 않습니다. 이 프로그램은 모든 것을 변경하지 않고 두 번째 gettimeofday() 호출을 주석 처리하여 정상적으로 작동합니다. (필자가 제시 한 예에서봤을 때, 프로그램을 다시 충돌 시키려면 주석을 달았다.) 확실하게, 나는 무료 전화를 끊었다. 그것은 문제를 해결하지 못합니다. – NickLokarno

0

제 질문에 댓글을 달았던 nos 덕분에 솔루션을 찾을 수있었습니다. MPI_Comm_Spawn 호출에 대한 인수 문자열에 쓰기 위해 사용되는 sprintf에 대한 호출을 제거했습니다.이 호출은 작업자에게 사용할 "다트"수를 알려줍니다. 대신 MPI_Send를 사용하여 정보를 보냅니다. 어떻게 든 sprintf는 gettimeofday를 호출하기 전까지는 문제가되지 않았던 것 같습니다.