[インデックス 14762] ファイルの概要
このコミットは、Go言語のビルドシステムの一部である cmd/dist
において、ブートストラッププロセス中にGCCコンパイラに -pipe
オプションを使用するように変更を加えるものです。これにより、コンパイル時のパフォーマンスが向上し、特にディスクI/Oがボトルネックとなる環境でのビルド時間の短縮が期待されます。
コミット
commit 0c6beb00fbe00b843030f7a1178dfbc23a8e63d6
Author: Dave Cheney <dave@cheney.net>
Date: Sun Dec 30 10:33:33 2012 +1100
cmd/dist: use -pipe during bootstrap
R=golang-dev, minux.ma, rsc
CC=golang-dev
https://golang.org/cl/7025044
GitHub上でのコミットページへのリンク
https://github.com/golang/go/commit/0c6beb00fbe00b843030f7a1178dfbc23a8e63d6
元コミット内容
cmd/dist
: ブートストラップ中に -pipe
を使用する
変更の背景
Go言語のビルドプロセス、特にブートストラップフェーズでは、Cコンパイラ(この場合はGCC)が使用されます。従来のコンパイルプロセスでは、コンパイラの各ステージ(プリプロセッサ、コンパイラ、アセンブラなど)が中間ファイルをディスクに書き込み、次のステージがそれを読み込むというI/Oが発生していました。このディスクI/Oは、特に大規模なプロジェクトやI/O性能が低いシステムにおいて、ビルド時間のボトルネックとなる可能性がありました。
このコミットは、GCCの -pipe
オプションを導入することで、このディスクI/Oのオーバーヘッドを削減し、ビルドパフォーマンスを向上させることを目的としています。
前提知識の解説
Go言語のブートストラップ (Bootstrap)
Go言語は、自身のコンパイラやツールチェインをGo言語自身で記述しています。そのため、Go言語の新しいバージョンをビルドする際には、まず既存の(通常は以前のバージョンの)Goコンパイラを使用して、新しいバージョンのコンパイラ自身をコンパイルする必要があります。この自己コンパイルのプロセスを「ブートストラップ」と呼びます。
ブートストラッププロセスでは、GoのソースコードがC言語のコードに変換され、その後Cコンパイラ(GCCやClangなど)によってコンパイルされます。このCコンパイラによるコンパイルフェーズにおいて、本コミットの変更が適用されます。
cmd/dist
cmd/dist
は、Go言語のソースコードからGoツールチェイン全体をビルドするためのコマンドです。これはGoのビルドシステムの中核をなし、コンパイラ、リンカ、アセンブラなどのツールを構築する役割を担っています。cmd/dist
は、Goのブートストラッププロセスを管理し、Cコンパイラを呼び出してGoのランタイムやその他のCベースのコンポーネントをコンパイルします。
GCCの -pipe
オプション
GCC (GNU Compiler Collection) は、C、C++、Goなど様々なプログラミング言語をサポートするコンパイラ群です。-pipe
オプションは、GCCにコンパイルの各ステージ間で中間ファイルをディスクに書き込む代わりに、パイプ(メモリ上のデータストリーム)を使用して直接データを渡すように指示するオプションです。
通常、GCCは以下のような多段階のプロセスでコンパイルを行います。
- プリプロセッサ (cpp): ソースコードを前処理し、マクロ展開やインクルードファイルの処理を行います。結果は一時ファイルに書き込まれます。
- コンパイラ (cc1): プリプロセスされたコードをアセンブリコードに変換します。結果は一時ファイルに書き込まれます。
- アセンブラ (as): アセンブリコードをオブジェクトファイルに変換します。結果は一時ファイルに書き込まれます。
- リンカ (ld): オブジェクトファイルを結合し、実行可能ファイルを生成します。
-pipe
オプションを使用すると、これらのステージ間での一時ファイルのディスク書き込みが省略され、メモリ上で直接データが受け渡されます。これにより、ディスクI/Oのオーバーヘッドが削減され、特にI/O性能が低いシステムや、多数の小さなファイルをコンパイルする際にビルド時間が短縮されます。
技術的詳細
このコミットは、src/cmd/dist/build.c
ファイル内の proto_gccargs
配列に -pipe
オプションを追加しています。proto_gccargs
は、Goのブートストラッププロセス中にCコンパイラ(GCC)に渡されるデフォルトの引数リストを定義しています。
具体的には、以下の引数リストに -pipe
が追加されました。
static char *proto_gccargs[] = {
"-Werror", // 警告をエラーとして扱う
"-fno-common", // 共通ブロックの生成を抑制
"-ggdb", // GDBデバッグ情報を生成
"-pipe", // パイプを使用して中間ファイルを渡す
"-O2", // 最適化レベル2
};
この変更により、Goのブートストラップビルドにおいて、Cコンパイラがソースファイルをコンパイルする際に、各コンパイルステージ間でディスクI/Oを介さずにメモリ上でデータを直接やり取りするようになります。これにより、特にディスクの読み書きが頻繁に発生するような環境や、多数の小さなCファイルがコンパイルされる場合に、ビルド時間の短縮効果が期待できます。
-pipe
オプションは、コンパイルプロセスを高速化する一方で、メモリ使用量が増加する可能性があります。しかし、現代のシステムでは通常、このメモリ増加は許容範囲内であり、ビルド時間の短縮というメリットの方が大きいと判断されたと考えられます。
コアとなるコードの変更箇所
--- a/src/cmd/dist/build.c
+++ b/src/cmd/dist/build.c
@@ -396,6 +396,7 @@ static char *proto_gccargs[] = {
"-Werror",
"-fno-common",
"-ggdb",
+ "-pipe",
"-O2",
};
コアとなるコードの解説
変更は src/cmd/dist/build.c
ファイルの proto_gccargs
という静的文字列配列に対して行われています。この配列は、Goのブートストラッププロセス中にCコンパイラ(GCC)を呼び出す際に使用されるコマンドライン引数を定義しています。
追加された行 + "-pipe",
は、この配列に -pipe
という文字列リテラルを追加しています。これにより、cmd/dist
がGCCを呼び出す際に、他の引数(-Werror
, -fno-common
, -ggdb
, -O2
など)と共に -pipe
オプションが渡されるようになります。
結果として、GoのブートストラップビルドにおけるCコンパイルフェーズが、ディスクI/Oを削減し、より効率的に実行されるようになります。
関連リンク
- Go Change-Id:
7025044
(Gerrit Code Review): https://golang.org/cl/7025044
参考にした情報源リンク
- GCC Command Options (Invoking GCC): https://gcc.gnu.org/onlinedocs/gcc/Option-Summary.html (特に
-pipe
オプションについて) - Go Bootstrap Process (Go Wiki): https://go.dev/doc/install/source (Goのブートストラップに関する一般的な情報)
- Go source code:
src/cmd/dist/build.c
(コミット対象ファイル) - Go issue tracker (関連する議論や背景情報がある場合)
- Stack Overflow や技術ブログ (GCCの
-pipe
オプションの一般的な説明) - https://gcc.gnu.org/onlinedocs/gcc/Overall-Options.html (GCCの全体的なオプションに関する公式ドキュメント)
- https://go.dev/doc/install/source (Goのソースからのインストールに関する公式ドキュメント)