CUDA:如何存储持久数据?

CUDA:如何存储持久数据?,cuda,Cuda,我想在CUDA中的设备上存储背景图像数据。稍后,当我从视频源读取新场景时,我想将新场景作为前景图像发送到GPU,并将其从背景图像中减去。我不希望为每个场景将背景图像重新发送到GPU。如何执行此操作?将背景图像存储在设备内存阵列中(即在GPU上)。然后,在读取前景图像时,使用cudaMemcpy将其复制到另一个设备内存阵列。然后启动一个内核,将两个设备内存数组作为参数,并执行图像减法。应该很简单 假设您使用默认的上下文创建,并且所有这些都在同一个CPU线程中运行,那么您不必像Bart评论的那样担心

我想在CUDA中的设备上存储背景图像数据。稍后,当我从视频源读取新场景时,我想将新场景作为前景图像发送到GPU,并将其从背景图像中减去。我不希望为每个场景将背景图像重新发送到GPU。如何执行此操作?

将背景图像存储在设备内存阵列中(即在GPU上)。然后,在读取前景图像时,使用
cudaMemcpy
将其复制到另一个设备内存阵列。然后启动一个内核,将两个设备内存数组作为参数,并执行图像减法。应该很简单


假设您使用默认的上下文创建,并且所有这些都在同一个CPU线程中运行,那么您不必像Bart评论的那样担心做任何特定的事情来保持CUDA上下文“完整”。但是,如果您执行任何CPU多线程处理,则需要执行一些上下文管理。

将背景图像存储在设备内存阵列中(即在GPU上)。然后,在读取前景图像时,使用
cudaMemcpy
将其复制到另一个设备内存阵列。然后启动一个内核,将两个设备内存数组作为参数,并执行图像减法。应该很简单


假设您使用默认的上下文创建,并且所有这些都在同一个CPU线程中运行,那么您不必像Bart评论的那样担心做任何特定的事情来保持CUDA上下文“完整”。但是,如果要进行任何CPU多线程处理,则需要进行一些上下文管理。

这里是一个简单的示例

int main(int argc, char **argv) {
    uint *hostBackground, *hostForeground; //new uint[]..
    uint *background, *foreground;
首先初始化背景和前景数据

    cudaMalloc(background, ..);
    cudaMalloc(foreground, ..);
然后加载背景数据

    cudaMemCpy(background, hostBackground, ..); //copy to device..
    while (applicationRuns) {
        readImage(hostForeground); //read image..
        cudaMemcpy(foreground, hostForeground, ..); //copy to device

        //operate on foreground..
        substruct_kernel<<<threads, blocks>>>(foreground, background, width, height);

        cudaMemcpy(hostForeground, foreground, ..); //copy to host

        //use hostForeground
    }
然后读取前景数据

    cudaMemCpy(background, hostBackground, ..); //copy to device..
    while (applicationRuns) {
        readImage(hostForeground); //read image..
        cudaMemcpy(foreground, hostForeground, ..); //copy to device

        //operate on foreground..
        substruct_kernel<<<threads, blocks>>>(foreground, background, width, height);

        cudaMemcpy(hostForeground, foreground, ..); //copy to host

        //use hostForeground
    }
下面是一个简单的子结构内核

__global__ void substruct_kernel(uint *foreground, uint *backgroung, int width, int height)
{
    int idx = threadIdx.x + threadDim.x * blockIdx.x;
    int idy = threadIdx.y + threadDim.y * blockIdx.y;

    if (idx < width && idy < height)
       foreground[idx + idy * width] -= background[idx + idy * width]; //clamp may be required..
}
\uuuuu全局\uuuuu无效子结构\u内核(uint*前景、uint*背景、int宽度、int高度)
{
int idx=threadIdx.x+threadDim.x*blockIdx.x;
int-idy=threadIdx.y+threadDim.y*blockIdx.y;
if(idx<宽度和idy<高度)
前景[idx+idy*宽度]-=背景[idx+idy*宽度];//可能需要夹具。。
}

我确实建议使用库来完成这些简单的操作。Blas库或推力库可能是选项。

这里是一个简单的示例

int main(int argc, char **argv) {
    uint *hostBackground, *hostForeground; //new uint[]..
    uint *background, *foreground;
首先初始化背景和前景数据

    cudaMalloc(background, ..);
    cudaMalloc(foreground, ..);
然后加载背景数据

    cudaMemCpy(background, hostBackground, ..); //copy to device..
    while (applicationRuns) {
        readImage(hostForeground); //read image..
        cudaMemcpy(foreground, hostForeground, ..); //copy to device

        //operate on foreground..
        substruct_kernel<<<threads, blocks>>>(foreground, background, width, height);

        cudaMemcpy(hostForeground, foreground, ..); //copy to host

        //use hostForeground
    }
然后读取前景数据

    cudaMemCpy(background, hostBackground, ..); //copy to device..
    while (applicationRuns) {
        readImage(hostForeground); //read image..
        cudaMemcpy(foreground, hostForeground, ..); //copy to device

        //operate on foreground..
        substruct_kernel<<<threads, blocks>>>(foreground, background, width, height);

        cudaMemcpy(hostForeground, foreground, ..); //copy to host

        //use hostForeground
    }
下面是一个简单的子结构内核

__global__ void substruct_kernel(uint *foreground, uint *backgroung, int width, int height)
{
    int idx = threadIdx.x + threadDim.x * blockIdx.x;
    int idy = threadIdx.y + threadDim.y * blockIdx.y;

    if (idx < width && idy < height)
       foreground[idx + idy * width] -= background[idx + idy * width]; //clamp may be required..
}
\uuuuu全局\uuuuu无效子结构\u内核(uint*前景、uint*背景、int宽度、int高度)
{
int idx=threadIdx.x+threadDim.x*blockIdx.x;
int-idy=threadIdx.y+threadDim.y*blockIdx.y;
if(idx<宽度和idy<高度)
前景[idx+idy*宽度]-=背景[idx+idy*宽度];//可能需要夹具。。
}

我确实建议使用库来完成这些简单的操作。Blas库或推力库可能是选项。

感谢您的回复。我正在使用C#接口并将其bing到CUDA dll。我必须存储哪个GPU内存?我最初想存储在常量内存中,但在其他帧中我无法访问它。常量应该可以,但只有当一个块中的所有线程同时访问同一地址时,它才有效。您可能想使用cudamaloc的设备内存,并传递指针,然后在完成后cudaFree它。如果你无法访问另一帧中的常量内存,那么你必须以某种方式破坏每一帧中的上下文,这很糟糕。谢谢你的回复。我正在使用C#接口并将其bing到CUDA dll。我必须存储哪个GPU内存?我最初想存储在常量内存中,但在其他帧中我无法访问它。常量应该可以,但只有当一个块中的所有线程同时访问同一地址时,它才有效。您可能想使用cudamaloc的设备内存,并传递指针,然后在完成后cudaFree它。如果无法访问另一帧中的常量内存,那么必须以某种方式破坏每一帧中的上下文,这是不好的。