CUDA に関するいくつかの質問。
1) すべてのサンプル コードで、グローバル関数で実行される並列でない操作 (つまり、スカラーの計算) は、常に特定のスレッドを指定して行われることに気付きました。たとえば、次の内積の単純なコードでは、スレッド 0 が合計を実行します。
__global__ void dot( int *a, int *b, int *c )
{
// Shared memory for results of multiplication
__shared__ int temp[N];
temp[threadIdx.x] = a[threadIdx.x] * b[threadIdx.x];
// Thread 0 sums the pairwise products
if( 0 == threadIdx.x )
{
int sum = 0;
for( int i = 0; i < N; i++ )
sum += temp[i];
*c = sum;
}
}
これは私にとっては問題ありません。ただし、私が書いたコードでは、非並列操作のスレッドを指定していませんでしたが、それでも機能します。したがって、スレッドを定義することは必須ですか? 特に、実行したい非並列操作は次のとおりです。
if (epsilon == 1)
{
V[0] = B*(Exp - 1 - b);
}
else
{
V[0] = B*(Exp - 1 + a);
}
さまざまな変数がグローバル関数の引数として渡されました。2 つ目の質問です。
V[0]
2) CUDAのプログラムとCPU上の別のシリアルで値を計算し、異なる結果を得ました。明らかに、CUDAの問題はスレッドを指定しなかったことにあると思いましたが、それでも結果は変わらず、シリアルのものよりも(はるかに)大きいです:6.71201e + 22対-2908.05 . どこに問題があるのでしょうか? グローバル関数で実行されるその他の計算は次のとおりです。
int tid = threadIdx.x;
if ( tid != 0 && tid < N )
{
{Various stuff which does not involve V or the variables used to compute V[0]}
V[tid] = B*(1/(1+alpha[tid]*alpha[tid])*(One_G[tid]*Exp - Cos - alpha[tid]*Sin) + kappa[tid]*Sin);
}
ご覧のとおり、私の状態では、ケースを考慮することを避けていtid == 0
ます。
3) 最後に、最後の質問: 通常、サンプル コードで、GPU メモリ上で割り当てられ、計算された CPU 値を使用する場合は、それらの値を CPU にコピーする必要があることに気付きました (たとえば、 command を使用してcudaMemcpy
、 を指定しcudaMemcpyDeviceToHost
ます) 。 . しかし、これらの値をメイン コード (CPU) で問題なく直接使用することができました。これは、GPU (または CUDA のインストール) に何か問題があるという手がかりになり得ますか?
ご協力ありがとうございました。
== 1月5日追記 ==
返信が遅くなり申し訳ありません。カーネルを呼び出す前に、計算する配列のすべてのメモリ割り当てがあります (これは非常に大量です)。特に、私の質問に含まれる配列に関するコードは次のとおりです。
float * V;
cudaMalloc( (void**)&V, N * sizeof(float) );
私が書いたコードの最後に:
float V_ [N];
cudaMemcpy( &V_, V, N * sizeof(float), cudaMemcpyDeviceToHost );
cudaFree(V);
cout << V_[0] << endl;
ご清聴ありがとうございました。