Cuda\uuuu同步线程未定义。没有它->;随机结果

Cuda\uuuu同步线程未定义。没有它->;随机结果,cuda,sync,Cuda,Sync,我是cuda的新手,我有个问题。我想对我的线程进行同步,所以我尝试使用syncthreads。问题是VisualStudio2010说:idetifier\uu syncthreads()未定义。。。顺便说一下,我正在使用cuda 4.2。所以我决定改用cudaDeviceSynchronize()并从主机调用它。我的代码与上面类似(我只向您发送重要部分): \uuuuu全局\uuuuuu无效和(浮动平均值[]){ 平均值[0]+=1; 平均值[1]+=2; } int main(){ 浮动平均

我是cuda的新手,我有个问题。我想对我的线程进行同步,所以我尝试使用syncthreads。问题是VisualStudio2010说:idetifier\uu syncthreads()未定义。。。顺便说一下,我正在使用cuda 4.2。所以我决定改用cudaDeviceSynchronize()并从主机调用它。我的代码与上面类似(我只向您发送重要部分):

\uuuuu全局\uuuuuu无效和(浮动平均值[]){
平均值[0]+=1;
平均值[1]+=2;
}
int main(){
浮动平均值[2];
浮动*devAvg;
cudaError\u t cudaStatus;
size\u t size=sizeof(无符号字符)*2;
cudaStatus=cudaMalloc((无效**)和devAvg,尺寸2);
if(cudaStatus!=cudaSuccess){
fprintf(stderr,“cudamaloc 2失败!”);
返回-1;
}
平均值[0]=0;
平均值[1]=0;
cudaStatus=cudaMemcpy(devAvg、avg、size、cudaMemcpyHostToDevice);
if(cudaStatus!=cudaSuccess){
fprintf(stderr,“cudaMemcpy失败!”);
返回-1;
}
dim3 nblocks(40,40);
dim3 n读数(20,20);
总和(德瓦夫);
cudaStatus=cudaDeviceSynchronize();
if(cudaStatus!=cudaSuccess){
fprintf(stderr,“cudaDeviceSynchronize在启动addKernel!\n后返回错误代码%d”,cudaStatus);
}
cudaStatus=cudaMemcpy(平均值、devAvg、大小、cudaMemcpyDeviceToHost);
if(cudaStatus!=cudaSuccess){
fprintf(stderr,“cudaMemcpy设备到主机失败!”);
返回-1;}

cout您的所有线程块都在写入相同的两个位置。使其正常工作的唯一方法是使用原子操作。否则,线程读取位置、添加到位置并“同时”将结果写回位置的结果是未定义的

如果按照以下方式重写内核:

__global__ void sum( float avg[]){
   atomicAdd(&(avg[0]),1);
   atomicAdd(&(avg[1]),2);
}
它应该可以解决您看到的问题

要回答关于uu syncthreads()的问题,我需要查看导致编译器错误的确切代码。如果您发布该错误,我将更新我的答案。在该内核中插入u syncthreads()调用应该不会有问题,尽管它不会修复您看到的问题

您可能希望查看《C编程指南》的一节

请注意,使用原子通常会导致代码运行较慢,因此应谨慎使用。不过,对于本学习练习,它应该为您解决问题

还要注意的是,您发布的代码编译不干净,存在许多缺少定义的问题,以及代码中的各种其他问题。但是,由于您发布了结果,我假设您有一些版本的代码可以工作,即使您没有发布它。因此,我还没有确定您发布的代码的所有问题

这里的代码与您的代码类似,所有各种编码问题都已解决,似乎对我很有用:

#include <stdio.h>
#include <iostream>

#define msBytes 0

__global__ void sum( float avg[]){
  atomicAdd(&(avg[0]),1);
  atomicAdd(&(avg[1]),2);
}
int main(){
  float avg[2];
  float *devAvg;
  cudaError_t cudaStatus;
  size_t size=sizeof(float)*2;
  cudaStatus = cudaMalloc((void**)&devAvg, size);
  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;}
  std::cout<<"avg[0]="<<avg[0]<<" avg[1]="<<avg[1]<<std::endl;
  cudaFree(devAvg);
  return 0;
  }

还要注意的是,要想在
float
上使用
atomicAdd
,必须有一个计算能力2.0或更好的设备(并通过编译器开关,例如
-arch=sm_20
为该类设备进行编译)。如果您有一个更早的设备(计算能力1.x)然后,您可以创建一个类似的程序,将avg[]定义为
int
而不是
float
。或者,如果您愿意,您可以创建自己的atomicAdd ___;设备__;函数,该函数可在cc 1.x设备上使用,如“注意,任何原子操作都可以基于atomicCAS()实现”一节中所建议的那样(比较和交换)。“

所有线程块都在写入相同的两个位置。使其正常工作的唯一方法是使用原子操作。否则,线程“同时”读取位置、添加位置并将结果写回位置的结果是未定义的

如果按照以下方式重写内核:

__global__ void sum( float avg[]){
   atomicAdd(&(avg[0]),1);
   atomicAdd(&(avg[1]),2);
}
它应该可以解决您看到的问题

要回答关于uu syncthreads()的问题,我需要查看导致编译器错误的确切代码。如果您发布该错误,我将更新我的答案。在该内核中插入u syncthreads()调用应该不会有问题,尽管它不会修复您看到的问题

您可能希望查看《C编程指南》的一节

请注意,使用原子通常会导致代码运行较慢,因此应谨慎使用。不过,对于本学习练习,它应该为您解决问题

还要注意的是,您发布的代码编译不干净,存在许多缺少定义的问题,以及代码中的各种其他问题。但是,由于您发布了结果,我假设您有一些版本的代码可以工作,即使您没有发布它。因此,我还没有确定您发布的代码的所有问题

这里的代码与您的代码类似,所有各种编码问题都已解决,似乎对我很有用:

#include <stdio.h>
#include <iostream>

#define msBytes 0

__global__ void sum( float avg[]){
  atomicAdd(&(avg[0]),1);
  atomicAdd(&(avg[1]),2);
}
int main(){
  float avg[2];
  float *devAvg;
  cudaError_t cudaStatus;
  size_t size=sizeof(float)*2;
  cudaStatus = cudaMalloc((void**)&devAvg, size);
  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;}
  std::cout<<"avg[0]="<<avg[0]<<" avg[1]="<<avg[1]<<std::endl;
  cudaFree(devAvg);
  return 0;
  }

还要注意的是,要想在
float
上使用
atomicAdd
,必须有一个计算能力2.0或更好的设备(并通过编译器开关,例如
-arch=sm_20
为该类设备进行编译)。如果您有一个更早的设备(计算能力1.x)然后,您可以创建一个类似的程序,将avg[]定义为
int
而不是
float
。或者,如果您愿意,您可以创建自己的atomicAdd ___;设备__;函数,该函数可在cc 1.x设备上使用,如“注意,任何原子操作都可以基于atomicCAS()实现”一节中所建议的那样(比较和交换)。“

不应该
size=sizeof(float)*2
?我不知道该怎么说
\uuuSyncThreads()
问题。您添加的代码对我来说编译并运行良好。我认为这表明您的环境有问题。您可能希望在(在首次卸载cuda版本后。)看起来_syncthreads()问题可能是由于
avg[0]=640000 avg[1]=1.28e+06