1

CUDA でプログラムを書くのに問題があります。私が実行しているプログラムは、行列とベクトルの乗算を実行し、導入されたベクトルに応じて結果を返す暗号化です。問題は、私は C++ と CUDA の両方で時間をかけており、CUDA よりも C++ の方が良い結果が得られることです。暗号化にはいくつかのキーが必要なため、ループを作成しました。コードは次のとおりです。

t1 = clock();
do {

    HANDLE_ERROR ( cudaMemcpy(MAT_dev, MAT, nBytes, cudaMemcpyHostToDevice) );
    HANDLE_ERROR ( cudaMemcpy(VEC_dev, VEC, nBytes, cudaMemcpyHostToDevice) );

    mult<<< 1, b >>>(MAT_dev, VEC_dev, SOL_dev, b);

    HANDLE_ERROR ( cudaMemcpy(SOL, SOL_dev, nBytes, cudaMemcpyDeviceToHost) );

    for (i = 0; i < b; i++) {
        cout << SOL[i] << " ";
    }
    cout << endl;

    for (i = 0; i < b; i++) {
        VEC[i] = SOL[i];
    }

    cont = cont + 1;

} while (cont < w);
t2 = clock();

私の結果:

C++ : 11.474 分

CUDA : 40.464 分

キーの数は1,000,000でした。Matrix 7 x 7 と Vector 7。

大丈夫なのか、それとも高速化するために何かが足りないのかわかりません。

ご協力いただきありがとうございます。

4

1 に答える 1

3

コードで考えられる問題:

  1. ほとんどの時間cudaMemcpy()cout<<
  2. 速度は、グリッド/ブロック サイズによって制限される場合があります。一般的に言えば、GPU ハードウェアを完全に活用するには、グリッド内の # ブロックを >= # ストリーム プロセスにする必要があります。# ブロック内のスレッドは少なくとも 64 で、常にワープ サイズの倍数でなければなりません。
  3. 行列/ベクトルのサイズが小さすぎて、優れたスケーラビリティを実現できません

可能な解決策:

  1. 1,000,000 m_{7x7} * v_{7} を実行する代わりに、1 m_{7,000,000x7} * v_{7} を実行してみてください。
  2. 1,000,000 cudaMemcpy() を 1 にマージしてみてください。
  3. cudaMallocPitch() を使用して、アラインメントの問題を緩和する小さな行列にメモリを割り当てます。
  4. 行列/ベクトルの要素タイプが double/float の場合は、cublas ライブラリで提供されている cublas_gemv() を使用してみてください

独自のカーネルを作成する前に、CUDA C プログラミング ガイドと C ベスト プラクティス ガイドを読むことをお勧めします。

于 2013-01-08T23:43:28.607 に答える