【问题标题】:Does compiling Go code on one machine and running it on another degrade the program's performance?在一台机器上编译 Go 代码并在另一台机器上运行它会降低程序的性能吗?
【发布时间】:2021-08-13 19:56:46
【问题描述】:

如果我在 Mac 上编译 Go 程序(显然是针对 Linux 架构)并将其推送到 Linux 服务器上运行,会不会有任何性能损失?

我在某处读到 Go 编译器会针对正在编译的特定硬件优化二进制文件,例如用于多线程的 CPU 内核数量等?是真的吗?

在一台机器上编译 Go 代码并在另一台机器上运行它是否安全(不会降低性能)?

【问题讨论】:

  • 是的,这是安全的。
  • 不是编译器,而是运行时根据其运行的硬件调整调度程序的细节。
  • Go 当然不会针对构建它的机器上的内核数量优化二进制文件。如果您的执行环境包含较少的内核,性能可能会下降,但这是因为内核较少,而不是因为二进制文件没有针对较少数量的内核进行优化。同样,如果您将相同的二进制文件移动到具有更多内核的环境中,那么使用所有可用内核也不会出现问题。

标签: performance go optimization deployment compilation


【解决方案1】:

在一台机器上编译 Go 代码并在另一台机器上运行它会降低程序的性能吗?

没有。

您的问题表明,当针对同一平台时,不同的系统可以从同一来源构建不同的二进制文件,但事实并非如此。默认情况下,Go 构建是可重现的,即在构建包时针对相同的平台(由 GOOS and GOARCH 指定)将始终产生完全相同的二进制文件,无论您在哪里构建它。这对于能够断言给定二进制文件实际上是从给定源生成的非常重要。

虽然有可能打破这一保证(例如,通过使用诸如-ldflags '-X main.timestamp=${DATE}' 之类的编译器参数故意在二进制文件中包含时间戳),但这不会影响您的任何可测量数量的执行速度。

【讨论】:

    【解决方案2】:

    在一台机器上编译 Go 代码并在另一台机器上运行它是否安全(不会降低性能)?

    是的。不会有性能下降。

    <...> Go 编译器会针对其编译所在的特定硬件优化二进制文件,例如用于多线程的 CPU 内核数量等?是真的吗?

    不,它不是(截至 2021 年 8 月 13 日),但请继续阅读以了解一些警告。

    我们讨论中的“问题”是假定的默认值。

    问题是,“Go”是一种编程语言,由它的spec(和它的memory model)定义,any 实现能够解析根据规范编写的文本文件并以遵循内存模型的方式执行他们定义的 Go 程序,根据定义,“可以运行 Go 程序”。

    如您所见,Go 可能有很多实现——包括用 Go 编写的 Go 解释器(例如搜索“yaegi”和“monkey-go”)。

    不过,我认为,可以安全地假设您意味着由 Go 核心团队(和许多志愿者)开发的 Go 的“库存”、“默认”实现,并且可用来自here.
    该特定实现提供了所谓的ahead-of-time (AOT) compilation,并且它包含的编译器目前不导出任何构建时控件来影响机器代码生成。 它也没有考虑构建过程所在的本地系统的细节——例如它的 CPU 型号和它的 CPU 上的硬件线程数。

    但请注意一个有趣的转折:since some time 现有的 Go 实现将 wasm 作为其目标架构之一,而 WASM 代码(通常)运行在可能实现 just-in-time (JIT) compilation 的 VM 上, /em> 能够在运行时微调已编译的代码(通过分析然后重新编译位于热路径上的代码)。
    与 AOT 编译的机器代码相比,这种微调的确切价值值得怀疑,因为它依赖的东西太多,只能通过基准测试来比较和对比。

    TL;DR

    在你的情况下,请放心:交叉编译没有任何区别。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-09-29
      • 2017-01-22
      • 2012-04-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-10-31
      • 2014-11-17
      相关资源
      最近更新 更多