【问题标题】:CUDA atomicAdd across blocksCUDA atomicAdd 跨块
【发布时间】:2013-09-26 11:50:24
【问题描述】:

我无法让atomicAdd 函数作用于所有块。事实证明,下面的内核代码给了我一个块中的线程总数(例如< 5000):

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

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

【问题讨论】:

标签: cuda


【解决方案1】:

此代码可以跨多个块工作,而无需分配 1.0f 数组。 if (index &lt; 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;
}

您可以将TOTAL_SIZE 更改为任何适合float 的数字

请注意,我在浏览器中输入了这段代码,可能有印刷错误。

【讨论】:

  • 我跑了你的代码,结果结果是0,好像内核函数什么都没变……
  • 我遗漏了正确的cuda error checking。可能您的设置有问题。但是我已经测试了这段代码,它可以在正确设置的机器上正常工作。我现在更新了代码来做同样的事情,但包括 CUDA 错误检查。如果您编译并运行它,您可能会知道哪里出了问题。您可能还想尝试在命令提示符下运行 nvidia-smi -a 以了解 GPU 是否已正确安装且可用。
  • 嘿,我重新安装了 CUDA 5.5,它在 VC++ 中工作,但是,如果说 TOTAL_SIZE 大于这个数字,Mathematica 会给出一个块中的线程数,这是因为 5000> 1024(一个块中允许的最大线程数)。
猜你喜欢
  • 2016-07-24
  • 2022-12-11
  • 2013-05-30
  • 1970-01-01
  • 2013-06-22
  • 2016-09-30
  • 1970-01-01
  • 1970-01-01
  • 2021-08-12
相关资源
最近更新 更多