我们的 C++ 应用程序在使用 Nvidia 显卡的某些系统上使用 WGL 创建窗口(以及使用 OpenGL 进行渲染)时遇到了严重的性能问题。一旦创建了一个窗口,或者更准确地说,只要调用了ChoosePixelFormat或SetPixelFormat,内存分配在进程的整个生命周期内都会显着变慢。这发生在我们可以访问的多种不同系统上,但在 Windows 8.1 Pro 64 位和 Windows 10 Enterprise 64 位上的Quadro M6000 12 GB(驱动程序版本 385.69)和Titan Xp (驱动程序版本 387.92)最为明显. 在较低程度上,这种影响也可以在 GeForce 卡和 Windows 7 Professional 64 位上测量到。
我制作了一个小型测试应用程序来演示该问题。我们运行一个涉及大量内存分配的昂贵作业,然后使用 WGL 创建一个窗口,调用 ChoosePixelFormat,删除该窗口,然后再次运行相同的昂贵内存分配。内存分配是定时的并输出到控制台。在我们测试过的所有系统(六种不同的卡,三种操作系统)上,调用 ChoosePixelFormat 后内存分配明显变慢(在 5% 和 20% 之间)。但是,当我们将 Quadro 或 Titan Xp 放入系统时,ChoosePixelFormat 之后的内存分配占用了之前的 300% 以上。
一些测试结果(我们在系统之间交换了卡以涵盖几乎所有组合,但我们没有保留所有基准,但这是一个有意义的子集):
Titan Xp, Windows 8.1 Pro 64 bit
Before Window Creation
Testing memory allocation performance 1 / 3: 5.20743 seconds
Testing memory allocation performance 2 / 3: 5.60933 seconds
Testing memory allocation performance 3 / 3: 5.4247 seconds
After Window Creation
Testing memory allocation performance 1 / 3: 18.0398 seconds
Testing memory allocation performance 2 / 3: 17.9902 seconds
Testing memory allocation performance 3 / 3: 17.9052 seconds
GTX 770, Windows 7 Professional 64 bit
Before Window Creation
Testing memory allocation performance 1 / 3: 4.66427 seconds
Testing memory allocation performance 2 / 3: 4.65927 seconds
Testing memory allocation performance 3 / 3: 4.62726 seconds
After Window Creation
Testing memory allocation performance 1 / 3: 5.69533 seconds
Testing memory allocation performance 2 / 3: 5.71333 seconds
Testing memory allocation performance 3 / 3: 5.72833 seconds
GTX 1080, Windows 8.1 Pro 64 bit
Before Window Creation
Testing memory allocation performance 1 / 3: 5.35666 seconds
Testing memory allocation performance 2 / 3: 5.37008 seconds
Testing memory allocation performance 3 / 3: 5.36607 seconds
After Window Creation
Testing memory allocation performance 1 / 3: 5.7112 seconds
Testing memory allocation performance 2 / 3: 5.69939 seconds
Testing memory allocation performance 3 / 3: 5.71902 seconds
我记得我会在我的 Optimus 笔记本电脑上使用一个老技巧,这样自己编写的应用程序会自动使用离散的 Nvidia GPU:将可执行文件重命名为wow.exe. 我试过这个,当然,它有效。在我们的实际应用程序和测试应用程序中,性能问题都消失了。在 Titan Xp 上,调用 ChoosePixelFormat 后的内存分配奇迹般地比调用它之前更快。我很确定这是因为为魔兽世界所做的视频驱动程序中的特殊分支绕过了一些让我们的生活变得艰难的“功能”。所以现在我们可以收工并发布名为 wow.exe 的软件,但在某些时候,客户可能会问这个名称代表什么,我们必须想出一个巧妙的首字母缩略词或重新命名。这不是一个永久的解决方案,而是一个非常奇怪的调试结果。(“显卡供应商不想让你知道的事情:用这个简单的技巧提高 3D 应用程序的性能!”)
在调试链接的测试应用程序时,您可以看到在窗口创建期间,一个或多个线程由在窗口破坏后仍然存在的视频驱动程序产生。我们怀疑他们以某种方式参与了所有这一切。但是,我们既没有时间也没有预算对此进行进一步调查。
除了将我们的软件命名为 wow.exe、降级到 GTX 1080 或等待 Nvidia 回答我们的支持查询(他们四年没有做过一次)之外,我们现在还有哪些选择?有没有人遇到过并成功克服了这个问题?在 Windows 7/8.1/10 上使用 WGL 创建窗口和 OpenGL(4.5 核心)上下文时,有什么方法可以绕过 ChoosePixelFormat 和 SetPixelFormat?(我们也尝试使用 GLFW 设置窗口,但我很确定这会在后台调用 WGL - 结果是相同的。)此外,我们会对拥有 Maxwell 或 Pascal Quadro 卡的人的任何评论非常感兴趣或没有遇到这些问题的 Titan Xp。也许我们的设置中的一个小改动就可以解决问题。
PS:虽然这个问题听起来有点离奇,但我们并不是第一个遇到的。之前已经描述过,但显然,Nvidia 没有时间回复或解决这个问题。