C++ 代码执行/cpu速度每2秒降低一次
(这是一个有点交叉的软硬件主题,对我来说,一开始是一个编程问题,但经过所有的故障排除,我认为这可能是一个硬件问题(可能更适合超级用户?)但我还没有解决它,所以我不确定,希望这个社区能分享一些相关的cpu理论。无论如何…) 我正在编写一个实时渲染程序,并且一直被每2秒都会发生的可见帧速率故障所困扰。经过多次评测,我确定这是一种性能下降,会影响程序中的所有代码部分(包括图形api调用),因此我认为cpu问题超出了程序的责任范围 我可以在一个新的code::Blocks项目中使用以下代码在我的机器上演示该问题:C++ 代码执行/cpu速度每2秒降低一次,c++,performance,cpu,cpu-usage,framebuffer,C++,Performance,Cpu,Cpu Usage,Framebuffer,(这是一个有点交叉的软硬件主题,对我来说,一开始是一个编程问题,但经过所有的故障排除,我认为这可能是一个硬件问题(可能更适合超级用户?)但我还没有解决它,所以我不确定,希望这个社区能分享一些相关的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;
}
也许其他一些机器会显示类似的输出?(根据需要调整输出阈值。)
我尝试过用g++和clang进行编译,但都产生了这种异常。(总体而言,g++版本的性能稍好一些。)
我突然想到,自从我建造这台电脑以来,除了我自己的项目外,我没有在上面运行任何3d应用程序,所以我试着运行LunarG Vulkan API附带的全息图演示和一些屏幕保护程序,果然每2秒钟就会出现一次故障。(这在屏幕保护程序中不太明显。)所以我很欣慰地知道,至少它是全系统的,我的程序没有做错什么
系统规格:
- cpu:AMD Ryzen 7 1800X
- 主板:MSI B350战斧北极
- 内存:1x16GB DDR4 3200
- gpu:GeForce GTX 1050 Ti
- psu:Cougar CMX 1000
- 操作系统:Linux Mint 18.1 64位
我一直在尝试破解Vulkan交换链,并试图对此进行优化。我所拥有的最理想的解决方案是让一个线程只专门用于每1/60秒调用一次
vkQueuePresentKHR
(使用std::this\u thread::sleep\u until
在调用之间等待),Vulkan present mode设置为VK\u present\u mode\u IMMEDIATE\u KHR
,另外一个线程会提前绘制多达7个其他交换链图像,因此交换线程不必等待它们(我知道根据Vulkan规范,这可能不是最安全的方法)。使用此设置,对vkQueuePresentKHR
的调用通常需要0.000050到0.000300秒才能返回,但每2秒至少有1帧需要>0.01秒,如果我使用的是VK\u PRESENT\u MODE\u FIFO\u KHR
,而电话刚好错过了vblank,不得不等待下一个,那么这可能是有意义的,但我使用的是VK\u PRESENT\u MODE\u IMMEDIATE\u KHR
,所以我不知道发生了什么,除了在vkQueuePresentKHR
内部调用的隐藏代码受到我的性能异常的严重影响之外。您所做的测试太敏感了
在我的电脑上,它不会每2秒打印一次内容。但当我将tab键切换到其他应用程序并执行某些操作(尤其是访问文件系统)时,它会打印几行。即使我只是无所事事地等待,它也会每隔10-30秒随机打印一行。顺便说一句,使用Clang4.0和运行在Windows 10上的Ubuntu中的libc++以及Intel Xeon CPU
现在谈谈3D渲染问题
在您的Linux PC上,您记录的减速绝对值约为每次事件0.5-1ms。如果你喜欢我有一个60赫兹的显示器,显示器的1帧=16.6毫秒。就其本身而言,1毫秒的延迟(可能是操作系统引入的)并不是渲染跳过帧的充分理由
可能是代码+示例代码中的一个问题,您在其中构建交换链和/或呈现内容。仅仅因为它们是SDK示例并不意味着它们可以保证在您的特定PC上正常工作
可能是Vulkan司机的问题。要测试这一点,请运行基于OpenGL的屏幕保护程序并查找这些缺失的帧
或者可能只是与Vulkan无关的GPU驱动程序的问题。在这种情况下,您可能会在OpenGL中看到相同的问题。性能问题的原因是
.将其作为
/usr/bin/time--verbose运行,并检查页面错误和上下文开关编号。您的进程可能会因为耗尽了时间而被重新调度。尝试以sudo chrt-f 99/usr/bin/time--verbose
的形式运行它,看看上下文切换的数量是否变为0。@maxim添加sudo chrt-f 99
可以显著减少非自愿的上下文切换,但我仍然每2秒看到较慢的帧。当我试着用我的旋转四轮车时,sudo chrt-f 99
导致Vulkan吐出一大堆错误,我的程序崩溃了。那台计算机上的温度如何?我知道,很多现代CPU如果检测到t,就会减慢速度
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