关于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);
}
各种变量作为全局函数的参数传递。我的第二个问题来了。
V[0]
2) 我用 CUDA 中的一个程序和 CPU 上的另一个序列计算了 的值,得到了不同的结果。显然我认为 CUDA 中的问题可能是我没有指定线程,但是,即使这样,结果也没有改变,而且它仍然(很多)比串行的大:6.71201e+22 vs -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;
再次感谢您的关注。