私は最初のCUDAアプリケーションを作成しており、練習用にすべてのカーネルを自分で作成しています。
一部では、X_transpose*Xを単純に計算しています。
私はcudaMallocPitchとcudaMemcpy2Dを使用してきましたが、最初にXとX_transpose*X用にデバイスに十分なスペースを割り当てます。Xをデバイスにコピーします。カーネルは、X行列とX_transpose*Xの結果を書き込むためのスペースの2つの入力を受け取ります。
プロファイラーを使用すると、カーネルは元々、サイズ5000x6000のマトリックスで実行するのに104秒かかりました。カーネル内の行列の境界をチェックしないように、ブロックサイズの倍数になるように、ホスト上で行列にゼロを埋め込みます。32x32のブロックサイズを使用します。
グローバルメモリへの合体した読み取り/書き込みを最大化するためにいくつかの変更を加えましたが、これは非常に役立つようです。ビジュアルプロファイラーを使用してコードのリリースビルドをプロファイリングすると、カーネルの実行に4.27秒かかります。
matlabの実行の正確なタイミング(操作X'* X;のみ)を実行していませんが、約3秒のようです。CUDAを使用してmatlabよりもはるかに優れたスピードアップが得られることを望んでいました。
nvidiaビジュアルプロファイラーは私のカーネルの問題を見つけることができません。私はここのコミュニティがそれをより速くする方法についていくつかの提案があるかもしれないことを望んでいました。
カーネルコード:
__global__ void XTXKernel(Matrix X, Matrix XTX) {
//find location in output matrix
int blockRow = blockIdx.y;
int blockCol = blockIdx.x;
int row = threadIdx.y;
int col = threadIdx.x;
Matrix XTXsub = GetSubMatrix(XTX, blockRow, blockCol);
float Cvalue = 0;
for(int m = 0; m < (X.paddedHeight / BLOCK_SIZE); ++m) {
//Get sub-matrix
Matrix Xsub = GetSubMatrix(X, m, blockCol);
Matrix XTsub = GetSubMatrix(X, m, blockRow);
__shared__ float Xs[BLOCK_SIZE][BLOCK_SIZE];
__shared__ float XTs[BLOCK_SIZE][BLOCK_SIZE];
//Xs[row][col] = GetElement(Xsub, row, col);
//XTs[row][col] = GetElement(XTsub, col, row);
Xs[row][col] = *(float*)((char*)Xsub.data + row*Xsub.pitch) + col;
XTs[col][row] = *(float*)((char*)XTsub.data + row*XTsub.pitch) + col;
__syncthreads();
for(int e = 0; e < BLOCK_SIZE; ++e)
Cvalue += Xs[e][row] * XTs[col][e];
__syncthreads();
}
//write the result to the XTX matrix
//SetElement(XTXsub, row, col, Cvalue);
((float *)((char*)XTXsub.data + row*XTX.pitch) + col)[0] = Cvalue;
}
私のマトリックス構造の定義:
struct Matrix {
matrixLocation location;
unsigned int width; //width of matrix(# cols)
unsigned int height; //height of matrix(# rows)
unsigned int paddedWidth; //zero padded width
unsigned int paddedHeight; //zero padded height
float* data; //pointer to linear array of data elements
size_t pitch; //pitch in bytes, the paddedHeight*sizeof(float) for host, device determines own pitch
size_t size; //total number of elements in the matrix
size_t paddedSize; //total number of elements counting zero padding
};
よろしくお願いします。
編集:私は言及するのを忘れました、私はケプラーカード、GTX6704GBで実行しています。