2

次のコードを前提として、thrust(CUDA用のC ++テンプレートライブラリ)を使用して、CUDAで一種のコードディクショナリを生成します。

thrust::device_vector<float> dCodes(codes->begin(), codes->end());
thrust::device_vector<int> dCounts(counts->begin(), counts->end());
thrust::device_vector<int> newCounts(counts->size());

for (int i = 0; i < dCodes.size(); i++) {
    float code = dCodes[i];
    int count = thrust::count(dCodes.begin(), dCodes.end(), code);

    newCounts[i] = dCounts[i] + count;

    //Had we already a count in one of the last runs?
    if (dCounts[i] > 0) {
        newCounts[i]--;
    }

    //Remove
    thrust::detail::normal_iterator<thrust::device_ptr<float> > newEnd = thrust::remove(dCodes.begin()+i+1, dCodes.end(), code);
    int dist = thrust::distance(dCodes.begin(), newEnd);
    dCodes.resize(dist);
    newCounts.resize(dist);
}

codes->resize(dCodes.size());
counts->resize(newCounts.size());

thrust::copy(dCodes.begin(), dCodes.end(), codes->begin());
thrust::copy(newCounts.begin(), newCounts.end(), counts->begin());

問題は、CUDAビジュアルプロファイラーを使用して、4バイトの複数のコピーに気付いたことです。IMOこれはによって生成されます

  1. ループカウンターi
  2. float codeint countdist
  3. iおよび上記の変数へのすべてのアクセス

これはすべてを遅くするようです(4バイトの順次コピーは面白くありません...)。

だから、私は推力をどのように伝えていますか、これらの変数はデバイスで処理される必要がありますか?それとも彼らはすでにですか?

forループがホストで実行されているのかデバイスで実行されているのかわからないため、thrust :: device_ptrを使用するだけでは不十分なようです(これも速度が遅いもう1つの理由である可能性があります)。

4

1 に答える 1

5

iを繰り返すたびに、サイズ、インデックス、コードなどをホストからデバイスにコピーする必要があります。プログラムの方法では、できることはあまりありません。最良の結果を得るには、デバイス上でiループ全体を移動することを検討してください。これにより、ホストからデバイスへのコピーがなくなります。

信頼はいくつかの点で優れていますが、パフォーマンスが懸念され、アルゴリズムが使用可能な関数に完全に適合しない場合は、推力アルゴリズムを明示的に使用せずに最高のパフォーマンスを得るために書き直す必要があります。

于 2010-03-09T03:36:50.377 に答える