(这是一个交叉的软件 - 硬件主题,它起初是一个编程问题,但经过所有的故障排除后我认为它可能硬件问题(可能更适合)对于超级用户?)但我还没有解决它,所以我不确定,并希望这个社区将有一些相关的cpu理论来分享。无论如何......)
我正在编写一个实时渲染程序,并且每隔2秒就会遇到一个可见的帧率故障。经过多次剖析后,我确定这是一个性能下降,会影响我程序中的所有代码段(包括图形api调用),因此我认为这是一个超出程序职责范围的cpu问题。
我可以在新的Code :: Blocks项目中使用以下代码在我的机器上演示问题:
#include <cstdint>
#include <iostream>
#include <chrono>
int main(int argc, char* args[])
{
std::cout << std::fixed;
std::chrono::system_clock::time_point runStart = std::chrono::high_resolution_clock::now();
while(true)
{
uint64_t count = 0;
std::chrono::system_clock::time_point frameStart = std::chrono::high_resolution_clock::now();
{
for(uint64_t i = 0; i < 100000; ++i)
++count;
}
std::chrono::system_clock::time_point frameStop = std::chrono::high_resolution_clock::now();
double runTime = std::chrono::duration<double, std::chrono::seconds::period>(frameStop - runStart).count();
double frameTime = std::chrono::duration<double, std::chrono::seconds::period>(frameStop - frameStart).count();
if(frameTime > 0.0005)
std::cout << count << " runTime: " << runTime << " \tframeTime: " << frameTime << '\n';
}
return 0;
}
典型输出看起来像这样,每2秒清楚地显示一些较慢的帧:
100000 runTime: 0.000393 frameTime: 0.000393
100000 runTime: 0.000840 frameTime: 0.000393
100000 runTime: 0.001214 frameTime: 0.000369
100000 runTime: 0.002984 frameTime: 0.000389
100000 runTime: 0.003384 frameTime: 0.000395
100000 runTime: 0.003781 frameTime: 0.000393
100000 runTime: 0.004158 frameTime: 0.000371
100000 runTime: 0.005927 frameTime: 0.000386
100000 runTime: 0.006329 frameTime: 0.000398
100000 runTime: 0.006724 frameTime: 0.000390
100000 runTime: 0.007127 frameTime: 0.000398
100000 runTime: 0.007507 frameTime: 0.000375
100000 runTime: 0.994469 frameTime: 0.000511
100000 runTime: 3.042060 frameTime: 0.000465
100000 runTime: 3.077671 frameTime: 0.000405
100000 runTime: 5.093173 frameTime: 0.000496
100000 runTime: 5.128435 frameTime: 0.000366
100000 runTime: 5.488874 frameTime: 0.000391
100000 runTime: 7.135737 frameTime: 0.000367
100000 runTime: 7.152022 frameTime: 0.000484
100000 runTime: 7.457491 frameTime: 0.000360
100000 runTime: 9.179262 frameTime: 0.000478
100000 runTime: 9.211521 frameTime: 0.000368
100000 runTime: 9.226528 frameTime: 0.000353
100000 runTime: 11.217430 frameTime: 0.000391
100000 runTime: 11.262574 frameTime: 0.000352
也许其他一些机器会显示类似的输出? (根据需要调整输出阈值。)
我尝试用g ++和clang进行编译,两者都产生了这种异常现象。 (g ++版本总体上表现得更好。)
我刚刚想到,自从我制作这台电脑以来,除了我自己的项目之外我还没有运行任何3D应用程序,所以我尝试运行LunarG Vulkan API附带的Hologram演示,以及一些屏幕保护程序,确实每2秒钟就会出现问题。 (它在屏幕保护程序中不太明显。)所以我至少知道它在整个系统范围内,而不是我对我的程序做错了。
系统规格:
看起来我用1000W psu过度使用它,所以缺少瓦数不是问题。除非Cougar psu有一些缺陷导致每2秒短暂下降一次?
任何想法可能导致这个以及我能做些什么呢?
编辑: 有关我的渲染问题的更多细节:
我已经在OpenGL周围构建了我的引擎很长一段时间,并且只要我在这台机器上工作就遇到了这个问题。在此之前,我的旧计算机上有类似的随机帧跳过,这有其自身的问题(老式游戏笔记本电脑的电池寿命为20分钟,并且有足够的过热倾向触发安全关闭)这就是为什么我没有&立即认为这是一个硬件问题。我一直在计划将我的项目移植到Vulkan,因此我不再担心框架跳过,希望在我更改渲染API时它会消失。但是现在我正在经历this Vulkan tutorial,我已经在绘制旋转四边形时看到了框架跳过,就像在教程中一样。
我一直在尝试围绕Vulkan交换链试图围绕这个进行优化。我得到的最佳解决方案是让一个专门的线程专门用于每隔1/60秒调用vkQueuePresentKHR
(using std::this_thread::sleep_until
在调用之间等待),Vulkan当前模式设置为VK_PRESENT_MODE_IMMEDIATE_KHR
并且另一个线程预先绘制了最多7个其他交换链图像,因此交换线程不必等待它们(我知道这可能不是最安全的方法)对Vulkan规范)。使用此设置,对vkQueuePresentKHR
的调用通常需要在0.000050和0.000300秒之间返回,但每2秒至少需要1帧,其中&gt; 0.01秒,这可能是有意义的,如果我使用VK_PRESENT_MODE_FIFO_KHR
并且电话刚刚错过了vblank并且不得不等待下一个,但是我使用VK_PRESENT_MODE_IMMEDIATE_KHR
所以我没有&#39知道发生了什么,除了在vkQueuePresentKHR
内调用的任何内幕代码受到我的性能异常的严重影响。
答案 0 :(得分:1)
答案 1 :(得分:0)
你所做的测试太敏感了。
在我的电脑上,它不会每2秒打印一次。但是,当我向其他应用程序添加alt-tab并执行某些操作时,尤其是访问文件系统,它打印几行。即使我只是闲着等待,它每10-30秒随机打印一行。 BTW使用clang 4.0和在Windows 10,Intel Xeon CPU上运行Ubuntu的libc ++。
现在关于你的3D渲染问题。
在您的Linux PC上,您记录的减速的绝对值大约为每事件0.5-1毫秒。如果你喜欢我有一个60赫兹的显示器,显示器的1帧= 16.6ms。就其本身而言,1ms的延迟(可能由操作系统引入)并不足以让渲染跳过帧。
您的代码+示例代码中可能存在问题,您可以在其中构建交换链和/或您提供内容的位置。仅仅因为它们是SDK样本并不意味着它们可以保证在您的特定PC上正常工作。
可能是Vulkan驱动程序的问题。要对此进行测试,请运行基于OpenGL的屏幕保护程序并查找这些丢失的帧。
或者只是与Vulkan无关的GPU驱动程序的问题。在这种情况下,您可能会看到与OpenGL相同的问题。