0

routine次のコードは、OpenACC 2.0 のディレクティブを使用してデバイスでコンパイルされた、アクセラレータでの単純なルーチンの呼び出しを示しています。

#include <iostream>

#pragma acc routine
int function(int *ARRAY,int multiplier){
        int sum=0;

        #pragma acc loop reduction(+:sum)
        for(int i=0; i<10; ++i){
                sum+=multiplier*ARRAY[i];
        }

        return sum;
}

int main(){
        int *ARRAY = new int[10];
        int multiplier = 5;
        int out;

        for(int i=0; i<10; i++){
                ARRAY[i] = 1;
        }

        #pragma acc enter data create(out) copyin(ARRAY[0:10],multiplier)

        #pragma acc parallel present(out,ARRAY[0:10],multiplier)
        if (function(ARRAY,multiplier) == 50){
                out = 1;
        }else{
                out = 0;
        }

        #pragma acc exit data copyout(out) delete(ARRAY[0:10],multiplier)

        std::cout << out << std::endl;
}

functionのデバイス コピーを使用する方法ARRAY[0:10]multiplier、並列領域内から呼び出されるタイミングを知るにはどうすればよいでしょうか? デバイス コピーの使用を強制するにはどうすればよいですか?

4

3 に答える 3

1

ルーチンがデバイス領域 (parallelコード内) 内で呼び出されると、デバイス上のスレッドによって呼び出されます。つまり、これらのスレッドはデバイス上の配列にしかアクセスできません。コンパイラは実際にその関数をインライン化することを選択するか、デバイス側の関数呼び出しである可能性があります。これは、関数がデバイスから呼び出されたときに、データのデバイス コピーを受け取ることを知ることができることを意味します。これは、関数が本質的presentに並列領域からデータ句を継承しているためです。関数内で一度デバイス上で実行していることを自分自身に納得させたい場合は、 を呼び出すことができますがacc_on_device、それはデバイス ポインターを受け取ったことではなく、アクセラレータ上で実行していることを伝えるだけです。

それ以上のデバイスコピーの使用を強制したい場合はnohost、ホストからの呼び出しが技術的に無効になるようにルーチンを作成できますが、それは実際にはあなたが求めていることを行いません。配列が実際にデバイス配列であることを GPU でチェックします。

ただし、 の内部にない並列領域内のコードはギャング冗長loop実行されることに注意してください。そのため、1 つのギャングで実行している場合や.outatomic

于 2015-08-10T20:41:15.233 に答える
0

関数には、ギャング/ワーカー/ベクターなどの 1 つの並列処理レベルを割り当てる必要があります。より正確な方法です。

ルーチンは、デバイス メモリ内の日付を使用します。

于 2015-04-07T05:50:55.130 に答える