CUDA 一维数组未更新

Posted

技术标签:

【中文标题】CUDA 一维数组未更新【英文标题】:CUDA 1-D array not getting updated 【发布时间】:2013-05-03 09:36:55 【问题描述】:

这是我第一次尝试 CUDA 程序。这是它应该做的:

    从主机内存接收一维像素数组 每个像素由一个线程处理:它是线程安全的,因为只读取“val”并且只更新“newval”。等待同步。 每个像素由一个线程处理:将“newval”复制到“val”。 将此数组写回主机内存。 对几个不同的帧重复 2-4。

然而,在新数组中,大约 32000 个变量中只有几个变量似乎具有不错的值。其余为零。

为简洁起见,我删除了计算。

__global__ void kernel(Pixel *array, float dt)

    const unsigned int tid = threadIdx.x;
    Pixel *point = array + tid;
    //DO A BUNCH OF CALCULATIONS ON PIXEL KIND OF LIKE THIS
    point->newval = point->val + foo;


__global__ void copykernel(Pixel *array)

    const unsigned int tid = threadIdx.x;
    Pixel *point = array + tid;
    //COPY THE NEWVALS OVER TO THE OLD VALS IN PREPARATION FOR THE NEXT FRAME
    point->val = point->newval;


extern "C" bool runIt(const int argc, const char **argv, Pixel *inarray, Pixel **outarrays, int arraysize, int numframes, float dt)

    int memsize = arraysize*sizeof(Pixel);
    int i=0;

    Pixel *array;
    cudaMalloc((void **) &array, memsize);
    cudaMemcpy(array, inarray, memsize, cudaMemcpyHostToDevice);

    int numthreads = arraysize;
    dim3 grid(1,1,1);
    dim3 threads(numthreads,1,1);

    for(i=0;i<numframes;i++)
    
        kernel<<<grid, threads>>>((Pixel *) array, dt);
        cudaThreadSynchronize();
        copykernel<<<grid, threads>>>((Pixel *) array);
        cudaThreadSynchronize();
        cudaMemcpy(array, outarrays[i], memsize, cudaMemcpyDeviceToHost);
    
    cudaFree(array);
    return true;

我怀疑我为设备设置的参数不正确,或者我将某个设备特定的关键字弄错了,或者忘记了关键步骤。有什么让你跳出来的吗?

【问题讨论】:

【参考方案1】:

我不认为你可以运行那么多线程,如果可以的话,这不是一个好主意。尝试将线程数设置为 256(2D 为 16x16),然后根据您的输入大小选择网格大小。

dim3 threads(256,1,1);
dim3 grid(arraysize/threads.x,1,1); //Careful of integer division, this is just for example

您的第二份副本也不正确。需要切换arrayout_arrays

cudaMemcpy(outarrays[i], array, memsize, cudaMemcpyDeviceToHost);

【讨论】:

哦。我应该抓住那个有缺陷的 cudaMemcpy ......当然,这就是问题所在。谢谢。现在,关于线程......这个数字没有给我带来问题;你能解释为什么这是个问题吗?最后,在运行第二个内核之前,我需要等待所有线程完成。那么,我可以将它们组合起来,然后在两者之间添加一个 cudaThreadSynchronize 吗? 弗兰克,你当然也应该修复线程,让我看看能不能为你找到这篇文章...... ***.com/questions/4391162/… 对于你的双内核,我猜如果你正在做一些事情,其中​​多个块可能需要相同的 old_val,那么你需要两个内核。但是如果一个像素在整个算法中只被触摸一次,则不需要两次开销。一个错误的例子是图像扭曲算法,它可以对源像素进行多次采样。 对...这不会显示,因为我删除了一大块代码,但像素引用了相邻像素的值(这是一个有限差分大气模型)。但是,如果我将第二个内核中的代码放入第一个内核中,并在中间添加一个 cudaThreadSynchronize 会起作用吗?

以上是关于CUDA 一维数组未更新的主要内容,如果未能解决你的问题,请参考以下文章

CUDA 中的一维最小卷积

一维树状数组区间更新区间查询

c语言定义一维数组,元素未初始化,那数组元素默认值是啥

[JavaScript 刷题] 数组 - 一维数组的动态和, leetcode 1480

Java 数组 之 一维数组 插入排序算法

采用一维数组输出等腰三角形的杨辉三角