0

文字ベクトルとして提供される 2 つの大きな数を乗算するプログラムがあります。ここで、OpenMP が使用されていることを確認する必要があります。入れ子になったループに問題があります。それらを使用すると、期待した結果が得られません。大変お世話になりました。これがコードです

#include<stdio.h>
#include<math.h>
#include<stdlib.h>
#include<string.h>
#include<omp.h>
#include<time.h>
#define MAX 100000

char * multiply(char [],char[], int manyThreads);
int main(){   
    //omp_set_dynamic(1);
    omp_set_nested(1);
    omp_set_num_threads(8);
    char a[MAX];
    char b[MAX];
    char *c;    

    printf("First number : ");
    scanf("%s",a);
    printf("Second number : ");
    scanf("%s",b);
    printf("Result : ");
    double start = omp_get_wtime( );

    c = multiply(a,b,1);
    printf("%s\n",c);
    double end = omp_get_wtime( );
    printf("Calculation time = %.16g\n", end - start);

    return 0;
}

char * multiply(char a[],char b[], int manyThreads){
    static char result[MAX];
    char tempResult[MAX];
    char temp[MAX];
    int aLength,bLength;
    int i,j,k=0,x=0,y;
    long int r=0;
    long sum = 0;
    aLength=strlen(a)-1;
    bLength=strlen(b)-1;

    #pragma omp parallel if(manyThreads == 1)
    {
        #pragma omp for schedule(dynamic) nowait
        for(i=0;i<=aLength;i++) 
        {
            a[i] = a[i] - 48;
        }

        #pragma omp for schedule(dynamic) nowait
        for(i=0;i<=bLength;i++) 
        {
            b[i] = b[i] - 48;
        }
    }

    #pragma omp parallel if(manyThreads == 1) 
    {       
        #pragma omp for schedule(dynamic) 
        for(i=bLength;i>=0;i--) 
        {
             r=0;

             #pragma omp parallel
             {
               #pragma omp for schedule(dynamic)
               for(j=aLength;j>=0;j--) 
               {
                  temp[k++] = (b[i]*a[j] + r)%10;
                 r = (b[i]*a[j]+r)/10;
               }
             }
             temp[k++] = r;
             x++;
             #pragma omp parallel
             {
               #pragma omp for schedule(dynamic)            
               for(y = 0;y<x;y++)
               {
                  temp[k++] = 0;
               }    
             }                   
        }
    }  

    k=0;
    r=0;
    #pragma omp parallel if(manyThreads == 1)
    {
        #pragma omp for schedule(dynamic) 
        for(i=0;i<aLength+bLength+2;i++)
        {
             sum =0;
             y=0;
             #pragma omp parallel
             {
               #pragma omp for schedule(dynamic)
               for(j=1;j<=bLength+1;j++)
               {
                  if(i <= aLength+j)
                  {
                      sum = sum + temp[y+i];
                  }
                  y += j + aLength + 1;
               }
             }

             tempResult[k++] = (sum+r) %10;
             r = (sum+r)/10;            
        }
    }
    tempResult[k] = r;
    j=0;

    #pragma omp parallel if(manyThreads == 1)
    {
        #pragma omp for schedule(dynamic) 
        for(i=k-1;i>=0;i--)
        {
             result[j++]=tempResult[i] + 48;
        }
    }

    result[j]='\0';

    if(result[0]==48)
    {
        result[0]=255;
    }

    return result;
}
4

1 に答える 1

2

データ競合エラーがあることを確認できます。
OpenMP を使用しない場合:

First number : 123456
Second number : 654321
Result :  08563613376
Calculation time = 0.005543371655221563

OpenMP の場合:

First number : 123456
Second number : 654321
Result :  00000000825
Calculation time = 0.007188999978097854

そして、私は問題全体を解決するわけではありませんが、私が見たものに基づいて、いくつかの発言があります. まず、 for 構造で変数
指定する必要があると思いますfor

#pragma omp for schedule(dynamic) nowait
        for(int i=0;i<=aLength;i++) 
        {
            a[i] = a[i] - 48;
        }

そして、あなたが(毎回)犯した主なエラーの例...並列領域に入るときは、変数を処理する必要があります。何が共有され、何が各スレッドのプライベートなのか? エンドループでは使用しませんが、各スレッドでnested parallelisma を実行するj++ため、以下のように j を保護する必要があります。

#pragma omp parallel if(manyThreads == 1) shared(j) 
    {
        int pos;
#pragma omp for schedule(dynamic) 
        for(int i=k-1;i>=0;i--)
        {
#pragma omp atomic capture
            pos = j++;

            result[pos]=(tempResult[i] + 48);
        }
    }

forOpenMPコンストラクトにreduction句があることも忘れていることに注意してください。

したがって、計算する for ループは次のsum += temp[y+i]ように書き換えることができます

#pragma omp for schedule(dynamic) reduction(+:sum)

また、すべてのアルゴリズム ロジックに従って、周囲およびネストされた領域のそれぞれでsharedand句を使用する必要があります。privateparallel

于 2013-08-19T12:33:57.587 に答える