gpt4 book ai didi

opengl - CUDA OPENGL 互操作性 : slow mapping

转载 作者:行者123 更新时间:2023-12-04 03:33:59 25 4
gpt4 key购买 nike

我的应用程序将从 openGL 获取渲染结果(深度图和渲染的 2D 图像信息)到 CUDA 进行处理。

我做的一种方法是通过 glReadPixel(..., image_array_HOST/depth_array_Host)* 检索图像/深度图,然后将 image_HOST/depth_HOST 传递给 CUDA通过 cudaMemcpy(...,cudaMemcpyHostToDevice)。这部分我已经完成了,虽然听起来有些多余。 (从 GPU>CPU>GPU)。*image_array_HOST/depth_array_Host 是我在主机上定义的数组。

另一种方法是使用 openGL<>cuda interpol。第一步是在 openGL 中创建一个缓冲区,然后将图像/深度信息传递到该像素缓冲区。还注册了一个 cuda token 并将其链接到该缓冲区。然后将 CUDA 上的矩阵链接到该 cuda token 。(据我所知,似乎没有直接的方法将像素缓冲区链接到 cuda 矩阵,应该有一个 openGL 可以识别的 cudatoken。如果我错了,请纠正我。)

这部分我也做过。它认为它应该相当有效,因为 CUDA 正在处理的数据是没有转移到任何地方,而只是转移到它在 openGL 上的位置。它是设备(GPU)内部的数据处理。

然而,我从第二种方法得到的花费时间甚至(略)长于第一种方法(GPU>CPU>GPU)。这让我很困惑。

我不确定我是否遗漏了任何部分,或者我没有以有效的方式做到这一点。

我也不确定的一件事是 glReadPixel(...,*data)。在我的理解中,如果 *data 是一个链接到 HOST 上内存的指针,那么它将执行从 GPU > CPU 传输的数据。如果*data=0,并且绑定(bind)了一个缓冲区,那么数据将被传输到那个缓冲区,这应该是GPU>GPU的事情。

也许其他一些方法可以比 glReadPixel(..,0) 更有效地传递数据。

希望有人能解释我的问题。

以下是我的代码:

--

// openGL has finished its rendering, and the data are all save in the openGL. It is ready to go.
...


// declare one pointer and memory location on cuda for later use.
float *depth_map_Device;
cudaMalloc((void**) &depth_map_Device, sizeof(float) * size);


// inititate cuda<>openGL
cudaGLSetGLDevice(0);


// generate a buffer, and link the cuda token to it -- buffer <>cuda token
GLuint gl_pbo;
cudaGraphicsResource_t cudaToken;
size_t data_size = sizeof(float)*number_data; // number_data is defined beforehand
void *data = malloc(data_size);
glGenBuffers(1, &gl_pbo);
glBindBuffer(GL_ARRAY_BUFFER, gl_pbo);
glBufferData(GL_ARRAY_BUFFER, size, data, GL_DYNAMIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, 0);
cudaGraphicsGLRegisterBuffer(&cudaToken, gl_pbo, cudaGraphicsMapFlagsNone); // now there is a link between gl_buffer and cudaResource
free(data);

// now it start to map(link) the data on buffer to cuda
glBindBuffer(GL_PIXEL_PACK_BUFFER, gl_pbo);
glReadPixels(0, 0, width, height, GL_RED, GL_FLOAT, 0);
// map the rendered data to buffer, since it is glReadPixels(..,0), it should be still fast? (GPU>GPU)
// width & height are defined beforehand. It can be GL_DEPTH_COMPONENT or others as well, just an example here.
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, gl_pbo);
cudaGraphicsMapResources(1, &cudaToken, 0); // let cufaResource which has a link to gl_buffer to the the current CUDA windows
cudaGraphicsResourceGetMappedPointer((void **)&depth_map_Device, &data_size, cudaToken); // transfer data
cudaGraphicsUnmapResources(1, &cudaToken, 0); // unmap it, for the next round

// CUDA kernel
my_kernel <<<block_number, thread_number>>> (...,depth_map_Device,...);

最佳答案

我想我现在可以部分地回答我的问题,希望它对某些人有用。

我将 pbo 绑定(bind)到 float cuda (GPU) 内存,但似乎 openGL 原始图像渲染数据是 unsigned char 格式,(以下是我的假设)所以这些数据需要转换为 float 然后传递给 cuda 内存.我觉得openGL做的就是用CPU来做这个格式转换,所以用pbo和不用pbo差别不大。

通过使用 unsigned char (glreadpixel(..,GL_UNSIGNED_BYTE,0)),与 pbo 绑定(bind)比不使用 pbo 读取 RGB 数据更快。然后我通过它做一个简单的 cuda 内核来进行格式转换,这比 openGL 做的更有效。通过这样做,速度要快得多。

但是,它不适用于深度缓冲区。由于某种原因,glreadpixel 读取深度图(无论有无 pbo)都很慢。然后,我发现了两个旧的讨论: http://www.opengl.org/discussion_boards/showthread.php/153121-Reading-the-Depth-Buffer-Why-so-slow

http://www.opengl.org/discussion_boards/showthread.php/173205-Saving-Restoring-Depth-Buffer-to-from-PBO

他们指出了格式问题,这正是我发现的 RGB 问题。 (无符号的字符)。但是我已经尝试过unsigned char/unsigned short和unsigned int,以及float用于读取深度缓冲区,所有性能几乎相同的速度。

所以我仍然有阅读深度的速度问题。

关于opengl - CUDA OPENGL 互操作性 : slow mapping,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15971391/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com