The Warmup Protocol Problem: JIT, GC, and Lazy Evaluation Effects on WRSS in Julia, Haskell, and Python
本研究调查了预热协议的选择——具体而言是即时编译(JIT)、垃圾回收(GC)以及延迟求值效应的排除或包含——如何扭曲 Julia、Haskell 和 Python 的工作负载-运行时缩放特征(WRSS)及瓶颈转换点,从而揭示了标准的稳态基准测试可能会误报真实的首次执行性能,并产生具有误导性的跨语言缩放结论。
原始论文采用 CC BY 4.0 许可(https://creativecommons.org/licenses/by/4.0/)。 这是对下方论文的AI生成解释。它不是由作者撰写或认可的。如需技术准确性,请参阅原始论文。 阅读完整免责声明
当计算机科学家试图测量程序的运行速度时,他们面临着一个隐藏的陷阱。现代软件在用户点击按钮的那一刻并不会立即以全速运行。相反,计算机通常会先花费最初的时刻来准备程序,将代码翻译成机器能理解的形式,或者清理旧数据以腾出空间处理新任务。这个准备阶段被称为“预热”(warmup)。几十年来,研究计算机如何同时处理多个任务的研究人员一直试图忽略这种预热,只测量之后进行的稳定、平滑的运行过程。他们认为这能提供一种关于语言真实能力的纯粹视角。但这种方法假设程序总是针对相同的数据长时间运行,而这种情况在现实世界中很少见,因为软件经常需要从零开始或频繁更换工作负载。
最近的一项研究挑战了这一长期存在的假设,它探讨了当我们不再隐藏预热时会发生什么。研究人员重点研究了三种流行的编程语言:Julia、Haskell 和 Python。他们使用了一种称为“工作负载-运行时缩放特征”(Workload–Runtime Scaling Signature)的特定方法,将程序所花费的时间分解为三个部分:工作者进行实际计算的时间、结合其结果的时间,以及用于内存管理或翻译等开销的剩余时间。通过运行同样三个复杂的任务——对一组巨大的数字列表进行排序、寻找领域中最近的一对点,以及对一组庞大的数值求和——他们比较了两种截然不同的衡量性能的方法。一种方法遵循传统的规则,先对计算机进行预热;而另一种方法则从完全的冷启动开始测量,包括所有的初始延迟。
结果显示,测量方式的选择比许多人意识到的更为重要。当研究人员将冷启动纳入考虑时,这些语言扩展性能的表现发生了剧烈变化。对于使用运行时翻译系统的 Julia 语言而言,初始翻译时间非常沉重,以至于完全改变了结果。在传统的预热测试中,Julia 表现出能够高效处理大量工作者,直到达到某个临界点后,结合结果的时间才成为瓶al(瓶颈)。然而,当把初始翻译时间计入时钟时,这个瓶颈出现得要早得多。由于翻译代码的时间推高了“剩余”时间,使得系统看起来比其平稳运行时的效率要低,程序似乎在比预热测试所暗示的更少的工作者数量时就撞到了墙。
Haskell 的表现则不同。由于这种语言会延迟计算,直到它们被绝对需要时才进行,因此初始成本是分散在整个运行过程中的,而不是集中在开始阶段。这意味着,无论研究人员是先对系统进行预热,还是从冷启动开始测量,结果几乎看起来是一样的。该语言的设计自然地平滑了启动时的粗糙边缘,使其无论如何进行测试都表现得异常稳定。Python 则介于两者之间。它的性能在很大程度上取决于数据在计算机不同部分之间是如何移动的。当任务需要通过一个缓慢的序列化过程移动大量数据时,冷启动会增加显著的延迟。但当数据可以更直接地共享时,这种影响就会减小。
或许最重要的发现是,正在执行的任务类型改变了预热的重要性程度。对于纯粹关于数字运算的任务,初始延迟相对于总工作量来说非常小,以至于几乎没有改变结果。但对于涉及大量组织和组合数据的任务,初始延迟成为了总时间的一个重要组成部分。在这些情况下,忽略预热会导致一种虚假的安全感,即误以为软件在可能频繁启动和停止的现代计算现实场景中能表现得如此之好。研究结论指出,目前衡量并行性能的标准方式——即剥离掉启动阶段——虽然对于稳定的、长时间运行的任务是准确的,但对于主导现代计算的动态、短时任务来说却具有误导性。为了真正理解这些语言的行为,研究人员和开发人员必须准确报告他们是如何处理启动阶段的,承认程序的最初几秒钟可以定义其整个性能特征。
您所在领域的论文太多了?
获取与您研究关键词匹配的最新论文每日摘要——附技术摘要,使用您的语言。