如何减少程序的CPU使用率?
Posted
技术标签:
【中文标题】如何减少程序的CPU使用率?【英文标题】:How to reduce CPU usage of a program? 【发布时间】:2009-03-07 12:33:25 【问题描述】:我编写了一个多线程程序,该程序使用大量浮点运算进行一些 CPU 繁重的计算。更具体地说,它是一个逐帧比较动画序列的程序。 IE。它比较动画 A 中的帧数据与动画 B 中的所有帧,针对动画 A 中的所有帧。我对不同的动画并行执行这种密集操作,因此程序可以在 A-B 对、B-C 对和 C-A 对上工作平行线。该程序正在使用 QtConcurrent 和一个“映射”函数,该函数将一个带有运动的容器映射到一个函数上。 QtConcurrent 为我管理线程池,我正在使用 Intel 四核处理器,因此它产生 4 个线程。
现在,问题是我的进程破坏了我的 CPU。使用是 100% 不变的,如果我在足够大的动作集上运行我的程序(非分页区域中的页面错误),我实际上会出现蓝屏死机。我怀疑这是因为我的电脑超频了。但是,这可能是因为我编写程序的方式吗?我用来测试机器稳定性的一些非常密集的基准测试工具从未让我的电脑崩溃。有什么方法可以控制我的程序如何使用我的 CPU 来减少负载?还是我误解了我的问题?
【问题讨论】:
这是最明显的答案...但是,就像我说的,一些复杂的基准测试和电脑游戏永远不会让我的电脑崩溃。为什么他们从来没有让我的电脑崩溃? sneg:因为运行计算机(或任何东西)超出其设计规格的一个非常基本的事实:结果是不可预测的。没有任何一项测试可以保证您的计算机的稳定性。降频,看看是否能解决问题。它很可能会。 简单的回答,您运行了多少其他程序以 100% 长时间运行计算机的 CPU 和大部分内存?机会是,没有。 【参考方案1】:超频 PC 会导致各种奇怪的问题。如果您怀疑这是问题的根本原因,请尝试将其计时在合理的范围内并重试您的测试。
这也可能是某种非常奇怪的内存错误,在这种情况下,您破坏了 RAM,导致 Windows(我猜是操作系统,因为 BSOD)无法再恢复(不太可能,但谁知道)。
我能想到的另一种可能性是,您的线程实现中有一些错误会杀死窗口。
但首先,我会看看超频问题...
【讨论】:
“我猜那个操作系统,因为 BSOD”:因为名字,对吧?不是说崩溃了吗? :D BSOD = 蓝屏死机,主要用于 Windows 操作系统上的蓝色错误屏幕,所以我猜是 Windows 因为这个名字。在这些情况下,崩溃行为对于 Windows 来说并不是一个很好的指标,因为如果硬件超出其限制运行,每个操作系统都会崩溃。【参考方案2】:这里有一些很好的答案。
我只想补充一点,从已经进行了大量性能调整的角度来看,除非每个线程都经过积极优化,否则它有很大的减少周期的空间。
用长距离赛车来类比,有两种方法可以尝试获胜:
-
让车开得更快
减少中途停留和绕行
根据我的经验,大多数最初编写的软件都远没有走最直接的路线,尤其是随着软件变得越来越大。
正如 Kenneth Cochran 所说,要找出程序中浪费的循环,永远不要猜测。如果你在没有证明它是一个问题的情况下修复了某个问题,那么你就是在猜测。
发现性能问题的流行方法是使用分析器。
但是,我经常这样做,我的方法是这样的:http://www.wikihow.com/Optimize-Your-Program%27s-Performance
【讨论】:
感谢迈克,感谢您对本主题的精彩总结。我很难选择答案,因为它们都同样有用,都给了我一些思考的东西。但是,您的回答很好地结束了。 感谢您提出一个好问题。关于影响世界的性能有一些愚蠢的想法,而您的问题揭示了这一点。【参考方案3】:您描述的那种操作已经是高度可并行化的。运行多个作业实际上可能损害性能。这样做的原因是因为任何处理器的缓存大小都是有限的,您尝试并发执行的次数越多,每个线程的缓存份额就越小。
您还可以研究使用 GPU 来吸收一些处理负载的选项。对于大多数类型的视频转换,现代 GPU 比同类 CPU 的效率要高得多。
【讨论】:
【参考方案4】:我怀疑这是因为我的电脑超频了。
这绝对是可能的。尝试将其设置为正常速度一段时间。
这可能是因为我编写程序的方式吗?
在用户模式下运行的程序不太可能导致蓝屏。
【讨论】:
【参考方案5】:我猜想,我会说您没有运行 3 核机器(或 4,假设 100% 使用率),如果您使用的线程多于核心,并行化会严重损害您的性能。每个 CPU 内核只创建一个线程,并且无论您做什么,永远不会让不同线程同时访问数据。大多数多核 CPU 中的缓存锁定算法绝对会扼杀你的性能。在这种情况下,在处理 L 帧动画的 N 核 CPU 上,我将在帧 0-(L/N) 上使用线程 1,在帧 (L/N)-(2*L/N) 上使用线程 2,. .. 框架上的螺纹 N ((N-1)*L/N)-L。按顺序执行不同的组合(A-B、B-C、C-A),这样就不会破坏缓存,而且应该更容易编码。
作为旁注?像这样的真正计算应该使用 100% CPU,这意味着它会尽可能快地运行。
【讨论】:
感谢您的提示,西蒙。我一定会看看如何让我的程序对缓存更友好【参考方案6】:超频是导致不稳定的最可能原因。对于任何 CPU 密集型算法,都会有一些 CPU 抖动。超频无法承受,我会找到一个很好的性能分析器来找到性能瓶颈。永远不要猜测问题出在哪里。您可能会花费几个月的时间来优化对性能没有实际影响的东西,或者更糟糕的性能甚至可能会降低。
【讨论】:
【参考方案7】:责怪硬件太容易了。我建议你尝试在不同的系统上运行你的程序,看看使用相同的数据结果如何。
你可能有错误。
【讨论】:
导致系统崩溃的程序不正常。应用程序永远不能使操作系统崩溃。如果不是硬件,则更有可能是操作系统中的错误。 根据我的经验,蓝屏死机取决于操作系统中的错误和/或内核驱动程序中的错误。因此,我认为操作系统不会因完美运行的应用程序而出现故障。这里测试最少的部分是什么?我会说应用程序不是硬件或操作系统。 我的意思是,操作系统中的错误会使故障应用程序蓝屏死机,但如果应用程序没有错误,则可能不会蓝屏。 这可能只是由于超频和他的使用导致的硬件故障(这将疯狂地破坏 CPU 缓存) @Subtwo:我曾经在东芝的主板和笔记本电脑的硬件维修部门工作。硬件并不完美,它通常是最后一个责备的地方,但现在我从事软件开发和硬件维修工作,我可以说蓝屏很常见是由硬件故障引起的。【参考方案8】:研究使用 SIMD 操作。我认为在这种情况下你会想要 SSE。与并行化相比,它们通常是更好的第一步,因为它们更容易获得正确性,并且为大多数线性代数类型的运算提供了相当大的推动力。
一旦您使用 SIMD 获得它,然后考虑并行化。听起来你也在猛击 CPU,所以你也许可以做一些睡眠而不是忙等待,并确保你正在清理或正确重用线程。
【讨论】:
顺便说一句,我确实尝试过使用 SIMD 操作。但后来我尝试使用 /arch:sse2 标志进行编译。性能看起来非常相似,所以我认为编译器在使用扩展指令集方面做得很好。【参考方案9】:由于没有 BSOD 错误代码(用于查找),因此很难帮助您解决这个问题。
您可以尝试重新安装您的内存((取出并放入)。我和我认识的其他一些人已经在一些需要它的机器上工作过。例如,我曾经尝试升级 OS X一台机器,它一直在崩溃......最后我把内存弹出并放回去,一切都很好。
【讨论】:
【参考方案10】:睡眠(1);将 CPU 使用率减半。我在使用 CPU 密集型算法时遇到了同样的问题。
【讨论】:
仅当您的工作单元是 1 毫秒长并且您没有使用多个线程时。如果是这样,它也会将你的速度减半。【参考方案11】:如果您的处理器有两个或更多内核,您可以转到任务管理器并转到进程并右键单击程序名称并单击Set affinity
并将程序设置为使用更少的内核。
执行您要求的操作将需要更长的时间,但会导致 CPU 使用率显着下降。
【讨论】:
【参考方案12】:我认为当内核内存区域损坏时会导致蓝屏死机。 所以使用多线程进行并行操作不可能是这个原因。
如果您要创建多个线程,每个线程都执行繁重的浮点运算,那么您的 CPU 利用率肯定会达到 100%。
如果您可以在每个线程中给予一些睡眠,以便其他进程有机会获得一些机会,那就更好了。 您也可以尝试降低线程的优先级。
【讨论】:
【参考方案13】:如果在 Windows 平台上,在一些工作之后调用一个函数来通知 CPU 你想让 cpu 给其他进程。像这样调用 sleep 函数:
Slepp ( 0 );
【讨论】:
以上是关于如何减少程序的CPU使用率?的主要内容,如果未能解决你的问题,请参考以下文章
如何减少 Tensorflow/Keras 使用的 CPU 数量?
如何减少 golang tcp 服务器中的 cpu 使用率?