CUDA atomicAdd跨块添加

CUDA atomicAdd跨块添加,cuda,Cuda,我无法使atomicAdd函数在所有块上工作。下面的内核代码给出了一个块中的线程总数(例如,

我无法使
atomicAdd
函数在所有块上工作。下面的内核代码给出了一个块中的线程总数(例如,
<5000
):

\uuuuu全局\uuuuu无效内核代码(浮点*结果)
{
int index=threadIdx.x+blockIdx.x*blockDim.x;
如果(指数<5000)
{
原子加法(结果,1.0f);
}
}

您能告诉我如何在不分配整个
1.0f
数组的情况下向值添加内容吗?这是因为我在一个资源非常有限的系统上使用此代码-每一位都计数。

此代码可以跨多个块工作,而无需分配
1.0f
数组。
if(index<5000)
语句的目的不是将您限制为单个螺纹块。它旨在确保只有整个网格中的合法线程参与该操作

试着这样做:

#include <iostream>
#define TOTAL_SIZE 100000
#define nTPB 256

#define cudaCheckErrors(msg) \
    do { \
        cudaError_t __err = cudaGetLastError(); \
        if (__err != cudaSuccess) { \
            fprintf(stderr, "Fatal error: %s (%s at %s:%d)\n", \
                msg, cudaGetErrorString(__err), \
                __FILE__, __LINE__); \
            fprintf(stderr, "*** FAILED - ABORTING\n"); \
            exit(1); \
        } \
    } while (0)

__global__ void kernelCode(float *result)
{
    int index = threadIdx.x+blockIdx.x*blockDim.x;
    if (index < TOTAL_SIZE)
    {
        atomicAdd(result, 1.0f);
    }
}

int main(){

  float h_result, *d_result;
  cudaMalloc((void **)&d_result, sizeof(float));
  cudaCheckErrors("cuda malloc fail");
  h_result = 0.0f;
  cudaMemcpy(d_result, &h_result, sizeof(float), cudaMemcpyHostToDevice);
  cudaCheckErrors("cudaMemcpy 1 fail");
  kernelCode<<<(TOTAL_SIZE+nTPB-1)/nTPB, nTPB>>>(d_result);
  cudaDeviceSynchronize();
  cudaCheckErrors("kernel fail");
  cudaMemcpy(&h_result, d_result, sizeof(float), cudaMemcpyDeviceToHost);
  cudaCheckErrors("cudaMemcpy 2 fail");
  std::cout<< "result = " << h_result << std::endl;
  return 0;
}
#包括
#定义总大小为100000
#定义nTPB 256
#定义cudaCheckErrors(msg)\
做{\
cudaError\u t\u err=cudaGetLastError()\
如果(_err!=cudaSuccess){\
fprintf(标准,“致命错误:%s(%s位于%s:%d)\n”\
msg,cudaGetErrorString(_err)\
__文件(行)\
fprintf(stderr,“***失败-中止\n”)\
出口(1)\
} \
}而(0)
__全局无效内核代码(浮点*结果)
{
int index=threadIdx.x+blockIdx.x*blockDim.x;
如果(索引<总大小)
{
原子加法(结果,1.0f);
}
}
int main(){
浮动h_结果,*d_结果;
cudamaloc((void**)和d_结果,sizeof(float));
CUDACHECKERS(“cuda malloc失败”);
h_结果=0.0f;
cudaMemcpy(d_结果和h_结果、sizeof(float)、cudamemcpyhostodevice);
CUDACHECKERS(“cudaMemcpy 1失败”);
核代码(d_结果);
cudaDeviceSynchronize();
cudaCheckErrors(“内核失败”);
cudaMemcpy(&h_结果、d_结果、sizeof(float)、cudamemcpydevicetoost);
cudaCheckErrors(“cudaMemcpy 2失败”);

std::coutYour代码工作正常..看一看..我运行了你的代码,但结果是0,好像内核函数没有改变任何东西…我忽略了正确的设置。可能是你的设置有问题。但是我已经测试了这段代码,并且它在正确设置的机器上正常工作。我现在已经更新了代码,以执行正确设置ame的东西,但包括CUDA错误检查。如果你编译并运行它,你可能会知道什么是错误的。你可能还想尝试在命令提示符下运行
nvidia smi-a
,以了解GPU是否正确安装并可用。嘿,我重新安装了CUDA 5.5,它在VC++中工作,但Mathematica仍然提供了一个res如果TOTAL_SIZE大于此值,则为块中的线程数,此处的情况是因为5000>1024(块中允许的最大线程数)。
#include <iostream>
#define TOTAL_SIZE 100000
#define nTPB 256

#define cudaCheckErrors(msg) \
    do { \
        cudaError_t __err = cudaGetLastError(); \
        if (__err != cudaSuccess) { \
            fprintf(stderr, "Fatal error: %s (%s at %s:%d)\n", \
                msg, cudaGetErrorString(__err), \
                __FILE__, __LINE__); \
            fprintf(stderr, "*** FAILED - ABORTING\n"); \
            exit(1); \
        } \
    } while (0)

__global__ void kernelCode(float *result)
{
    int index = threadIdx.x+blockIdx.x*blockDim.x;
    if (index < TOTAL_SIZE)
    {
        atomicAdd(result, 1.0f);
    }
}

int main(){

  float h_result, *d_result;
  cudaMalloc((void **)&d_result, sizeof(float));
  cudaCheckErrors("cuda malloc fail");
  h_result = 0.0f;
  cudaMemcpy(d_result, &h_result, sizeof(float), cudaMemcpyHostToDevice);
  cudaCheckErrors("cudaMemcpy 1 fail");
  kernelCode<<<(TOTAL_SIZE+nTPB-1)/nTPB, nTPB>>>(d_result);
  cudaDeviceSynchronize();
  cudaCheckErrors("kernel fail");
  cudaMemcpy(&h_result, d_result, sizeof(float), cudaMemcpyDeviceToHost);
  cudaCheckErrors("cudaMemcpy 2 fail");
  std::cout<< "result = " << h_result << std::endl;
  return 0;
}