c# - Swapchain.Present() 花费的时间太长,导致滞后

标签 c# performance lag slimdx dxgi

自从我将我的所有 c# SlimDX DX11 渲染代码从我的表单(是的,我是一个懒惰的开发人员)移动到定制类后,我最近遇到了一些延迟。我将我的程序打入 EQATEC Profiler 并将其作为我延迟的主要贡献者:

EQATEC Profiler results showing function postRender() to be at fault

现在很明显,postRender() 中的任何内容都占用了宝贵的毫秒数。事实上,无论我有什么疯狂的、令人费解的代码,它都能有效地将我的帧率降低到 ~15 FPS。

那么 postRender() 中有什么?只需一行代码:

swapChain.Present(0, PresentFlags.None);

我只是不知道是什么导致它如此缓慢,我根本没有对交换链代码进行任何更改。我只改变了屏幕分辨率 (1680x1050),但这绝对没问题(作为引用,这台机器可以在该分辨率下以最大设置运行 crysis2 而不会出汗)。

有没有人知道什么可能导致交换链在呈现时花费如此长的时间,或者我下一步应该去哪里寻找问题?

编辑:

查看我的代码结构,我的RenderFrame()函数如下:

preRender();
DeferredRender(preShader);
//Composite scene to output image
CompositeScene(compositeShader);
//Post Process
PostProcess(postProcShader);
//Depth of Field
DoF(dofShader);
//Present the swapchain
postRender();

其中一些功能的结果是基于之前的功能(例如,DeferredRender 使用四个渲染目标以逐像素的方式捕获 Diffuse lighting、Normals、Positions 和 Color。然后 CompositeScene 将它们放在一起。这将要求 GPU 在继续之前计算出上一步。整个过程继续进行,DoF 需要 PostProcess 等的结果。因此,唯一可能保持 Swapchain.Present() 的着色器必须是着色器它在 DoF 函数中运行,因为所有其他着色器都会导致 CPU 锁定,直到它们完成。对吗?

最佳答案

有几个原因可能会导致您发现 Present() 在您的框架中占用了那么多时间。 Present 调用是 CPU 和 GPU 之间同步的主要方法;如果 CPU 生成帧的速度比 GPU 处理帧的速度快得多,它们就会排队。一旦缓冲区变满, Present() 就会变成一个美化的 Sleep() 调用,同时等待它清空。

当然,根据您在此处提供的少量信息,这几乎是不可能的。仅仅因为一台机器运行孤岛危机并不意味着你可以随心所欲地在卡片上扔任何你想要的东西。仔细检查您不希望渲染大量的几何体,并且您的着色器没有异常长和复杂。

还可以使用可用的 GPU 分析器之一查看您的应用; PIX 是一个很好的基点,而 NVIDIA 和 AMD 各自为自己的产品提供更具体的产品。最后,确保您的驱动程序已更新。如果驱动程序中存在错误,您对问题进行推理的任何机会都会消失。

关于c# - Swapchain.Present() 花费的时间太长,导致滞后,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10373169/

相关文章:

c# - 用户代码未处理实体异常

java - 动态壁纸,帧动画,滞后

c# - 使用 wpf C# Ado.Net 数据实体从 SQL Server 获取图像到数据网格中

c# - 在 C# 中解压缩流

c# - 如果将对象 [] 参数传递给另一个带有对象 [] 参数的过程,将如何解释它们?

python - 这对缓冲区操作更有效 : python strings or array()

performance - go 的加速问题

javascript - 将对象分配给临时变量

javascript - 如何在 javascript 中使用 setTimeout 考虑延迟

actionscript-3 - ActionScript:来自ByteArray的声音存在滞后