1

私はOpenclプログラミングが初めてです。opencl をよりよく学習するために、いくつかのチュートリアルを読んだ後、単純なパターン マッチング カーネル関数の開発を開始しました。しかし、私はいくつかの疑問があります:

まず、カーネル関数内でグローバル変数を宣言しました。すべての作業項目が各変数の 1 つのコピーを共有するということですか?

次に、標準の C ライブラリ、特に使用方法を教えてください。「文字列.h」。

   __kernel void matchPatterns_V1(__global char *strings, __global char *patterns, __global int *matchCount,
                            int strCount, int strLength, int patCount, int patLength) {


    int id = get_global_id(0);
    int rowIndex = id*strLength;
    int i, matches = 0;     

    __global char *pos = strings;
    __global char *temp = strings;
    __global char *pat = patterns;

    for(i = 0; i < patCount; i++)
    {
            temp = &strings[rowIndex];      
            pat = &patterns[i*patLength];
            while(pos != '\0') {
                    pos = StrStr(temp, pat);
                    if(pos != '\0') {
                            matches++;
                            temp = pos + patLength;
                    }
            }
    }
    matchCount[id] = matches;
    }

要約すると、各作業項目には、変数「pos」、「temp」、および「pat」の独自のコピーがありますか?

最高の書籍やチュートリアル サイトの提案など、Opencl の学習に関するアドバイスは大歓迎です。

4

1 に答える 1

5

いいえ、グローバルメモリスペースにあるため、通常、カーネル呼び出しごとに1つのコピーがあり、すべての作業項目で共有されます。各ワークグループがグローバルメモリに独自の「アイテム」を持っていることを保証できない場合、またはより一般的には、カーネル内の2つのワークアイテムがメモリ内の同じ場所に同時に書き込むことがない場合、グローバルメモリへの書き込みは危険です)競合状態になるからです。

もちろん、これらのグローバルメモリ変数からデータを読み取るだけの場合は問題ありません。

また、カーネル引数にしかなり得ないため、カーネル内で変数を宣言することもできません。そうしようとすると、OpenCLコンパイラから次のようになります。__global

error: global variables cannot be allocated inside kernel code

正当な理由で、技術的な不可能性を除けば、グローバル変数はまったく目的を果たさないでしょう...私が考えることができる唯一の理由は、非常識なデザインパターンである作業項目間の通信です。


あなたの質問については、コメントで、OpenCL仕様のセクション6.5のこのスニペットを参照してください:

// declares a pointer p in the __private address space that
// points to an int object in address space __global
__global int *p;

したがって、ポインタタイプに関連付けられたメモリ空間は、ポインタ自体ではなく、ポインタが指す変数のメモリ空間を表します。ポインタ自体は常に__private(つまり、作業項目ごとに)存在します。


OpenCLの標準Cライブラリの文字列操作関数は使用できませんが、必要に応じてGPUで使用できるように再コーディングできます(ほとんどの関数は実装が難しくありません)。

于 2013-02-08T09:26:36.597 に答える