4

このカーネルは正しいことを行っており、正しい結果が得られています。パフォーマンスを向上させたい場合、私の問題は while ループの正確性にあります。ブロックとスレッドの構成をいくつか試しましたが、それらを変更しようとすると、while ループで正しい結果が得られません。カーネルの構成を変更して得た結果は、firstArray と secondArray が完全に埋められないことです (セル内に 0 があります)。両方の配列には、 if ループから取得した curValue を入力する必要があります。

どんなアドバイスも大歓迎です:)

前もって感謝します

#define N 65536

__global__ void whileLoop(int* firstArray_device, int* secondArray_device)
{   
    int curValue = 0;
    int curIndex = 1;

    int i = (threadIdx.x)+2;

    while(i < N) {
        if (i % curIndex == 0) {
            curValue = curValue + curIndex;
            curIndex *= 2;
        }
        firstArray_device[i] = curValue;
        secondArray_device[i] = curValue;
        i += blockDim.x * gridDim.x;
    }
}

int main(){

  firstArray_host[0] = 0;
  firstArray_host[1] = 1;

  secondArray_host[0] = 0;
  secondArray_host[1] = 1;


  // memory allocation + copy on GPU

  // definition number of blocks and threads
  dim3 dimBlock(1, 1);
  dim3 dimGrid(1, 1);

  whileLoop<<<dimGrid, dimBlock>>>(firstArray_device, secondArray_device);

  // copy back to CPU + free memory
}
4

3 に答える 3

4

ここには、意味のある最適化を行うのを妨げるデータ依存性の問題があります。変数 curValue と curIndex は while ループ内で変更され、次の実行にフィード フォワードされます。ループを最適化しようとするとすぐに、変数の状態が異なり、結果が変化する状況が発生します。

あなたが何を達成しようとしているのかはよくわかりませんが、依存関係を避けるために、ループの以前の実行の値に依存しないように while ループを作成してみてください。threadIdx、blockDim、gridDim などの環境状態でインデックスと値が計算されるように、データをスレッドとデータ チャンクに分離してみてください。

また、条件付きループを避けるようにしてください。実行回数が一定の for ループを使用することをお勧めします。これは最適化も容易です。

于 2012-04-12T12:56:02.840 に答える
1

このアルゴリズムを並列化するには、配列内の特定のインデックスの値を直接計算できる式を考え出す必要があります。したがって、配列の範囲内でランダムなインデックスを選択し、その場所の値を決定する要因を検討します。数式を見つけたら、ランダム インデックスの出力値とシリアル アルゴリズムから計算された値を比較してテストします。それが正しければ、スレッドとブロックのインデックスに基づいて一意のインデックスを選択することから始まるカーネルを作成します。次に、そのインデックスの値を計算し、配列内の対応するインデックスに格納します。

些細な例:

シリアル:

__global__ void serial(int* array)
{
  int j(0);
  for (int i(0); i < 1024; ++i) {
    array[i] = j;
    j += 5;
}

int main() {
  dim3 dimBlock(1);
  dim3 dimGrid(1);
  serial<<<dimGrid, dimBlock>>>(array);
}

平行:

__global__ void parallel(int* array)
{
  int i(threadIdx.x + blockDim.x * blockIdx.x);
  int j(i * 5);
  array[i] = j;
}

int main(){
  dim3 dimBlock(256);
  dim3 dimGrid(1024 / 256);
  parallel<<<dimGrid, dimBlock>>>(array);
}
于 2012-04-12T18:13:29.130 に答える