私はカーネルをマルチスレッドの「ホスト」プログラムに実装しています。ここでは、すべてのホスト スレッドがカーネルを呼び出しています。定数メモリの使用に問題があります。定数メモリにはいくつかのパラメーターが配置されますが、スレッドごとに異なります。問題が発生するサンプルもビルドします。
これがカーネル
__global__ void Kernel( int *aiOutput, int Length )
{
int id = threadIdx.x + blockIdx.x * blockDim.x;
int iValue = 0;
// bound check
if( id < Length )
{
if( id % 3 == 0 )
iValue = c_iaCoeff[2];
else if( id % 2 == 0 )
iValue = c_iaCoeff[1];
else
iValue = c_iaCoeff[0];
aiOutput[id] = iValue;
}
__syncthreads();
}
そして、pthread がこの関数を呼び出しています。
void* WrapperCopy( void* params )
{
// choose cuda device to perform on
CUDA_CHECK_RETURN( cudaSetDevice( 0 ) );
// cast of params
SParams *_params = (SParams*)params;
// copy coefficients to constant memory
CUDA_CHECK_RETURN( cudaMemcpyToSymbol( c_iaCoeff, _params->h_piCoeff, 3*sizeof(int) ) );
// loop kernel
for( int i=0; i<100; i++ )
{
// perfrom kernel
Kernel<<< BLOCKCOUNT, BLOCKSIZE >>>( _params->d_piArray, _params->iLength );
}
// copy data back from gpu
CUDA_CHECK_RETURN( cudaMemcpy(
_params->h_piArray, _params->d_piArray, BLOCKSIZE*BLOCKCOUNT*sizeof(int), cudaMemcpyDeviceToHost ) );
return NULL;
}
定数メモリはこのように宣言されています。
__constant__ int c_iaCoeff[ 3 ];
ホストスレッドごとに異なる値がh_piCoeff
あり、それを定数メモリにコピーします。
すべての pthread 呼び出しで同じ結果が得られるようになりました c_iaCoeff
。これは、定数メモリがどのように機能するかの問題であり、コンテキストで宣言する必要があると思います。サンプルでは、c_iaCoeff
呼び出しているすべての pthread に対して宣言されているのは 1 つだけで、pthreads によって呼び出されたカーネルは最後の値を取得しますcudaMemcpyToSymbol
。そうですか?
ここで、定数メモリを 2 次元配列に変更しようとしました。2 番目の次元は以前と同じ値になりますが、最初の次元は使用される pthread のインデックスになります。
__constant__ int c_iaCoeff2[ THREADS ][ 3 ];
カーネルでは、このように使用されます。
iValue = c_iaCoeff2[iTId][2];
しかし、この方法で定数メモリを使用できるかどうかはわかりませんね。また、定数メモリにデータをコピーしようとするとエラーが発生しました。
CUDA_CHECK_RETURN( cudaMemcpyToSymbol( c_iaCoeff[_params->iTId], _params->h_piCoeff, 3*sizeof(int) ) );
一般的に、定数メモリを 2 次元配列として使用することは可能ですか? はいの場合、私の失敗はどこにありますか?