可能な限り多くのコンピューティングリソースを利用してスプレーマトリックス*高密度ベクトル乗算のGPUで可能な最大スループットを計算しようとしています。cuSparse反復回数が増えるとスループットが低下する
は、これを達成するために、私は2つの方法を試みた:
をホスト上のXとAのためにメモリを割り当てます。ホストにxとAを格納します。デバイスにxとAのメモリを割り当てます。 xとAをデバイスに保存します。タイマーを開始する。ループ内でcusparsecsrmv経由で疎な行列*密ベクトル乗算を実行し、NUM_ITERATIONS回cusparsecsrmvを実行します。タイマーを停止する。 yをデバイスからホストにコピーし、結果が正しいかどうかを確認します。
ホストにxとAのメモリを割り当てます。ホストにxとAを格納します。デバイス上にxとAの配列(x [NUM_IMPS]、A [NUM_IMPS])のメモリを割り当てます。 XとAをデバイスに保存します。タイマーを開始する。ループ内でcusparsecsrmv経由で疎な行列*密ベクトル乗算を実行し、各A [i] * x [i]でNUM_IMPS回cusparsecsrmvを実行します。タイマーを停止する。 y [NUM_IMPS-1]をデバイスからホストにコピーし、結果が正しいかどうかを確認してください。ここで
は、方法1のために私のコードです:ここでは
// == Start timer for just measuring multiplication ==
QueryPerformanceFrequency(&Frequency1);
QueryPerformanceCounter(&StartingTime1);
// Sparse matrix * dense vector multiplication
/* exercise Level 2 routines (csrmv) */
for (int i = 0; i < NUM_ITERATIONS; i++) {
status = cusparseScsrmv(handle, CUSPARSE_OPERATION_NON_TRANSPOSE, m, n, nnz,
&alpha, descr, cooVal, csrRowPtr, cooColIndex,
&xVal[0], &beta, &y[0]);
}
// == End time for just measuring multiplication ==
QueryPerformanceCounter(&EndingTime1);
ElapsedMicroseconds1.QuadPart = EndingTime1.QuadPart - StartingTime1.QuadPart;
ElapsedMicroseconds1.QuadPart *= 1000000;
ElapsedMicroseconds1.QuadPart /= Frequency1.QuadPart;
は、方法2のために私のコードです:
// == Start timer for just measuring multiplication ==
QueryPerformanceFrequency(&Frequency1);
QueryPerformanceCounter(&StartingTime1);
for (int i = 0; i < NUM_IMPS; i++) {
status = cusparseScsrmv(handle_array[i], CUSPARSE_OPERATION_NON_TRANSPOSE, m, n, nnz,
&alpha, descr_array[i], cooVal_array[i], csrRowPtr_array[i], cooColIndex_array[i],
&xVal_array[i][0], &beta, &y_array[i][0]);
}
// == End time for just measuring multiplication ==
QueryPerformanceCounter(&EndingTime1);
ElapsedMicroseconds1.QuadPart = EndingTime1.QuadPart - StartingTime1.QuadPart;
ElapsedMicroseconds1.QuadPart *= 1000000;
ElapsedMicroseconds1.QuadPart /= Frequency1.QuadPart;
NUM_ITERATIONSまたはNUM_IMPS = 1の場合、それらは同じスループットを得ます。 NUM_IMPS = 10の場合、スループットは最大になります。しかし、NUM_IMPS = 100以上になると、スループットが低下し始めます。 は同様NUM_ITERATIONSでそれが増加し始めるが、私は、超大量にNUM_ITERATIONSを設定したら、これが起こっているのはなぜ10万スループットがNUM_ITERATIONS = 1
のスループットの下にドロップしますと言いますか?私はthorughputがちょうどある時点で飽和し、それ以上には行くことができないと期待しますが、は減少しません。
私の考えは、cusparsecsrmvへの複数回の呼び出しにより、GPUが低速化しているか、GPU自体が低速になるため速度が低下するため、スループットは低下しますが、これらはすべて妥当ではないようです私に結論。
タイミングを測定する正しい方法は何ですか?すべての呼び出しの直後にcudaDeviceSynchronize()コマンドを追加しますか?私はそれを実行し、パフォーマンスは、私が期待したよりもはるかに低かった。 – Veridian
パフォーマンスは「タンク」しませんでした。あなたはちょうどそれを正しく測定し始めました。 – talonmies
だから、私はcudaDeviceSynchronizeを実行する前に何回反復して実行すべきだと思いますか?また、引数なしでcudaDeviceSynchronizeを実行するだけですか? – Veridian