c++ - 大图像的 CUDA 内存分配问题

标签 c++ cuda

我有一个从图像制作直方图的函数(给出的顺序版本(作业))

CImg< unsigned char > histogramImage = CImg< unsigned char >(BAR_WIDTH * HISTOGRAM_SIZE, HISTOGRAM_SIZE, 1, 1);
unsigned int *histogram;
histogram = (unsigned int *)malloc(HISTOGRAM_SIZE * sizeof(unsigned int));
 memset(reinterpret_cast< void * >(histogram), 0, HISTOGRAM_SIZE * sizeof(unsigned int));

cudaMemset(gpuImage, 0, grayImage.width() * grayImage.height() * sizeof(unsigned char));

cuda_err = cudaMemcpy(gpuImage, grayImage, grayImage.width() * grayImage.height() * sizeof(unsigned char), cudaMemcpyHostToDevice);
if (cuda_err != cudaSuccess)
{
    std::cout << "ERROR: Failed cudaMemcpy" << std::endl;
   return -1;
}

unsigned int *gpuhistogram;
cuda_err = cudaMalloc((void **)(&gpuhistogram), HISTOGRAM_SIZE * sizeof(unsigned int));
if (cuda_err != cudaSuccess)
{
    std::cout << "ERROR: Failed cudaMalloc" << std::endl;
}
cudaMemset (gpuhistogram, 0, HISTOGRAM_SIZE * sizeof(unsigned int));

histogram1D(gpuImage, histogramImage, grayImage.width(), grayImage.height(), gpuhistogram, HISTOGRAM_SIZE, BAR_WIDTH, total, gridSize, blockSize);

cuda_err = cudaMemcpy(histogram, gpuhistogram, HISTOGRAM_SIZE * sizeof(unsigned int), cudaMemcpyDeviceToHost);
if (cuda_err != cudaSuccess)
{
    std::cout << "ERROR: Failed cudaMemcpy" << std::endl;
}

那个电话

void histogram1D(unsigned char *grayImage, unsigned char *histogramImage, const int width, const int height, unsigned int *histogram, const unsigned int HISTOGRAM_SIZE, const unsigned int BAR_WIDTH, NSTimer &timer, dim3 grid_size, dim3 block_size) {

NSTimer kernelTime = NSTimer("kernelTime", false, false);

kernelTime.start();
histo <<< grid_size, block_size >>> (grayImage, histogram,width);
cudaDeviceSynchronize();
kernelTime.stop();

cout << fixed << setprecision(6);
cout << "histogram1D (kernel): \t\t" << kernelTime.getElapsed() << " seconds." << endl;
}

核函数是

__global__ void histo(unsigned char *inputImage, unsigned int *histogram, int width)
{

int x = threadIdx.x + (blockIdx.x * blockDim.x);
int y = threadIdx.y + (blockIdx.y * blockDim.y);

unsigned int index = static_cast< unsigned int >(inputImage[(y * width) + x]);
atomicAdd(&histogram[index],1);
}

我遇到的问题是,当我使用 1024x1024 到 3543x2480 范围内的图像调用它时,它起作用了。但是,我有一张 8192x8192 的图像,当函数返回时,*histogram 中的值仍然为 0。我的试验似乎表明它与 *gpuhistogram 的内存分配有关(不应该 unsigned int 足够大?)因为这个作品的顺序版本。如何解决这个问题?有什么想法吗?

最佳答案

  1. 检查您的卡。来自维基百科:

    技术规范计算能力(版本) 1.0 1.1 1.2 1.3 2.x 3.0 3.5 线程 block 网格的最大维数 2 3 线程 block 网格的最大 x、y 或 z 维度 65535 231-1

  2. 我怀疑您的直方图的性能会比 CPU 代码差,请尝试使用共享内存之类的东西并假设 256 个值。诀窍是每个 block 使用 bin# of threads(每个 block 256 个线程)。我不想破坏作者的收入,所以请参阅 CUDA by Example 2010

关于c++ - 大图像的 CUDA 内存分配问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14642758/

相关文章:

c++ - 带有赋值重载语法的复制构造函数?

c++ - 在 GPU 上使用 CUDA 并行化简单算法

c++ - 将 Nsight 设置为与现有 Makefile 项目一起运行

c++ - 是否可以优雅地在 vector<MyType> 上运行标准算法?

C++ 组合与迭代器

c++ - boost 文字序列化版本(15 vs 18)

cuda for循环疑惑

cuda - 在 NVIDIA GPU 分析中,什么是子分区、扇区和单元?

CUDA:计算能力为1.0的设备的线程 block 限制是多少?

C++ 11x 检查 : how to implement const-variants?