1

ベクトルと行列のクラスを並列化する作業を行っていますが、問題が発生しました。の形でループがあるときはいつでも

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

コードにはデータ依存性があり、並列化されません。Intelコンパイラを使用する場合、プラグマなしでこれを処理するのに十分スマートです(これに似た膨大な数のループと、実際にはこれよりも複雑なケースのため、依存関係チェックなしのプラグマを避けたいと思います。存在する場合に備えて確認したいと思います)。

これを許可する PGI コンパイラのコンパイラ フラグを知っている人はいますか?

ありがとうございました、

ジャスティン

編集: for ループでエラーが発生しました。実際のループをコピーして貼り付けていませんでした

4

1 に答える 1

1

問題は、これらのルーチンでキーワードを使用していないことだと思います。restrictそのため、C コンパイラはポインターのエイリアスについて心配する必要があります。

このプログラムのコンパイル:

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

void dbpa(double *b, double *a, const int n) {
    for (int i = 0; i < n; i++) b[i] += a[i] ;

    return;
}

void dbpa_restrict(double *restrict b, double *restrict a, const int n) {
    for (int i = 0; i < n; i++) b[i] += a[i] ;

    return;
}

int main(int argc, char **argv) {
    const int n=10000;
    double *a = malloc(n*sizeof(double));
    double *b = malloc(n*sizeof(double));

    for (int i=0; i<n; i++) {
        a[i] = 1;
        b[i] = 2;
    }

    dbpa(b, a, n);
    double error = 0.;
    for (int i=0; i<n; i++)
        error += (3 - b[i]);

    if (error < 0.1)
        printf("Success\n");

    dbpa_restrict(b, a, n);
    error = 0.;
    for (int i=0; i<n; i++)
        error += (4 - b[i]);

    if (error < 0.1)
        printf("Success\n");

    free(b);
    free(a);
    return 0;
}

PGI コンパイラで:

$ pgcc  -o tryautop tryautop.c -Mconcur -Mvect -Minfo
dbpa:
      5, Loop not vectorized: data dependency
dbpa_restrict:
     11, Parallel code generated with block distribution for inner loop if trip count is greater than or equal to 100
main:
     21, Loop not vectorized: data dependency
     28, Loop not parallelized: may not be beneficial
     36, Loop not parallelized: may not be beneficial

dbpa()restrict キーワードのないルーチンは並列化されていませんが、ルーチンは並列化されているという情報が得られdbpa_restict()ます。

ただし、実際には、この種のものについては、コンパイラに自動並列化するよう説得するよりも、OpenMP (または TBB や ABB など) を使用する方がよいでしょう。おそらく、実行している内容に応じて、既存の線形代数パッケージを高密度または疎のいずれかで使用する方がよいでしょう。

于 2013-08-14T18:47:00.273 に答える