【问题标题】:code execution/cpu speed slows down every 2 seconds [closed]代码执行/CPU速度每2秒减慢一次[关闭]
【发布时间】:2018-02-16 07:07:00
【问题描述】:

(这是一个交叉的软件-硬件主题,对我来说是一个编程问题,但经过所有故障排除后,我认为它可能是一个硬件问题(也许更适合超级用户? ) 但是我还没有解决所以我不确定,希望这个社区有一些相关的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 和一些屏幕保护程序附带的全息图演示,果然,每 2 秒就会出现一次故障。 (在屏幕保护程序中不太明显。)所以我很欣慰地知道它至少是系统范围的,而不是我的程序做错了什么。

系统规格:

  • cpu:AMD 锐龙 7 1800X
  • 主板:微星 B350 战斧北极
  • 内存:1x16GB DDR4 3200
  • GPU:GeForce GTX 1050 Ti
  • 电源:美洲狮 CMX 1000
  • 操作系统:Linux Mint 18.1 64 位

看起来我用 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 帧需要 > 0.01 秒,如果我使用 VK_PRESENT_MODE_FIFO_KHR 和call 几乎没有错过 vblank 并且不得不等待下一个,但我正在使用 VK_PRESENT_MODE_IMMEDIATE_KHR 所以我不知道发生了什么,除了在 vkQueuePresentKHR 内部调用的任何底层代码正在受到我的性能异常的严重影响。

【问题讨论】:

  • /usr/bin/time --verbose &lt;executable&gt; 运行它并检查页面错误和上下文切换号。可能您的流程被取消计划,因为它耗尽了时间量。尝试以sudo chrt -f 99 /usr/bin/time --verbose &lt;executable&gt; 运行,看看上下文切换次数是否变为0。
  • @maxim 添加 sudo chrt -f 99 显着减少了非自愿上下文切换,但我仍然每 2 秒看到较慢的帧。当我用我的旋转四边形尝试它时,sudo chrt -f 99 导致 Vulkan 吐出一堆错误,我的程序崩溃了。
  • 那台电脑的温度如何?我知道许多现代 CPU 如果检测到它们开始过热,它们会放慢速度。
  • @Jeremy 上次检查时(几个月前),AM4 插座类型的一些规格尚未开源,所以很遗憾我无法读取温度传感器在 Linux 中,只能通过重新启动并查看 bios 来检查它,但是当我这样做时,它通常在 40 摄氏度左右,而且我从来没有听到泵启动的声音,所以我认为这不是问题。

标签: c++ performance cpu cpu-usage framebuffer


【解决方案1】:

【讨论】:

    【解决方案2】:

    你做的测试太敏感了。

    在我的电脑上,它不会每 2 秒打印一次。但是当我 alt-tab 到其他应用程序并做某事时,尤其是。访问文件系统,它会打印几行。即使我只是闲着等待,它也会每隔 10-30 秒随机打印一行。顺便说一句,在 Windows 10 和 Intel Xeon CPU 上使用带有 libc++ 的 clang 4.0。

    现在谈谈您的 3D 渲染问题。

    在您的 Linux PC 上,您记录的减速的绝对值约为每次事件 0.5-1 毫秒。如果你喜欢我有一个 60 Hz 的显示,1 帧显示 = 16.6 毫秒。就其本身而言,这 1 毫秒的延迟(可能由操作系统引入)并不是渲染跳帧的充分理由。

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

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

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

    【讨论】:

    • @LightnessRacesinOrbit 该代码还打印运行时间值,该值告诉同时发生了完整的爆发。无论如何,我刚刚用刷新的std::endl 替换了 '\n',得到了相同的行为。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-01-15
    • 1970-01-01
    • 2012-05-16
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多