【问题标题】:Computing physics and displaying it with GPU only计算物理并仅使用 GPU 显示
【发布时间】:2021-10-26 12:31:37
【问题描述】:

因此,基本上,我最近学习了 OpenCL,并利用这种新发现的强大功能,使物理模拟的速度提高了大约 10 倍。问题是,我只使用了 10% 的 GPU。我假设这是因为我将数据发送回 CPU/Ram,然后再将其发送回 GPU,以便显示。有人知道如何避免这种情况吗?我有点想为我的图形使用 OpenCL,但有些事情告诉我这是一个坏主意——对于上下文,我从未使用过 OpenGL。顺便说一句,这一切都在 C++ 中。这是我的代码的伪代码示例:

void start()
{
    CreateKernel();
    SendDataToKernel();
}

void update()
{
    RunKernel();
    float x,y = ReadDataFromKernel();
    Draw(std::round(x), std::round(y));
}

【问题讨论】:

  • 当您在 Google 上搜索“opencl opengl interop”时,您是否找到对您有帮助的内容?
  • 如果您不使用opengl,您是在软件中绘图吗?这可能是导致您的 GPU 等待工作的瓶颈
  • 除了你的伪代码之外,可能还有很多不同的原因,包括 CPU 端的工作量太大、GPU 上的计算与全局内存访问比率低等。使用分析器获取更多信息或建立minimal reproducible example,以便人们可以调查并帮助您了解真正的问题。

标签: c++ gpu opencl hpc


【解决方案1】:

如果您只观察到 10% 的 GPU 使用率,则问题在于没有发送帧缓冲区。

我做过类似的事情,在 GPU 上进行物理模拟并在 OpenCL 中进行实时渲染,然后通过 PCIe 将位图发送到 CPU,并通过<Windows.h>SetBitmapBits 发送到显示器,然后再通过 GPU。这非常有效,并且 GPU 利用率为 100%,例如 herehere。 您可以通过 OpenCL-OpenGL 互操作性直接对显示器进行绘图,以提高效率,但这实际上没有必要,也无法解决您的问题。

解决办法是在CPU上做2个线程:

  1. 计算线程:它在无限循环中运行物理计算,没有任何延迟,并在每次迭代中调用 GPU 计算内核和compute_queue.finish();。此线程始终使 GPU 保持 100% 负载。
  2. 渲染线程:它运行内核以渲染数据,然后将位图复制过来并执行绘图命令到屏幕上。如果整个过程花费的时间少于 1/60 秒,则调用Sleep 以减少 GPU 上的负载并让它花更多时间在物理计算上。 为了使这两个线程相互独立,您还应该创建两个 OpenCL 命令队列,一个用于计算线程,一个用于渲染线程。

【讨论】:

  • 嘿,感谢您的回答,现在实施它,很高兴看到我会得到什么样的结果。我想知道使用互斥锁是否是最佳做法,以避免内核在读取缓冲区时只写入缓冲区的一部分,或者这在 SIMD 处理器中真的不是问题吗?
  • 据我测试,即使有两个队列,问题也不存在,因为 GPU 上的内核仍然是按顺序计算的,但这并不总是如此。要真正确保在渲染时不更新一半缓冲区,您可以在 GPU 上使用单个队列进行计算和渲染。队列中的内核调用总是按顺序计算的。
猜你喜欢
  • 2021-08-06
  • 1970-01-01
  • 2018-03-08
  • 2013-10-17
  • 2012-06-23
  • 2013-08-31
  • 2015-08-21
  • 2015-08-27
  • 2023-03-12
相关资源
最近更新 更多