3

Cuda GLOBAL メモリについて助けが必要です。私のプロジェクトでは、すべてのカーネル呼び出しでこの配列を送信しないように、グローバル配列を宣言する必要があります。

編集:

私のアプリケーションはカーネルを 1,000 回以上呼び出すことができ、すべての呼び出しで [1000 X 1000] を超えるサイズの配列を彼に送信しているため、より多くの時間がかかっていると思います。それが私のアプリの動作が遅い理由です。だから私はGPUのグローバル配列を宣言する必要があるので、私の質問は

1グローバル配列の宣言方法

2カーネル呼び出し前に CPU からグローバル配列を初期化する方法

前もって感謝します

4

2 に答える 2

6

カーネルにサイズ 1000 x 1000 の配列を送信しているが、グローバル配列を使用してこれを行う方法を知りたいと言っているため、編集された質問は混乱しています。この量のデータをカーネルに送信する方法として私が知っている唯一の方法は、グローバル配列を使用することです。そのため、おそらくグローバル メモリ内の配列を使用して既にこれを行っているでしょう。

それにもかかわらず、グローバル メモリで配列を作成して初期化するには、少なくとも 2 つの方法があります。

1. と を使用して静的に、__device__たとえばcudaMemcpyToSymbol:

 #define SIZE 100
 __device__ int A[SIZE];
 ...
 int main(){
   int myA[SIZE];
   for (int i=0; i< SIZE; i++) myA[i] = 5;
   cudaMemcpyToSymbol(A, myA, SIZE*sizeof(int));
   ...
   (kernel calls, etc.)
 }

(デバイス変数参照cudaMemcpyToSymbol参照)

cudaMalloc2.およびを使用して動的にcudaMemcpy:

 #define SIZE 100
 ...
 int main(){
   int myA[SIZE];
   int *A;
   for (int i=0; i< SIZE; i++) myA[i] = 5;
   cudaMalloc((void **)&A, SIZE*sizeof(int));
   cudaMemcpy(A, myA, SIZE*sizeof(int), cudaMemcpyHostToDevice);
   ...
   (kernel calls, etc.)
 }

( cudaMalloc 参照, cudaMemcpy 参照)

わかりやすくするために、すべての cuda 呼び出しとカーネル呼び出しで実行する必要があるエラー チェックを省略しています。

于 2013-02-24T20:53:24.593 に答える
0

私がこの質問をよく理解していれば、それはちょっと不明確ですが、グローバル配列を使用して、すべてのカーネル呼び出しでデバイスに送信する必要があります。この悪い習慣は、カーネル呼び出しごとにデータをデバイスに転送する必要があるため、レイテンシが高くなります。私の経験では、そのような練習はマイナスのスピードアップにつながりました。

最適な方法は、私がフリップフロップ技術と呼んでいるものを使用することです. あなたがそれを行う方法は次のとおりです。

  1. デバイスで 2 つの配列を宣言します。d_arr1d_arr2
  2. host -> device配列の 1 つにデータをコピーします。
  3. d_arr1とへのポインタをカーネルのパラメータとして渡します。d_arr2
  4. データをカーネルに処理します。
  5. 後続のカーネル呼び出しでは、パラメーターとして渡すポインターを交換します

このようにして、カーネル呼び出しごとにデータを転送することを回避します。ホスト ループの最初と最後にのみ転送します。

int a, even =0;
for(a=0;a<1000;a++)
{
  if (even % 2 ==0 )
   //call to the kernel(pointer_a, pointer_b)
  else
  //call to the kernel(pointer_b, pointer_a)
}
于 2013-02-25T15:55:45.807 に答える