Does compiling Go code on one machine and running it on another degrade the program's performance?

huangapple go评论88阅读模式
英文:

Does compiling Go code on one machine and running it on another degrade the program's performance?

问题

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

我在某个地方读到过,Go 编译器会针对特定的硬件进行优化,比如多线程的 CPU 核心数量等。这是真的吗?

在一台机器上编译 Go 代码,然后在另一台机器上运行,是否安全(不会有性能下降)?

英文:

Will there be any performance loss if I compile a Go program on my Mac (obviously, targeting Linux architecture) and push it to Linux server to run on?

I read somewhere that Go compiler optimizes the binary for the specific hardware its being compiled on, like the number of CPU cores for multithreading, etc.? Is it true?

Is it safe to compile Go code on one machine and run it on another (without performance degradation)?

答案1

得分: 4

在一个机器上编译Go代码,然后在另一个机器上运行不会降低程序的性能。

你的问题暗示了在针对相同平台时,不同的系统可以从相同的源代码构建不同的二进制文件,但实际上并不会出现这种情况。Go构建默认是可复现的,也就是说,当在构建一个包时,针对相同的平台(由GOOS和GOARCH指定)将始终生成完全相同的二进制文件,无论在哪里构建。这对于能够确认给定的二进制文件实际上是由给定的源代码生成的非常重要。

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

英文:

> Does compiling Go code on one machine and running it on another degrade the program's performance?

No.

Your question suggests that different systems can build different binaries from the same source when targeting the same platform, but they don't. Go builds are reproducible by default, i.e. targeting the same platform (as specified by GOOS and GOARCH) when building a package will always yield the exact same binary, no matter where you build it. This is extremely important to be able to assert that a given binary was actually produced from a given source.

While it is possible to break this guarantee (for example through deliberate inclusion of a timestamp in the binary through use of a compiler argument such as -ldflags '-X main.timestamp=${DATE}') this won't influence your execution speed in any measurable quantity.

答案2

得分: 3

在一台机器上编译Go代码然后在另一台机器上运行是安全的(不会有性能下降)。

不会有性能下降。

Go编译器并不会针对特定的硬件进行优化,比如多线程的CPU核心数量等(截至2021-08-13)。但是请继续阅读以下一些注意事项。

我们讨论的问题是假设的默认情况。

事实是,“Go”是一种由其规范(以及其内存模型)定义的编程语言,任何能够解析按照规范编写的文本文件并以符合内存模型的方式执行定义的Go程序的实现,都可以被定义为“可以运行Go程序”。

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

尽管如此,我认为可以安全地假设你所指的是由Go核心团队(以及许多志愿者)开发的“标准”、“默认”的Go实现,可以从这里获取。该特定实现提供了所谓的提前编译(AOT),它包含的编译器目前不会导出任何构建时的控制来影响机器代码生成。它也不考虑构建过程所在的本地系统的特定情况,比如CPU型号和CPU的硬件线程数。

但请注意一个有趣的变化:从某个时间开始,标准的Go实现将wasm作为其目标之一,而WASM代码(通常)在一个可能实现即时编译(JIT)的虚拟机上运行,该虚拟机能够在运行时对编译的代码进行微调(通过对热路径上的代码进行分析和重新编译)。与AOT编译的机器代码相比,这种微调的确切价值是有问题的,因为它取决于太多的因素,只能通过基准测试进行比较和对比。

总结

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

英文:

> Is it safe to compile Go code on one machine and run it on another (without performance degradation)?

Yes. There will be no performance degradation.

> <…> Go compiler optimizes the binary for the specific hardware its being compiled on, like the number of CPU cores for multithreading, etc.? Is it true?

No, it is not (as of 2021-08-13) but read on for some caveats.

The "problem" in our discussion is the assumed defaults.

The thing is, "Go" is a programming langugage defined by its spec (and its memory model), and any implementation which is able to parse text files written according to the spec and execute the Go program they define in a way it adheres to the memory model, is, by definition, "can run Go programs".

As you can see, there could be lots of implementations of Go — including Go interpreters written in Go (search for "yaegi" and "monkey-go", for instance).

Still, I think, it can be safely assumed you meant the "stock", "default" implementation of Go which is developed by the Go core team (and lots of volunteers) and is available from here.
That particular implementation provides the so-called ahead-of-time (AOT) compilation, and the compiler it includes does not, presently, export any build-time controls to affect machine code generation.
It also does not consider the specifics of the local system the build process takes place on — such as its CPU model and the number of H/W threads on its CPUs.

But note an interesting twist: since some time the stock Go implementation has wasm as one of the architectures it targets, and WASM code (typically) runs on a VM which may implement just-in-time (JIT) compilation which is able to fine-tune the compiled code at runtime (by profiling and then recompiling code laying on the hot paths).
The exact value of such fine-tuning compared to an AOT-compiled machine code is questionable as it depends on too many things, and can only be compared and contrasted by benchmarking.

TL;DR

In your case, please, be confident: cross-compilation does not make any difference.

huangapple
  • 本文由 发表于 2021年8月14日 03:56:46
  • 转载请务必保留本文链接:https://go.coder-hub.com/68777768.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定