如果摩尔定律成立,并且 CPU/GPU 变得越来越快,那么软件(以及相关的软件开发人员)是否仍会突破界限,以至于您仍需要优化代码?或者一个天真的阶乘解决方案是否足以满足您的代码(等)?
26 回答
2 倍的处理能力并不能改善您糟糕的 n^2 搜索的糟糕程度。
糟糕的代码总能克服 CPU 速度。
举一个很好的例子,请转到这个Coding Horror专栏,然后向下滚动到描述Programming Pearls书的部分。转载了一张图表,显示对于某种算法,具有 4.77MHz 8 位处理器的 TRS-80 如何击败 32 位 Alpha 芯片。
当前加速的趋势是添加更多内核,因为让单个内核运行得更快是困难的。所以聚合速度提高了,但线性任务并不总是受益。
“没有蛮力和无知无法克服的问题”这句话并不总是正确的。
计算机速度越快,我们期望它们做的事情就越多。
无论是视频游戏中更多多边形的更快代码,还是金融市场交易的更快算法,如果更快具有竞争优势,优化仍然很重要。你不必超越追逐你和你伙伴的狮子——你只需要超越你的伙伴。
直到所有程序员第一次编写出最佳代码之前,总会有优化的地方。同时,真正的问题是:我们应该首先优化什么?
摩尔定律谈到了我们可以在一个芯片上封装多少个晶体管——它没有说明这些晶体管能够以越来越快的速度切换。事实上,在过去的几年里,时钟速度或多或少地停滞不前——我们只是不断地在每个芯片上获得越来越多的“核心”(本质上是完整的 CPU)。要利用这一点,需要对代码进行并行化,因此,如果您“天真”地编写代码,那么未来的神奇优化器将忙于找出代码中隐藏的并行性,以便将其分配给多个内核(更现实地说,对于在可预见的未来,您将不得不为您的编译器提供很多帮助;-)。
沃斯定律:
软件变慢的速度比硬件变快的速度快。
PS 更严肃的一点是:随着计算模型转向并行处理,代码优化变得更加重要。如果您将代码优化 2 倍,并且它在 1 个盒子上运行 5 分钟而不是 10 分钟,那么它可能不会那么令人印象深刻。下一台具有 2 倍速度的计算机将对此进行补偿。但是想象一下你在 1000 个 CPU 上运行你的程序。然后任何优化都可以节省大量的机器时间。还有电。优化并拯救地球!:)
计算任务似乎大致分为两大类。
- 有界计算需求的问题。
- 无限计算需求的问题。
大多数问题都属于第一类。例如,实时 3d 光栅化。很长一段时间以来,这个问题是典型的消费电子产品无法解决的。没有令人信服的 3d 游戏或其他程序可以在 Apple 上生成实时世界][。不过,最终,技术赶上了,现在这个问题是可以实现的。类似的问题是蛋白质折叠的模拟。直到最近,将已知的肽序列转化为生成的蛋白质分子是不可能的,但现代硬件使这在几个小时或几分钟的处理过程中成为可能。
但是有一些问题,就其性质而言,它们可以吸收所有可用的计算资源。其中大部分是动态物理模拟。显然,它可以执行例如天气的计算模型。几乎只要我们有电脑,我们就一直在这样做。然而,这样一个复杂的系统受益于提高的准确性。以更精细的空间和时间分辨率进行模拟逐位改进了预测。但是,无论任何给定的模拟具有多大的准确性,都有更高准确性的空间,随之而来的好处是。
这两种类型的问题对各种优化都有非常重要的用途。第二种很明显。如果进行模拟的程序有所改进,那么它的运行速度会更快,给出结果会更快或更准确。
不过,第一个有点微妙。在一定时期内,再多的优化都是不值得的,因为不存在速度足够快的计算机。一段时间后,优化就变得毫无意义了,因为运行它的硬件比所需的速度快很多倍。但是有一个狭窄的窗口,在此期间最佳解决方案将在当前硬件上可接受地运行,但次优解决方案不会。在此期间,经过深思熟虑的优化可能是首先进入市场的获胜产品与还跑的产品之间的区别。
优化不仅仅是速度。摩尔定律不适用于计算机内存。此外,优化通常是编译代码以利用 CPU 特定指令的过程。这些只是我能想到的一些优化,更快的 CPU 无法解决这些优化。
优化总是必要的,因为摩尔定律的缓解因素是英国媒体报道。
其他答案似乎集中在问题的速度方面。没关系。我能看到的真正问题是,如果你优化你的代码,运行它会花费更少的能量。您的数据中心运行温度更低,您的笔记本电脑使用时间更长,您的手机充电可以使用一天以上。市场的这一端存在真正的选择压力。
在许多情况下仍需要优化,特别是:
实时系统,其中 CPU 时间非常宝贵
内存就是内存的嵌入式系统非常宝贵
服务器,许多进程同时需要关注
游戏,其中 3-D 光线追踪、音频、人工智能和网络可以构成一个非常苛刻的程序
世界在变,我们也需要随之改变。当我刚开始时,成为一名优秀的程序员就是要了解所有可以做的微小优化,通过在 C 语言中操作指针以及其他类似的东西,从例程中再挤出 0.2%。现在,我将更多的时间花在让算法更易于理解上,因为从长远来看,这更有价值。但是 - 总是有一些事情需要优化,而且总是有瓶颈。更多的资源意味着人们对他们的系统有更多的期望,所以马虎对专业人士来说不是一个有效的选择。
但是,随着您添加更多的速度/内存/资源来使用,优化策略会发生变化。
一些优化与速度无关。例如,在优化多线程算法时,您可能正在优化共享锁总数的减少。如果您当前的处理能力用于等待锁定,则以速度(或更糟的是,处理器)的形式添加更多的处理能力可能不会产生任何影响......如果您做错了事情,添加处理器甚至会使您的整体性能下降. 在这种情况下,优化意味着尝试减少锁的数量,并尽可能保持它们的细粒度,而不是尝试减少指令的数量。
只要有些人编写使用过多资源的慢代码,其他人就必须优化他们的代码以更快地提供这些资源并恢复速度。
我发现一些开发人员可以编写次优代码的创造力令人惊讶。例如,在我以前的工作中,一个人编写了一个函数来计算两个日期之间的时间,方法是继续增加一个日期并进行比较。
计算机速度不能总是克服人为错误。这些问题可能会被表述为“ CPU 是否会变得足够快,以至于编译器可以花时间捕捉(和修复)实现问题”。显然,将需要(在可预见的未来)代码优化来解决Shlemiel the Painter类型的问题。
软件开发仍然是告诉计算机确切地做什么。“越来越快”的 CPU 将赋予我们设计越来越抽象和自然的编程语言的能力,最终达到计算机接受我们的意图并实现所有低级细节的地步……总有一天。
电脑就像青少年的房间。
它永远不会大到足以容纳所有的垃圾。
我认为这一切的结果是计算能力变得越来越便宜,因此程序员可以花更少的时间来完成给定的任务。例如,Java 或 Python 等高级语言几乎总是比汇编等低级语言慢。但是对于程序员来说,新事物是可能的,这要容易得多。我认为最终目标将是计算机能够直接与人类交流,并将人类语音编译成字节码。那么程序员将不复存在。(计算机可能会接管世界)
对或错,在我看来它已经发生了,而且不一定是坏事。更好的硬件确实为开发人员提供了将更多精力集中在解决手头问题上的机会,而不是担心额外 10% 的内存利用率。
优化是无可争辩的,但只有在需要时。我认为额外的硬件功能只是减少了真正需要它的实例。但是,编写软件以将航天飞机发射到月球的人最好优化他的代码:)
鉴于计算机的速度比几十年前快了大约一千倍,但通常看起来并没有快多少,我想说,在我们不再担心优化之前,我们还有很长的路要走。问题是随着计算机变得越来越强大,我们让计算机为我们做越来越多的工作,这样我们就可以在更高的抽象层次上工作。每个抽象级别的优化仍然很重要。
是的,计算机做很多事情的速度要快得多:你可以在几分钟内画出曼德布罗,而过去需要几天的计算机时间。GIF 几乎是即时加载的,而不是在屏幕上绘制可见的几秒钟。很多事情都更快。但是,例如,浏览并没有那么快。文字处理并没有那么快。随着计算机变得更强大,我们期望更多,我们让计算机做更多事情。
在可预见的未来,优化将很重要。然而,微优化远没有过去那么重要。这些天最重要的优化可能是算法的选择。你选择 O(n log n) 还是 O(n^2) .... 等等。
优化的成本非常低,所以我怀疑是否有必要放弃它。真正的问题是找到利用所有计算能力的任务——所以我们不会放弃优化,而是优化我们并行做事的能力。
最终我们将无法变得更快,最终我们将受到空间的限制,因此为什么您会看到更新的 3GHZ 和多核处理器。所以是的,优化仍然是必要的。
在某种程度上总是需要优化代码,而不仅仅是为了加快执行速度和降低内存使用量。例如,寻找处理信息的最佳节能方法将是数据中心的主要要求。分析技能将变得更加重要!
是的,我们正处于优化的关键阶段,并且在可预见的未来也会出现。因为:
- RAM 速度的增长速度低于 CPU 速度。因此,CPU 和 RAM 之间的性能差距仍在不断扩大,如果您的程序大量访问 RAM,则必须优化访问模式以有效利用缓存。否则超快的 CPU 将有 90% 的时间处于空闲状态,只是等待数据到达。
- 核心数量不断增加。您的代码是从每个添加的内核中受益还是在单个内核上运行?这里的优化意味着并行化,并且根据手头的任务,它可能会很困难。
- CPU 速度永远不会赶上指数算法和其他蛮力类型的东西。这个答案很好地说明了这一点。
让我们希望网络速度跟上,这样我们就可以通过网络传输足够多的数据来跟上 CPU 的速度……
如前所述,总会有瓶颈
假设你的 CPU 的晶体管数量与宇宙中亚原子粒子的数量一样多,并且它的时钟以硬宇宙射线的频率运行,你仍然可以击败它。
如果您想领先于最新的 CPU 时钟,只需在循环中添加另一层嵌套,或在子例程调用中添加另一层嵌套。
或者,如果您想真正专业,请添加另一层抽象。
这并不难:-)
即使 CPU 越来越快,您也可以随时优化
- 网络吞吐量,
- 磁盘寻道,
- 磁盘使用情况,
- 内存使用情况,
- 数据库事务,
- 系统调用次数,
- 调度和锁定粒度,
- 垃圾收集。
(这是我在过去半年看到的真实世界的例子)。
在计算历史的不同阶段,复杂计算机系统的不同部分被认为是昂贵的。您必须衡量瓶颈并判断在哪里投入精力。