3D マトリックスのデータはレイヤーによって (上から下に) 生成され、そのデータに 2D マトリックスBを乗算したいのですが、各レイヤーを取得する代わりに、レイヤー 1 からベクトル、レイヤー 2 からベクトルを取得する必要があります。すぐ。
現在、私が行っているのは、これらのベクトルを 3D マトリックスから 2D マトリックスtmpAにコピーし、(CUBLAS を使用して) Bで乗算し、結果をtmpBに格納して、最終的に行ごとに 3D マトリックスCに対応する場所にコピーすることです。
全体として、私のアプリ全体は CPU バージョンよりも少なくとも 2 倍高速に実行されますが、デバイスからデバイスへのメモリ コピー (であっても) は、パフォーマンスに関してはまったく良くないように思えます。
この計算を行うより良い方法は何でしょうか? メモリのコピーを避けるために、乗算する前にデータを再配置することを考えていました。
3D マトリックスAとCおよび 2D マトリックスBは、既に GPU のメモリに格納されています。
編集
M、N、Pを、デバイスのメモリ上の線形配列に行優先順に格納された 3D 行列Aの次元とします。私のコードは次のようになります。
cudaMalloc((void**)&d_tmpIn, sizeof(float)*M*P);
cudaMalloc((void**)&d_tmpOut, sizeof(float)*M*P);
cudaMalloc((void**)&d_C, sizeof(float)*M*N*P);
for (int iN = 0; iN < N; iN++)
{
dst = d_tmpIn;
for (int iM = 0; iM < M; iM++)
{
cudaMemcpy(dst, &(d_A[iN*P+0+iM*N*P]), sizeof(float)*P, cudaMemcpyD2D);
dst += P;
}
cublasDgemm(cublasHandle, CUBLAS_OP_N, CUBLAS_OP_N, P, M, M, &alpha, d_tmpIn, P, d_B, M, &beta, d_tmpOut, P);
src = d_tmpOut;
for (int iM = 0; iM < M; iM++)
{
cudaMemcpy(&(d_C[iN*P+0+iM*N*P]), src, sizeof(float)*P, cudaMemcpyD2D);
src += P;
}
}
お役に立てれば。