Q1。编写不消耗CPU但仍能获得出色性能的代码的最佳实践是什么?这个问题非常通用。我在这里寻求的是列出用于不同环境的不同实践?除了进程监视器/任务管理器之外的调试技巧
编辑: 我不是说IO绑定进程。我说的是CPU绑定过程。但是,在这里我不希望我的进程继续占用CPU。 如果我有一台4核机器,并且如果我在一个过程中运行四个简单的循环,那么在应用程序/进程运行之前,CPU消耗将高达400%。
我在这里寻求一些关于这个话题的经验,每个人都会遇到一些时间或其他。例如我调试了一个应用程序在Windows上占用CPU,因为它不断循环搜索不存在的文件。
如何以两种不同的CPU绑定应用程序顺利运行(给出良好响应)的方式编写程序?
更新 意见建议:
编写好的干净代码,然后分析您的应用程序,然后进行优化。 (感谢提示)
重写/重新设计/重构代码比分析和修复代码更容易。
使用分析器调试应用程序
不要对长时间等待的线程使用自旋锁
算法选择
这些建议对初学者理解概念有很大帮助。
答案 0 :(得分:6)
答案 1 :(得分:6)
做尽可能少的工作。
由于您已编辑了原始问题,我将在此处添加更多想法,以解决您所描述的具体情况。
假设您不知道进程阻塞的位置(因为您要求调试提示),您可以从暂停调试器开始,这将停止应用程序无论它在做什么,从那里您可以调查当前所有线程的位置,看看它们是否处于紧密循环中。
其次,任何体面的探查者都会轻易帮助抓住这样的情况。连接探查器并将应用程序运行到阻塞点,查看显着获得总运行时间百分比的调用。从那里你可以回来找到阻塞循环。
找到问题后,理想情况下需要重新考虑算法以完全避免这种情况。如果这不可能,那么在线程上引入sleep命令。这将允许其他线程进入CPU并以增加操作运行时为代价提高应用程序和OS整体的响应性。多核编程的技巧是确保所有线程在性能和对其他等待任务的考虑之间妥协。
在不知道特定语言或操作系统的情况下,我不能就问题提出建议,但我认为对于大多数成熟的语言都有很好的解决方案。
答案 2 :(得分:6)
首先,写好干净的代码。以最简单的方式做事。 之后,重复执行以下操作,直到您对程序的速度感到满意为止:
不是否会在优化名称中陷入预先歪曲代码的陷阱。
记住Amdhal's Law。通过加速已经消耗了程序时间的1%的东西,你不会得到显着的改进。通过加快程序花费的大部分时间,您可以获得最佳效果。
答案 3 :(得分:2)
如果它的纯粹CPU使用率增加,那么它就是你需要的大O符号。您需要弄清楚如何使算法在尽可能少的计算中工作。
但是,对于一般性能,我发现CPU使用率是较小的瓶颈之一。
有关性能的一些更重要的事情是
数据绑定,您是预先获得所有数据还是根据需要获取数据。选择其中一种方法可能是您的应用程序性能的关键。
您可以减少正在处理的数据吗?如果你可以轻松地将它们全部放入内存中,那么你可以在这里获得性能。另外,如果你在内存中放得太多,可能会产生相反的效果。
我想总结一下,没有通用的性能解决方案。编写你的代码(有一些智慧),然后看看它在哪里挣扎。
答案 4 :(得分:2)
我说的是CPU绑定过程。但是,在这里我不希望我的过程继续占用 中央处理器。如果我有一台4核机器,如果我在一个进程中运行四个简单的循环,那么CPU 在应用程序/流程运行之前,消耗量最多可达400%。
您可能希望在处于空闲状态时查看限制机制以降低CPU利用率:
在正常情况下,当代码无需执行任何操作时(即“忙等待”),您的代码甚至会消耗CPU周期。
例如,如果没有其他任何操作,空的无限循环将尽可能快地运行。
但是,在某些情况下,您不想忙等待,或者在某些平台上您可能想要完全避免它。
这样做的一种既定方法是在空闲时使用sleep调用,以便系统调度程序可以重新调度所有正在运行的线程。类似地,您可以使用计时器来确定函数的实际更新速率,并且如果不必运行代码,则可以简单地避免调用代码(这是游戏或模拟器有时使用的机制)。
通常,您需要避免轮询,而是使用智能数据结构(例如作业队列),以便相应地自动调整运行时行为,而无需永久检查数据结构本身。 / p>
答案 5 :(得分:1)
答案 6 :(得分:1)
遵循代码优化技术。
计算您的操作记忆。
计算每项操作的时间 (大记法)
答案 7 :(得分:1)
我不太清楚你是否正在寻找最有效利用CPU的方法,或者在你需要大量CPU密集型工作时避免陷入困境的方法。
这些是无法比拟的。
对于前者,理想情况下,您需要一个只需要您可以完全接管CPU的操作系统,因此您不必浪费操作系统本身的CPU周期,更不用说可能正在运行的任何其他进程。
对于后者,我最近一直在编写一些使用设计不佳的 CPU绑定算法的代码,而新的Intel I7处理器一直是我的救世主。鉴于四个核心每个都可以运行两个线程,我只是尝试将每个应用程序的操作系统线程使用限制为五个或六个,并且我仍然可以使用CPU切换到另一个窗口来运行kill
命令。至少在我驾驶系统进入空间泄漏交换之前。
答案 8 :(得分:0)
这里有好的建议。编写代码越简单,就越有时间自救。
我将性能调整视为extension of debugging。人们说衡量,衡量,衡量,但我没有。我只是让程序告诉我究竟是什么问题,如果需要的话,可以在未事先通知的情况下多次使用它。这通常是一个惊喜,它永远不会错。
通常的历史,取决于程序的大小,找到并解决一系列性能问题,每个都提供10%到50%的加速(如果有一个不好的问题则更多)。这使整体加速可能达到10倍。
然后样本告诉我它到底在做什么,但我想不出如何在没有基本重新设计的情况下修复它,意识到如果我首先以不同的方式完成设计,那将会是很多更快开始。
假设我可以进行重新设计,那么我可以进行更多轮次的性能查找和修复。在此之后,当我达到收益递减的程度时,我知道它的速度与实际可能的速度一样快,而且我可以在装配级别单步执行,并在每个指令“拉动它的重量”时得到答案。 / p>
达到这一点真的很满意。