簡體   English   中英

並行乘法矩陣openmp比順序慢

[英]parallel multiply matrix openmp is slower than sequential

我是一個新的OpenMp編程器,現在我遇到了兩個矩陣相乘的問題。 這是我的並行代碼,但是沒有我期望的那么快。 例如,我給它一個3000 * 3000矩陣和3000 * 3000,而我的域是2(隨機數是0或1),並行比順序慢

    clock_t tStart = clock();
    cout<<(char)169<<" parallel "<<(char)170<<endl;
    int a,b,c,Domain ;
    cin>>a>>b>>c>>Domain;
    srand(time(0));
    int **arr1;
    int **arr2;
    int **arrRet;

    arr1 = new int*[a];
    #pragma omp for schedule (dynamic)
    for(int i=0 ; i<a ; i++)
    arr1[i] = new int [b];

    arr2 = new int*[b];
    #pragma omp for schedule (dynamic)
    for(int i=0 ; i<b ; i++)
    arr2[i] = new int [c];

    arrRet = new int*[a];
    #pragma omp for schedule (dynamic)
    for(int i=0 ; i<a ; i++)
    arrRet[i] = new int [c];

    #pragma omp for schedule (dynamic)
    for(int i=0 ; i<a ; i++)
    {
        #pragma omp for schedule (dynamic)
        for(int j=0; j<b ; j++)
        {
        arr1[i][j]=rand()%Domain;
        }
    }

    //cout<<"\n\n\n";
    #pragma omp for schedule (dynamic)
    for(int i=0 ; i<b ; i++)
    {
        #pragma omp for schedule (dynamic)
        for(int j=0 ; j<c ; j++)
        {
        arr2[i][j]=rand()%Domain;
        }
    }

    //cout<<"\n\n\n";
    #pragma omp for schedule (dynamic)
    for(int i=0 ; i<a ; i++)
        #pragma omp for schedule (dynamic)
        for(int j2=0 ; j2<c ; j2++)
        {
            int sum=0;
            #pragma omp parallel for shared(sum) reduction(+:sum)
            for(int j=0 ; j<b ; j++)
            {
                sum+=arr1[i][j]*arr2[j][j2];
            }
            arrRet[i][j2]=sum;
        }
    printf("Time taken : %.4fs\n", (double)(clock() - tStart) / CLOCKS_PER_SEC);

有許多免費的高度優化的線性代數庫 我強烈建議您盡可能使用其中之一。

您的性能下降可能是由許多原因造成的。 以下列表詳細介紹了一些最常見的原因:

  • 當每次迭代的工作量完全平衡時使用schedule(dynamic) 省略該子句會將時間表設置為static ,這更適合於這種並行化類型。

  • 內存分配壓力過大。 您實際上不需要為單個矩陣保留多個存儲區域。 由於矩陣大小在程序中不會改變,因此您可以為每個矩陣完美地使用一個分配。 由於連續的行在內存中彼此靠近,因此這也改善了數據的局部性。 然后,您可以使用A[ i * b + j ]訪問每個元素,其中b是列數。

int *A = (int *) malloc( a * b * sizeof(int) );
  • 在您的代碼中,您似乎錯過了一個parallel區域。 這導致除最后一個之外的所有omp for都不由多個線程執行。

  • 使用collapse(2)omp for合並omp for嵌套循環中的構造,如以下示例所示:

#pragma omp for collapse(2)
for( i = 0; i < a; i++ ) {
   for( j = 0; j < b; j++ ) {
      // your parallel code
   }
}

暫無
暫無

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

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