【发布时间】:2012-12-12 16:51:08
【问题描述】:
我是 cuda 新手,但遇到了问题。我想对我的线程进行同步,所以我尝试使用同步线程。问题是 Visual Studio 2010 说:标识符 __syncthreads() 未定义...顺便说一句,我正在使用 cuda 4.2。所以我决定改用 cudaDeviceSynchronize() 并从主机调用它。我的代码类似于上面的代码(我只将重要部分发送给您):
__global__ void sum( float avg[]){
avg[0]+=1;
avg[1]+=2;
}
int main(){
float avg[2];
float *devAvg;
cudaError_t cudaStatus;
size_t size=sizeof(unsigned char)*2;
cudaStatus = cudaMalloc((void**)&devAvg, size2);
if (cudaStatus != cudaSuccess) {
fprintf(stderr, "cudaMalloc 2 failed!");
return -1;
}
avg[0]=0;
avg[1]=0;
cudaStatus = cudaMemcpy(devAvg,avg, size, cudaMemcpyHostToDevice);
if (cudaStatus != cudaSuccess) {
fprintf(stderr, "cudaMemcpy failed!");
return -1;
}
dim3 nblocks(40,40);
dim3 nthreads(20,20);
sum<<<nblocks,nthreads,msBytes>>>(devAvg);
cudaStatus = cudaDeviceSynchronize();
if (cudaStatus != cudaSuccess) {
fprintf(stderr, "cudaDeviceSynchronize returned error code %d after launching addKernel!\n", cudaStatus);
}
cudaStatus = cudaMemcpy(avg,devAvg,size,cudaMemcpyDeviceToHost);
if (cudaStatus != cudaSuccess) {
fprintf(stderr, "cudaMemcpy Device to Host failed!");
return -1;}
cout<<"avg[0]="avg[0]<<" avg[1]="<<avg[1]<<endl;
cudaFree devAvg;
return 0;
}
我认为结果应该是 平均[0]=640.000 平均[1]=1.280.000
但不仅我的结果不同(这可能是溢出问题),而且它们并不稳定。例如,对于三种不同的执行,结果是:
平均[0]=3041 平均[1]=6604
平均[0]=3015 平均[1]=6578
平均[0]=3047 平均[1]=6600
那么我在这里做错了什么?是同步问题吗?为什么我不能使用 __syncthreads() 还是竞争条件的问题?
对于 __syncthreads() 问题,我编写的任何代码都附带它。即使是最简单的:
#include "cuda_runtime.h"
#include "device_launch_parameters.h"
#include <stdio.h>
#include <Windows.h>
// Kernel that executes on the CUDA device
__global__ void square_array(float *a, int N)
{
int idx = blockIdx.x * blockDim.x + threadIdx.x;
if (idx<N) a[idx] = a[idx] * a[idx];
__syncthreads();
}
// main routine that executes on the host
int main(void)
{
float *a_h, *a_d; // Pointer to host & device arrays
const int N = 10; // Number of elements in arrays
size_t size = N * sizeof(float);
a_h = (float *)malloc(size); // Allocate array on host
cudaMalloc((void **) &a_d, size); // Allocate array on device
// Initialize host array and copy it to CUDA device
for (int i=0; i<N; i++) a_h[i] = (float)i;
cudaMemcpy(a_d, a_h, size, cudaMemcpyHostToDevice);
// Do calculation on device:
int block_size = 4;
int n_blocks = N/block_size + (N%block_size == 0 ? 0:1);
square_array <<< n_blocks, block_size >>> (a_d, N);
// Retrieve result from device and store it in host array
cudaMemcpy(a_h, a_d, sizeof(float)*N, cudaMemcpyDeviceToHost);
// Print results
for (int i=0; i<N; i++) printf("%d %f\n", i, a_h[i]);
// Cleanup
free(a_h); cudaFree(a_d);
return 0;
}
它是这样说的:错误:标识符“__syncthreads()”未定义
有趣的是,即使使用 4.2 CUDA SDK 附带的示例代码,也会发生同样的事情......也许是更普遍的错误,因为 SDK 示例中有更多被认为未定义的函数。
【问题讨论】:
-
不应该
size=sizeof(float)*2? -
对于
__syncthreads()问题我不知道该说些什么。您添加的代码对我来说编译并运行良好。我认为这表明您的环境有问题。您可能需要仔细遵循windows getting started guide 中的步骤(在首先卸载您拥有的 cuda 版本之后。) -
看起来 __syncthreads() 问题可能是由于 Visual Studio 与您拥有的特定包含文件之间的交互造成的。使用 nvcc(即使在 VS 中)编译 .cu 文件时,通常不需要特别包含
cuda_runtime.h和device_launch_parameters.h(您会注意到我的答案不包含这些)尝试从源文件中删除这些包含语句,然后查看如果你可以编译__syncthreads()