Go 博客

GCC 4.7.1 中的 Gccgo

Ian Lance Taylor
2012 年 7 月 11 日

Go 语言一直都是由一个 规范 定义的,而不是一个实现。Go 团队编写了两个不同的编译器来实现该规范:gc 和 gccgo。拥有两个不同的实现有助于确保规范的完整性和正确性:当编译器出现分歧时,我们会修正规范,并相应地更改一个或两个编译器。Gc 是最初的编译器,go 工具默认使用它。Gccgo 是一个不同的实现,具有不同的侧重点,在本篇文章中,我们将更深入地了解它。

Gccgo 作为 GNU 编译器集合 (GCC) 的一部分进行分发。GCC 支持多种不同语言的前端;gccgo 是一个连接到 GCC 后端的 Go 前端。Go 前端独立于 GCC 项目,并且旨在能够连接到其他编译器后端,但目前仅支持 GCC。

与 gc 相比,gccgo 编译代码的速度较慢,但支持更强大的优化,因此由 gccgo 构建的 CPU 密集型程序通常运行速度更快。GCC 多年来实现的所有优化都可以使用,包括内联、循环优化、向量化、指令调度等等。虽然它并不总是能生成更好的代码,但在某些情况下,使用 gccgo 编译的程序可以运行速度快 30%。

gc 编译器仅支持最流行的处理器:x86(32 位和 64 位)和 ARM。然而,gccgo 支持 GCC 支持的所有处理器。并非所有这些处理器都经过了对 gccgo 的彻底测试,但许多处理器都经过了测试,包括 x86(32 位和 64 位)、SPARC、MIPS、PowerPC,甚至 Alpha。gccgo 还已在 gc 编译器不支持的操作系统上进行了测试,特别是 Solaris。

Gccgo 提供标准的完整 Go 库。Go 运行时的许多核心功能在 gccgo 和 gc 中都是相同的,包括 goroutine 调度器、通道、内存分配器和垃圾收集器。Gccgo 支持像 gc 编译器那样拆分 goroutine 堆栈,但目前仅在 x86(32 位或 64 位)上支持,并且仅在使用 gold 链接器时支持(在其他处理器上,每个 goroutine 将具有一个大型堆栈,并且一系列深层函数调用可能会运行到堆栈末尾并使程序崩溃)。

Gccgo 发行版尚未包含 go 命令的版本。但是,如果您从标准 Go 版本安装 go 命令,它已经通过 -compiler 选项支持 gccgo:go build -compiler gccgo myprog。用于 Go 与 C/C++ 之间调用的工具 cgo 和 SWIG 也支持 gccgo。

我们将 Go 前端置于与其他 Go 工具相同的 BSD 许可证下。您可以在 gofrontend 项目 中下载前端的源代码。请注意,当 Go 前端与 GCC 后端链接以生成 gccgo 时,GCC 的 GPL 许可证具有优先权。

GCC 的最新版本 4.7.1 包含支持 Go 1 的 gccgo。如果您需要为 CPU 密集型 Go 程序提供更好的性能,或者需要支持 gc 编译器不支持的处理器或操作系统,那么 gccgo 可能是您的最佳选择。

下一篇文章:组织 Go 代码
上一篇文章:Google I/O 2012 的 Go 视频
博客索引