代码执行/ cpu速度每2秒减慢[关闭]

问题描述 投票:-3回答:2

(这是一个交叉的软件 - 硬件主题,它起初是一个编程问题,但经过所有的故障排除后,我认为它可能是一个硬件问题(可能更适合超级用户?)但我还没解决它我不确定,希望这个社区有一些相关的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秒钟就会出现问题。 (它在屏幕保护程序中不太明显。)所以我很高兴至少知道它是系统范围的,而不是我的程序错误。

系统规格:

  • cpu:AMD Ryzen 7 1800X
  • 主板:MSI B350 Tomahawk Arctic
  • ram:1x16GB DDR4 3200
  • gpu:GeForce GTX 1050 Ti
  • psu:Cougar CMX 1000
  • os:Linux Mint 18.1 64位

看起来我用1000W psu过度使用它,所以缺少瓦数不是问题。除非Cougar psu有一些缺陷导致每2秒短暂下降一次?

任何想法可能导致这个以及我能做些什么呢?

编辑:有关我的渲染问题的更多详细信息:

我一直在OpenGL周围构建我的引擎,并且只要我一直在使用这台机器就遇到了这个问题。在此之前我在我的旧电脑上有类似的随机跳帧,它有自己的问题(老式游戏笔记本电脑的电池续航时间为20分钟,并且有足够的过热倾向触发安全关闭)这就是为什么我没有立刻想到这是一个硬件问题。我一直在计划将我的项目移植到Vulkan,因此我不再担心框架跳过,希望在我更改渲染API时它会消失。但现在我正在通过this Vulkan tutorial,我已经看到了框架跳过,就像在教程中绘制旋转四边形一样。

我一直试图破解我的方式围绕Vulkan交换链试图优化这个。我拥有的最佳解决方案是让一个专门的线程专门用于每1/60秒调用vkQueuePresentKHRusing std::this_thread::sleep_until在调用之间等待),Vulkan当前模式设置为VK_PRESENT_MODE_IMMEDIATE_KHR,另一个线程绘制到最多7个其他提前交换链图像,因此交换线程不必等待它们(我知道根据Vulkan规范,这可能不是最安全的方法)。通过这种设置,对vkQueuePresentKHR的调用通常需要在0.000050和0.000300秒之间返回,但是每2秒至少有1帧需要> 0.01秒,这可能是有意义的,如果我使用VK_PRESENT_MODE_FIFO_KHR并且呼叫几乎没有错过vblank并且不得不等待下一个,但我正在使用VK_PRESENT_MODE_IMMEDIATE_KHR所以我不知道发生了什么,除了在vkQueuePresentKHR内调用的任何底层代码受到我的性能异常严重影响。

c++ performance cpu cpu-usage framebuffer
2个回答
1
投票

0
投票

你所做的测试太敏感了。

在我的电脑上,它不会每2秒打印一次。但是,当我向其他应用程序添加alt-tab并执行某些操作时,尤其是访问文件系统,它打印几行。即使我只是闲着等待,它每10-30秒随机打印一行。 BTW使用clang 4.0和在Windows 10上运行Ubuntu的libc ++,Intel Xeon CPU。

现在关于你的3D渲染问题。

在您的Linux PC上,您记录的减速的绝对值大约为每事件0.5-1ms。如果你喜欢我有一个60赫兹的显示器,显示器的1帧= 16.6ms。就其本身而言,1ms延迟(可能由OS引入)并不足以使渲染跳过帧。

可能是您的代码+示例代码中的问题,您可以在其中构建交换链和/或您提供内容的位置。仅仅因为它们是SDK样本并不意味着它们可以保证在您的特定PC上正常工作。

可能是Vulkan驱动程序的问题。要测试这一点,请运行基于OpenGL的屏幕保护程序并查找这些丢失的帧。

或者只是与Vulkan无关的GPU驱动程序的问题。在这种情况下,您可能会看到与OpenGL相同的问题。

© www.soinside.com 2019 - 2024. All rights reserved.