我正在运行一个用C ++编写的程序,其中CPU使用率是一个重要因素,并且一直在努力减少它,直到遇到意外异常为止。该程序使用std::cout
行来查看性能,当我删除它时,该程序的CPU使用率在Windows资源监视器中以4-6秒的间隔急剧增加约1秒。
在std::cout
行中,它以0-2%的CPU使用率平稳运行,而没有任何尖峰现象。删除std::cout
行,它以0-2%的CPU使用率运行,而Windows资源监视器中4-6秒的CPU占用间隔则高达25%。
有趣的是,增加输出字符串的大小会减小CPU Spike的高度,而减小字符串的大小会增加CPU Spike的高度。
以下是有问题的代码行:
float engineCompletionTime = engineTimer->getEngineCompletionTime();
/* Stops CPU from spiking */
std::cout << "Engine cycle took " << engineCompletionTime << " milliseconds." << std::endl;
if (engineCompletionTime < 14.0f) {
std::this_thread::sleep_for(std::chrono::milliseconds((int)(14.0f - engineCompletionTime)));
}
编辑:谢谢您的初步答复,但请注意:
当std :: cout行位于程序中时,没有CPU峰值。
当std :: cout行不在程序中时,会有CPU峰值。
随着std :: cout打印的字符串大小的增加,CPU峰值的大小减小。
答案 0 :(得分:5)
根据实现的不同,写入std::cout
基本上涉及将控制权移交给操作系统一小段时间,然后将数据发送到终端。这不是Windows上最快的过程,在此期间程序基本上处于空闲状态。 std::cout
必须处理的数据越多,延迟花费的时间就越长,因此程序在空闲时间上花费的时间就越多。
如果某个程序花费大量时间等待输入(从另一个程序,从键盘或鼠标,从具有图形用户界面的“重画屏幕”信号,或者具有GUI的操作系统),则它具有较低的CPU使用率,或来自文件系统)。基本上,CPU使用率表示程序不等待的时间的一部分。
如果程序的唯一工作是无延迟地处理大量传入数据,则它根本不应该等待,如果CPU使用率很高,也可以。另一方面,如果您有一个正在等待用户输入的程序(例如交互式应用程序),则CPU使用率高可能会出现问题,因为这意味着该程序正在做很多事情。即使用户什么都不做也能正常工作。
使程序更高效通常可以解决此问题。
如果您要检查紧密循环中发生的事情,而不是使用事件处理,那会导致CPU使用率很高,因为即使程序正在等待某些事情,它也会主动检查 。每三分钟检查一次门是否有包裹,然后只等到门铃放权,这是有区别的。如果每三分钟检查一次,即使您只是在等待,您也会做很多工作。但是,如果您只是等到门铃响起(与事件处理一样),您实际上就没有做任何工作。
答案 1 :(得分:0)
std :: cout并不是完全高性能的(特别是在Win32上!),并且强制使用std :: endl进行刷新不会帮助解决问题:) 通常最好自己跟踪这些日志消息,或者:在完成后写入文件,每N次打印一次平均值以打印一次,或者在末尾打印一个简化的摘要。