Glut 和 cuda 每秒停顿 100 毫秒
Posted
技术标签:
【中文标题】Glut 和 cuda 每秒停顿 100 毫秒【英文标题】:Glut and cuda stall for 100ms every second 【发布时间】:2013-07-30 21:43:33 【问题描述】:我正在从事一个涉及 cuda 和 freeglut 的项目,我正在努力从中汲取精华。
我有一个循环进行一些计算然后绘制。我从 nsight 跟踪中注意到,每秒大约有 100 到 200 毫秒的时间,似乎什么都没做。这简直是不能接受的。理想情况下,我希望消除这个失速,因为它使我只能以最快的速度前进 80%-90%。
停顿不会发生在第二个开头的点上,而是以非常有规律的间隔发生。
我的处理循环看起来像这样
cudaDeviceSynchronize();
kernel_call_1( ... , stream0);
if(T != 0) cudaStreamWaitEvent(stream1, event0, 0);
cudaMemcpyAsync( ... ,cudaMemcpyDeviceToHost,stream1);
kernel_call_2( ... , stream0);
cudaEventRecord(event0, stream0);
drawGL( ... );
OpenGL 是在与 CUDA 不同的卡上完成的,CUDA 的输出通过 memcpy 被带到主机上,并通过 glTexSubImage3D 推送到 OpenGL。
CUDA 或 OpenGL 或 FreeGLUT 是否会在我背后做任何可能导致停顿的事情?
编辑: 我注意到的另一件事是,NSight 区分了 cpu 和 gpu 帧。如果我查看 cpu 帧,它们似乎会慢慢地与 gpu 不同步。这种情况一直持续到停顿,在这种情况下,单个 cpu 帧运行时间很长,但 gpu 帧继续以相同的速度运行,并将它们拉回同步。 OpenGL 是否在我背后进行同步,有什么方法可以控制这种行为吗?
编辑: 这是 NSight 跟踪的屏幕截图。
【问题讨论】:
我也有类似的经历,不过我只在 1 个 GPU 上运行。我意识到,由于内核调用和 openGL 调用是异步的,因此内核调用正在“赶上”,即:在他可以将上下文切换到 OpenGL 之前,GPU 一个接一个地运行 2 个内核启动。就我而言,它有助于在 CUDA 调用之后和 drawGL() 调用之前移动 cudaDeviceSynchronize()。 这不是一个合适的解决方案,目前 CUDA 和 OpenGL 正在同时运行(因为它们在不同的 GPU 上)。 CUDA 和 OpenGL 之间的 devsync 将 OpenGL 从 CUDA 下方推出,它们一个接一个地运行。 据我所知,您可能希望在 CUDA 计算的同时绘制与 CUDA 结果无关的几何图形。 CUDA 完成后,您可以绘制依赖于 CUDA 的几何图形,在这种情况下,您将需要 cudaDeviceSynchronize()。还要注意你的 GPU 帧如何落后于你的 CPU 帧,这真的是故意的吗?在旁注中,您可能还会考虑 glFinish()。 不,cpu 帧的滞后不是故意的,可能是卡顿的原因。 OpenGL 跟踪具有用于 GPU 工作负载事件(绘制调用、命令缓冲区、传输和帧)的单个缓冲区。当这填满时,记录将被转储,导致停顿。请注意 CPU 帧如何超过 GPU 帧结束时间。如果您禁用 OpenGL 跟踪,我认为停顿会消失。我们希望在 4.0 之后的 Nsight 版本中显着减少图形跟踪开销。 【参考方案1】:据一位 NVIDIA 员工称,在提出问题时(2014 年),情况如下:
OpenGL 跟踪为 GPU 工作负载事件(绘图调用、 命令缓冲区、传输和帧)。当这填满 记录被转储导致停顿。请注意CPU框架如何 超过 GPU 帧结束时间。如果你禁用 OpenGL 跟踪我认为 摊位会消失。我们希望大幅减少 Nsight 4.0 之后的图形跟踪开销。
所以可能的解决方案是在 Nsight 中禁用 OpenGL 跟踪。
[此答案添加为社区 wiki 条目,以保留答案在 cmets 中并将问题从未回答队列中删除。根据需要随意投票和编辑]。
【讨论】:
以上是关于Glut 和 cuda 每秒停顿 100 毫秒的主要内容,如果未能解决你的问题,请参考以下文章