簡體   English   中英

MPI:程序的工作取決於進程數

[英]MPI: program works depending on the number of processes

我編寫了一個使用MPI庫(MPICH-2)的程序。 該程序會找到2到N之間的所有素數。如果我僅使用兩個進程,則可以很好地工作,但是當我指定大於2的進程數時,它就不會工作。 該程序效率很低,因為我的目的是比較使用MPI的程序與不使用MPI的相同程序之間的性能。 我有一台雙核計算機,並且正在Ubuntu 13.10上使用NetBeans 7.4。 問題是否取決於計算機的內核數量? 我知道調度取決於操作系統,但是我不知道該怎么想! 也許我要放置一個MPI_Barrier? 我在下面插入代碼和輸出,因為當我使用2個以上的proc調用程序時,您會看到一些奇怪的零。

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


int count(int *a, int N){
    int b[N];
    int i, j, n_prime;

    for(i=0; i<N; i++)
        b[i] = a[i];

    b[0] = b[1] = 0;
    for (i=2; i<N; i++) {
        b[i] = 1;
        for (j=2; j<i; j++) 
            if (i % j == 0) {
                    b[i] = 0; 
                    break;
            }
        }
    n_prime = 0;
    for (j=2; j<N; j++) 
    if (b[j]) n_prime++;
    return n_prime;
    }

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

    int size, rank, div;
    int N;
    int *array;
    int i, j, k, check, n_prime, n_prime_loc;
    int *sub_array, *prime, *recv_prime, *b, *prime2;
    double t1, t2;


    if(argc != 2){
    printf("Argument error: %s not recognized as argument\n", argv[0]);
    return -1;
    }

    N = atoi(argv[1]);

    MPI_Init(NULL, NULL);

    t1 = MPI_Wtime();

    MPI_Comm_size(MPI_COMM_WORLD, &size);
    MPI_Comm_rank(MPI_COMM_WORLD, &rank);

    div = N/size;       //elements per process

    b = (int*) malloc(sizeof(int)*N);
    if (b == NULL){
        printf("Cannot allocate array 'b'\n");
        return -1;
    }

    n_prime = count(b, N);

    /* Dynamic allocation of the arrays */
    sub_array = (int*) malloc(sizeof(int)*div);
    if (sub_array == NULL){
        printf("Cannot allocate array 'sub_array'\n");
        return -1;
    }
    recv_prime = (int*) malloc(sizeof(int)*n_prime);
    if (recv_prime == NULL){
        printf("Cannot allocate array 'recv_prime'\n");
        return -1;
    }
    array = (int*) malloc(sizeof(int)*N);
    if (array == NULL){
        printf("Cannot allocate array 'array'\n");
        return -1;
    }
    prime = (int*) malloc(sizeof(int)*n_prime);
    if (prime == NULL){
        printf("Cannot allocate array 'prime'\n");
        return -1;
    }

    /* Initialization of the array */
    for (i=0; i<N; i++)       
        array[i] = i+1;
    for(i=0; i<n_prime; i++)
        prime[i] = 0;
    for(i=0; i<n_prime; i++)
        recv_prime[i] = 0;

    /* Process 0 divides the array among the processes */
    MPI_Scatter(array, div, MPI_INT, sub_array, div, MPI_INT, 0, MPI_COMM_WORLD);

    check = 0;      //used to check if we find a divisor
    k=0;

    for(i=0; i<div; i++){
        check = 0;
        if (sub_array[i] == 1) continue;
        for(j=2; j<sub_array[i]; j++){
            if(sub_array[i] % j == 0){
                check = 1;
            }
        }
        if (check == 0){     //if we don't find a divisor, the number is prime
            prime[k] = sub_array[i];
            k++;
        }
    }

    n_prime_loc = 0;

    for(i=0; i<n_prime; i++)
        if(prime[i]!=0)
            n_prime_loc++;

    prime2 = (int*) malloc(sizeof(int)*n_prime_loc);

    j=0;
    for(i=0; i<n_prime; i++){
        if(prime[i]==0) continue;
        prime2[j] = prime[j];
        j++;
    }

    /* Each process sends its computation to the root process */
    MPI_Gather(prime2, n_prime_loc, MPI_INT, recv_prime, n_prime_loc, MPI_INT, 0, MPI_COMM_WORLD);

    MPI_Barrier(MPI_COMM_WORLD);

    if(rank == 0){

        printf("Prime numbers: ");
        for(i=0; i<n_prime; i++)
            printf("%i ", recv_prime[i]);
        printf("\n");
    }

    /* Free the allocated arrays */
    free(b);
    free(array);
    free(recv_prime);
    free(prime);
    free(prime2);
    free(sub_array);

    t2 = MPI_Wtime();
    //printf("Computation time for Process %i: %f\n", rank, t2-t1);

    MPI_Finalize();

    return (EXIT_SUCCESS);
    }

輸出為:

hino@hino-X51L:~/NetBeansProjects/Prime$ mpiexec -np 10 ./Prime 1000
Prime numbers: 2 3 5 7 11 13 17 19 23 29 31 37 41 43 47 53 59 61 67 71 73 79 83 89 97
101 103 107 109 113 127 131 137 139 149 151 157 163 167 173 179 181 191 193 197 199
0 0 0 0 211 223 227 229 233 239 241 251 257 263 269 271 277 281 283 293 307 311 313 
317 331 337 347 349 353 359 367 373 379 383 389 397 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
0 0 401 409 419 421 431 433 439 443 449 457 461 463 467 479 487 491 499 503 509 521 
523 541 547 557 563 569 571 577 587 593 599 450 451 452 601 607 613 617 619 631 641 
643 647 653 659 661 673 677 683 691 701 709 719 727 733 739 743 751 757 761 769 773 
787 797 649 650 485 486 
hino@hino-X51L:~/NetBeansProjects/Prime$ mpiexec -np 2 ./Prime 1000
Prime numbers: 2 3 5 7 11 13 17 19 23 29 31 37 41 43 47 53 59 61 67 71 73 79 83 89 97
 101 103 107 109 113 127 131 137 139 149 151 157 163 167 173 179 181 191 193 197 199 
211 223 227 229 233 239 241 251 257 263 269 271 277 281 283 293 307 311 313 317 331 
337 347 349 353 359 367 373 379 383 389 397 401 409 419 421 431 433 439 443 449 457 
461 463 467 479 487 491 499 503 509 521 523 541 547 557 563 569 571 577 587 593 599 
601 607 613 617 619 631 641 643 647 653 659 661 673 677 683 691 701 709 719 727 733 
739 743 751 757 761 769 773 787 797 809 811 821 823 827 829 839 853 857 859 863 877 
881 883 887 907 911 919 929 937 941 947 953 967 971 977 983 991 997 

快速掃描向我顯示了這里的一些錯誤:

  1. 您需要確保將數字數組平均分配。 例如,如果您將100個數字分配到3個進程中,那么您將得到一些最終不會被MPI_SCATTER正確分配的MPI_SCATTER 不過這不是你的問題。

  2. 您的MPI_GATHER在接收端有問題。 這里的問題是您要從每個進程發送n_prime_loc號,但是每個進程的值也不同。 例如,等級0可能找到10個質數,因此其n_prime_loc值將為10,但是在等級1上,可能會有25個質數(我知道這些示例並不准確,但請堅持下去)。 問題在於,由於等級0是MPI_GATHER操作的根,因此將使用n_prime_loc的值,這意味着如果另一個進程發送的數字更多,則等級0是期望的,那么就會出現問題。 您需要生成一個足夠大的緩沖區,以容納所有可能的結果並適當地收集結果。 或者,您可以選擇不使用MPI_GATHER因為先驗未知緩沖區的大小。 相反,您可以使用MPI_SENDMPI_RECV ,也可以使用MPI_PROBE知道要創建多大的緩沖區。 您可以做任何一件事情。

  3. 您的MPI_BARRIER在這里沒有用。 由於某些原因,當人們不知道在MPI中做什么時,他們會拋出MPI_BARRIER 此功能所做的全部工作是使所有進程都在這一點上等待,直到所有其他進程到達同一點為止。 您已經通過調用MPI_GATHER來完成此操作,因為該調用涉及其他所有進程。

  4. 聽起來您只在一個進程上運行此應用程序。 雖然可以肯定地做到這一點,但實際上並不會獲得太大的提速,也不會比擁有內核快得多。 如果您有一個雙核處理器,並且試圖運行4個進程,那么您將花費大量時間來爭取CPU和上下文切換。 您應該盡量不要使用比核心更多的MPI等級。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM