-1

質問のタイトルは混乱しているように聞こえるかもしれませんが、実際には..そうです!

この行を実行するプログラムがあります

new_matrix = matrix1 + matrix2 + CPU_GIVE_ME_A_MATRIX();

「+」演算子はオーバーロードされており、単純なマトリックス クラスを作成してコードの読み取りを簡素化しました。

    myMatrixClass operator+ (const myMatrixClass& mt)
{

    myMatrixClass result(this->rows, this->columns);
    // Sum each couple of values
    for(int i=0; i<rows; i++)
    {
        for(int j=0; j<columns; j++)
            result.values[i*columns+j] = this->values[i*columns+j] + mt.values[i*columns+j];
    }
    return result;
}

CUDAで第3項を計算するプログラムの別のバージョンがあります

new_matrix = matrix1 + matrix2 + GPU_GIVE_ME_A_MATRIX();

少しプロファイリングした後、次のことがわかりました。

GPU_GIVE_ME_A_MATRIX() 関数全体が CPU_GIVE_ME_A_MATRIX() 関数 (メモリ転送を含む) よりも高速であるため、CUDA はその仕事をしました..

しかし、行 new_matrix = matrix1 + matrix2 + CPU_GIVE_ME_A_MATRIX(); new_matrix = matrix1 + matrix2 + GPU_GIVE_ME_A_MATRIX(); よりも高速です。

この奇妙な動作の原因は何ですか? CPUキャッシュ何か?

この行は数回実行されるため (レンダリングに必要です)、CUDA プログラム全体は CPU バージョンよりも遅くなりますが、GPU_GIVE_ME_A_MATRIX() 関数は CPU_GIVE_ME_A_FUNCTION() 関数よりも高速です。

4

1 に答える 1

1

CPU バージョンは、結果の行列を CPU キャッシュに入れます (または、少なくともそうすることができます) が、GPU バージョンの結果は、システム メモリから読み込む必要があります。これはほとんどの場合に望ましいことですが (デバイスからホストへの転送ごとに CPU キャッシュを汚染したくありません)、このデータの CPU 読み取り (少なくとも最初の 1 回目) は、データがホストで計算された場合よりも遅くなることを意味します。 -側。

一般に、メモリをできるだけ長くデバイスに保持し、転送するメモリをできるだけ少なくすることをお勧めします。この場合、GPU に十分な作業が与えられていないように思えます。おそらく、単一の行列を計算するよりも大きなタスクを GPU に与えることができますか?

于 2012-04-14T21:47:49.937 に答える