[インデックス 13218] ファイルの概要
このコミットは、Go言語のベンチマークスイートであるtest/bench/shootout/timing.log
ファイルに対する変更を記録しています。具体的には、mandelbrot
ベンチマークの実行結果がログに復元され、以前のパフォーマンス数値に戻ったことが示されています。これは、特定のコードレビュー(http://codereview.appspot.com/6261051
)の適用により、浮動小数点定数の扱いが改善された結果です。
コミット
commit ec4d213594c5948f930c9d46f9444e422e1670cd
Author: Rob Pike <r@golang.org>
Date: Wed May 30 10:35:47 2012 -0700
test/bench/shootout/timing.log: mandelbrot is restored
R=golang-dev, bradfitz, rsc
CC=golang-dev
https://golang.org/cl/6259054
GitHub上でのコミットページへのリンク
https://github.com/golang/go/commit/ec4d213594c5948f930c9d46f9444e422e1670cd
元コミット内容
test/bench/shootout/timing.log: mandelbrot is restored
R=golang-dev, bradfitz, rsc
CC=golang-dev
https://golang.org/cl/6259054
変更の背景
このコミットの背景には、Go言語のコンパイラにおける浮動小数点定数の扱いに関するパフォーマンス上の問題がありました。以前のコミット(http://codereview.appspot.com/6209077
で言及されている変更)によって、mandelbrot
ベンチマークのパフォーマンスが著しく低下していました。Mandelbrot集合の計算は浮動小数点演算を多用するため、浮動小数点定数のコンパイル方法がパフォーマンスに直接影響します。
http://codereview.appspot.com/6261051
で示されているコードレビューは、この問題に対処し、浮動小数点定数に対する古いコード生成ロジックを復元することを目的としていました。この変更が適用された結果、mandelbrot
ベンチマークの実行時間が以前の良好な数値に戻ったため、その結果をtiming.log
に反映させる必要がありました。
つまり、このコミットは、Goコンパイラの最適化に関する以前の変更が意図せずパフォーマンスリグレッションを引き起こしたことへの修正と、その修正が成功したことを示すベンチマークログの更新です。
前提知識の解説
ベンチマークとShootoutベンチマーク
ベンチマークとは、ソフトウェアやハードウェアの性能を測定し、比較するためのテストのことです。特定のタスクを実行するのにかかる時間や、リソースの使用量などを計測します。
Shootoutベンチマーク(またはThe Computer Language Benchmarks Game)は、異なるプログラミング言語やその実装(コンパイラ、インタプリタなど)の性能を比較するための、標準化された一連のベンチマークプログラム群です。Mandelbrot集合の計算は、浮動小数点演算の性能を測るための一般的なベンチマークの一つとしてよく用いられます。
Mandelbrot集合
Mandelbrot集合は、複素平面上の点cに対して、漸化式 z_{n+1} = z_n^2 + c
(ただし z_0 = 0
)で定義される数列 z_n
が無限大に発散しないような点cの集合です。この集合はフラクタル図形として知られ、非常に複雑で美しい構造を持っています。Mandelbrot集合の計算は、浮動小数点数の乗算、加算、比較といった基本的な演算を大量に行うため、CPUの浮動小数点演算ユニット(FPU)の性能を評価するのに適しています。
浮動小数点定数とコンパイラの最適化
浮動小数点定数とは、プログラムコード中に直接記述される小数点を含む数値(例: 3.14
, 1.0e-5
)のことです。コンパイラは、これらの定数をプログラムの実行可能コードに変換する際に、様々な最適化を適用することがあります。
コンパイラの最適化には、以下のようなものがあります。
- 定数畳み込み (Constant Folding): コンパイル時に計算可能な定数式を事前に計算し、その結果をコードに埋め込む。
- 命令選択 (Instruction Selection): 特定の演算に対して、最も効率的なCPU命令を選択する。
- レジスタ割り当て (Register Allocation): 変数や中間結果をCPUの高速なレジスタに割り当てることで、メモリアクセスを減らす。
浮動小数点演算は、整数演算に比べて複雑で時間がかかることが多いため、コンパイラは浮動小数点定数の表現方法や、それらを用いた演算のコード生成において、特に慎重な最適化を行います。例えば、特定の浮動小数点定数をより効率的な形式で表現したり、計算の精度と速度のバランスを取ったりすることがあります。
このコミットの文脈では、Goコンパイラが浮動小数点定数をどのように内部的に表現し、それらを用いた演算の機械語コードをどのように生成するかが、Mandelbrotベンチマークのパフォーマンスに大きな影響を与えていたと考えられます。以前の変更が、何らかの理由でこのコード生成を非効率にしてしまい、その後の修正で元の効率的なコード生成が復元された、という流れです。
技術的詳細
このコミットは、Go言語のコンパイラが浮動小数点定数を扱う際のコード生成戦略の変更が、ベンチマークのパフォーマンスに与える影響を示しています。
http://codereview.appspot.com/6209077
で言及されている変更は、おそらくGoコンパイラの内部的な浮動小数点定数の表現方法や、それらを用いた演算の最適化に関するものでした。Mandelbrot集合の計算は、複素数の乗算と加算を繰り返し行うため、浮動小数点演算が非常に頻繁に発生します。もしコンパイラが浮動小数点定数を非効率な方法で処理したり、それらを含む演算に対して最適な機械語命令を生成できなかったりすると、プログラム全体の実行速度に大きな影響が出ます。
例えば、以下のようなケースが考えられます。
- 精度の問題: 浮動小数点定数の内部表現が、計算に必要な精度を十分に持たず、実行時に余分な丸め誤差や変換処理が発生した。
- 命令選択の非効率化: 特定の浮動小数点演算に対して、CPUのFPUが提供する高速な命令ではなく、より汎用的だが低速な命令が選択された。
- レジスタ利用の非最適化: 浮動小数点定数や中間結果が効率的にレジスタに割り当てられず、頻繁なメモリアクセスが発生した。
http://codereview.appspot.com/6261051
の変更は、これらの問題に対処するために、以前の(より効率的だった)浮動小数点定数に対するコード生成ロジックを復元したと考えられます。これにより、Mandelbrotベンチマークが以前のパフォーマンスレベルに戻ったことは、この修正が成功し、Goコンパイラが浮動小数点演算を再び効率的に処理できるようになったことを示しています。
timing.log
に記録されている数値は、各ベンチマークの実行時間(または関連するメトリクス)を示しています。
gcc -O2 mandelbrot.c
: C言語版のMandelbrotプログラムをGCCコンパイラで最適化レベル-O2でコンパイルして実行した結果。これは比較のベースラインとなります。gccgo -O2 mandelbrot.go
: Go言語版のMandelbrotプログラムをgccgoコンパイラで最適化レベル-O2でコンパイルして実行した結果。gc mandelbrot
: Go言語版のMandelbrotプログラムをGoの公式コンパイラ(gc)でコンパイルして実行した結果。gc_B mandelbrot
: Go言語版のMandelbrotプログラムをGoの公式コンパイラ(gc)で、おそらく特定のビルドオプション(例えば、より新しいバージョンや異なる最適化設定)でコンパイルして実行した結果。
これらの数値が以前の良好な状態に戻ったことは、Goコンパイラの浮動小数点演算の性能が回復したことを定量的に示しています。
コアとなるコードの変更箇所
このコミットは、test/bench/shootout/timing.log
ファイルに以下の9行を追加しています。
--- a/test/bench/shootout/timing.log
+++ b/test/bench/shootout/timing.log
@@ -1022,3 +1022,12 @@ mandelbrot (much slower, due to unrelated http://codereview.appspot.com/6209077)
meteor 2098
gc meteor-contest 0.13u 0.00s 0.13r # -13%
gc_B meteor-contest 0.13u 0.00s 0.13r # -7%
+
+# After http://codereview.appspot.com/6261051, restoring old code generated
+# for floating-point constants. Mandelbrot is back to its previous numbers.
+
+mandelbrot 16000
+ gcc -O2 mandelbrot.c 36.07u 0.00s 36.16r
+ gccgo -O2 mandelbrot.go 41.72u 0.01s 41.90r
+ gc mandelbrot 60.62u 0.00s 60.76r
+ gc_B mandelbrot 60.68u 0.00s 60.82r
コアとなるコードの解説
追加された行は、timing.log
ファイル内のベンチマーク結果のセクションを更新しています。
-
# After http://codereview.appspot.com/6261051, restoring old code generated
# for floating-point constants. Mandelbrot is back to its previous numbers.
この2行はコメントであり、今回の変更の理由を説明しています。http://codereview.appspot.com/6261051
で示されるコードレビューが適用された後、浮動小数点定数に対して生成されるコードが以前の状態に戻され、その結果Mandelbrotベンチマークの数値も以前の良好な状態に戻ったことを明記しています。 -
mandelbrot 16000
これはMandelbrotベンチマークの新しいエントリです。16000
という数値は、おそらくベンチマークの入力サイズや、特定の実行条件を示すIDのようなものです。 -
gcc -O2 mandelbrot.c 36.07u 0.00s 36.16r
C言語版のMandelbrotベンチマークの実行結果です。36.07u
: ユーザーCPU時間(user CPU time)0.00s
: システムCPU時間(system CPU time)36.16r
: リアル時間(real time、または経過時間) これらの数値は、C言語版のMandelbrotが約36秒で完了したことを示しています。これは、Go言語版のパフォーマンスを評価するための基準となります。
-
gccgo -O2 mandelbrot.go 41.72u 0.01s 41.90r
Go言語版のMandelbrotベンチマークをgccgo
コンパイラでコンパイルして実行した結果です。gccgo
はGCCのフロントエンドとしてGoをサポートするコンパイラです。約41.9秒で完了しています。 -
gc mandelbrot 60.62u 0.00s 60.76r
Go言語版のMandelbrotベンチマークをGoの公式コンパイラ(gc
)でコンパイルして実行した結果です。約60.76秒で完了しています。 -
gc_B mandelbrot 60.68u 0.00s 60.82r
Go言語版のMandelbrotベンチマークをGoの公式コンパイラ(gc
)で、おそらく特定のビルド構成(例えば、異なる最適化フラグや、より新しい開発ブランチなど)でコンパイルして実行した結果です。約60.82秒で完了しています。
これらの数値がtiming.log
に追加されたことで、Goコンパイラの浮動小数点定数処理の改善が、Mandelbrotベンチマークの実行時間に明確な影響を与え、以前のパフォーマンスレベルに回復したことが公式に記録されました。
関連リンク
- Go言語のコードレビューシステム (Gerrit): https://go-review.googlesource.com/
- The Computer Language Benchmarks Game: https://benchmarksgame-team.pages.debian.net/benchmarksgame/
- Mandelbrot集合 - Wikipedia: https://ja.wikipedia.org/wiki/%E3%83%9E%E3%83%B3%E3%83%87%E3%83%AB%E3%83%96%E3%83%AD%E3%83%BC%E3%83%88%E9%9B%86%E5%90%88
参考にした情報源リンク
http://codereview.appspot.com/6259054
(Go Gerrit CL)http://codereview.appspot.com/6209077
(Mandelbrotベンチマークのパフォーマンス低下に関連する以前のCL)http://codereview.appspot.com/6261051
(浮動小数点定数のコード生成を復元したCL)- Go言語の公式ドキュメント (コンパイラ、ベンチマークに関する情報)
- GCC (GNU Compiler Collection) のドキュメント
- 浮動小数点数に関する一般的なコンピュータサイエンスの知識
- ベンチマークとパフォーマンス測定に関する一般的な知識
- Gitのコミットと差分表示に関する知識
time
コマンドの出力(user, system, real time)に関する知識
[インデックス 13218] ファイルの概要
このコミットは、Go言語のベンチマークスイートであるtest/bench/shootout/timing.log
ファイルに対する変更を記録しています。具体的には、mandelbrot
ベンチマークの実行結果がログに復元され、以前のパフォーマンス数値に戻ったことが示されています。これは、特定のコードレビュー(http://codereview.appspot.com/6261051
)の適用により、浮動小数点定数の扱いが改善された結果です。
コミット
commit ec4d213594c5948f930c9d46f9444e422e1670cd
Author: Rob Pike <r@golang.org>
Date: Wed May 30 10:35:47 2012 -0700
test/bench/shootout/timing.log: mandelbrot is restored
R=golang-dev, bradfitz, rsc
CC=golang-dev
https://golang.org/cl/6259054
GitHub上でのコミットページへのリンク
https://github.com/golang/go/commit/ec4d213594c5948f930c9d46f9444e422e1670cd
元コミット内容
test/bench/shootout/timing.log: mandelbrot is restored
R=golang-dev, bradfitz, rsc
CC=golang-dev
https://golang.org/cl/6259054
変更の背景
このコミットの背景には、Go言語のコンパイラにおける浮動小数点定数の扱いに関するパフォーマンス上の問題がありました。以前のコミット(http://codereview.appspot.com/6209077
で言及されている変更)によって、mandelbrot
ベンチマークのパフォーマンスが著しく低下していました。Mandelbrot集合の計算は浮動小数点演算を多用するため、浮動小数点定数のコンパイル方法がパフォーマンスに直接影響します。
http://codereview.appspot.com/6261051
で示されているコードレビューは、この問題に対処し、浮動小数点定数に対する古いコード生成ロジックを復元することを目的としていました。この変更が適用された結果、mandelbrot
ベンチマークの実行時間が以前の良好な数値に戻ったため、その結果をtiming.log
に反映させる必要がありました。
つまり、このコミットは、Goコンパイラの最適化に関する以前の変更が意図せずパフォーマンスリグレッションを引き起こしたことへの修正と、その修正が成功したことを示すベンチマークログの更新です。
前提知識の解説
ベンチマークとShootoutベンチマーク
ベンチマークとは、ソフトウェアやハードウェアの性能を測定し、比較するためのテストのことです。特定のタスクを実行するのにかかる時間や、リソースの使用量などを計測します。
Shootoutベンチマーク(またはThe Computer Language Benchmarks Game)は、異なるプログラミング言語やその実装(コンパイラ、インタプリタなど)の性能を比較するための、標準化された一連のベンチマークプログラム群です。Mandelbrot集合の計算は、浮動小数点演算の性能を測るための一般的なベンチマークの一つとしてよく用いられます。
Mandelbrot集合
Mandelbrot集合は、複素平面上の点cに対して、漸化式 z_{n+1} = z_n^2 + c
(ただし z_0 = 0
)で定義される数列 z_n
が無限大に発散しないような点cの集合です。この集合はフラクタル図形として知られ、非常に複雑で美しい構造を持っています。Mandelbrot集合の計算は、浮動小数点数の乗算、加算、比較といった基本的な演算を大量に行うため、CPUの浮動小数点演算ユニット(FPU)の性能を評価するのに適しています。
浮動小数点定数とコンパイラの最適化
浮動小数点定数とは、プログラムコード中に直接記述される小数点を含む数値(例: 3.14
, 1.0e-5
)のことです。コンパイラは、これらの定数をプログラムの実行可能コードに変換する際に、様々な最適化を適用することがあります。
Go言語では、浮動小数点定数を含む数値定数はデフォルトで「型なし(untyped)」として扱われます。これにより、コンパイル時にはfloat32
やfloat64
といった特定の浮動小数点型の精度を超えた、任意精度(arbitrary precision)で値を保持できます。コンパイラは、これらの型なし定数を含む計算をこの高精度で実行します。値が特定の浮動小数点型(例: float64
)に変換されるのは、型付き変数に代入されるか、特定の型を要求するコンテキストで使用される場合のみです。このアプローチにより、中間計算がすぐにfloat32
やfloat64
の限られた精度に切り捨てられる場合に発生する可能性のある精度損失を最小限に抑えます。
コンパイラの最適化には、以下のようなものがあります。
- 定数畳み込み (Constant Folding): コンパイル時に計算可能な定数式を事前に計算し、その結果をコードに埋め込む。これにより、実行時の計算が削減されます。
- 融合積和演算 (Fused Multiply-Add, FMA):
x * y + z
のような式に対して、基盤となるハードウェアがサポートしていれば、GoコンパイラはFMA命令を利用する可能性があります。FMA演算は、乗算と加算を単一の操作として実行することで、パフォーマンスと精度の両方を向上させることができます。これにより、乗算と加算が別々に行われる場合に発生する中間的な丸めステップを回避できます。ただし、明示的な型キャストやメモリ位置への代入は、中間的な丸めを強制する可能性があります。 - 定数マージ (Constant Merging):
gccgo
のようなGo用のコンパイラは、異なるコンパイル単位間で同一の定数をマージして、最終的なバイナリサイズを削減することができます。
浮動小数点演算は、整数演算に比べて複雑で時間がかかることが多いため、コンパイラは浮動小数点定数の表現方法や、それらを用いた演算のコード生成において、特に慎重な最適化を行います。例えば、特定の浮動小数点定数をより効率的な形式で表現したり、計算の精度と速度のバランスを取ったりすることがあります。
このコミットの文脈では、Goコンパイラが浮動小数点定数をどのように内部的に表現し、それらを用いた演算の機械語コードをどのように生成するかが、Mandelbrotベンチマークのパフォーマンスに大きな影響を与えていたと考えられます。以前の変更が、何らかの理由でこのコード生成を非効率にしてしまい、その後の修正で元の効率的なコード生成が復元された、という流れです。
技術的詳細
このコミットは、Go言語のコンパイラが浮動小数点定数を扱う際のコード生成戦略の変更が、ベンチマークのパフォーマンスに与える影響を示しています。
http://codereview.appspot.com/6209077
で言及されている変更は、おそらくGoコンパイラの内部的な浮動小数点定数の表現方法や、それらを用いた演算の最適化に関するものでした。Mandelbrot集合の計算は、複素数の乗算と加算を繰り返し行うため、浮動小数点演算が非常に頻繁に発生します。もしコンパイラが浮動小数点定数を非効率な方法で処理したり、それらを含む演算に対して最適な機械語命令を生成できなかったりすると、プログラム全体の実行速度に大きな影響が出ます。
例えば、以下のようなケースが考えられます。
- 精度の問題: 浮動小数点定数の内部表現が、計算に必要な精度を十分に持たず、実行時に余分な丸め誤差や変換処理が発生した。Goの型なし定数は高精度を保ちますが、最終的に型付き変数に変換される際に精度が失われる可能性があります。
- 命令選択の非効率化: 特定の浮動小数点演算に対して、CPUのFPUが提供する高速な命令(例: FMA)ではなく、より汎用的だが低速な命令が選択された。
- レジスタ利用の非最適化: 浮動小数点定数や中間結果が効率的にレジスタに割り当てられず、頻繁なメモリアクセスが発生した。
http://codereview.appspot.com/6261051
の変更は、これらの問題に対処するために、以前の(より効率的だった)浮動小数点定数に対するコード生成ロジックを復元したと考えられます。これにより、Mandelbrotベンチマークが以前のパフォーマンスレベルに戻ったことは、この修正が成功し、Goコンパイラが浮動小数点演算を再び効率的に処理できるようになったことを示しています。
timing.log
に記録されている数値は、各ベンチマークの実行時間(または関連するメトリクス)を示しています。
gcc -O2 mandelbrot.c
: C言語版のMandelbrotプログラムをGCCコンパイラで最適化レベル-O2でコンパイルして実行した結果。これは比較のベースラインとなります。gccgo -O2 mandelbrot.go
: Go言語版のMandelbrotプログラムをgccgoコンパイラで最適化レベル-O2でコンパイルして実行した結果。gccgo
はGCCのフロントエンドとしてGoをサポートするコンパイラです。gc mandelbrot
: Go言語版のMandelbrotプログラムをGoの公式コンパイラ(gc)でコンパイルして実行した結果。gc_B mandelbrot
: Go言語版のMandelbrotプログラムをGoの公式コンパイラ(gc)で、おそらく特定のビルドオプション(例えば、より新しいバージョンや異なる最適化設定)でコンパイルして実行した結果。
これらの数値が以前の良好な状態に戻ったことは、Goコンパイラの浮動小数点演算の性能が回復したことを定量的に示しています。Goのfloat32
とfloat64
型はIEEE 754標準に準拠していますが、この標準はバイナリ表現の性質上、すべての10進数を正確に表現できるわけではないため、計算に小さな丸め誤差が生じる可能性があります。もしfloat64
の精度が不十分な場合(例: 金融計算)、Goは標準ライブラリのmath/big
パッケージで任意精度浮動小数点演算を提供するbig.Float
や、github.com/shopspring/decimal
のようなサードパーティの10進数ライブラリといった代替手段を提供しています。
コアとなるコードの変更箇所
このコミットは、test/bench/shootout/timing.log
ファイルに以下の9行を追加しています。
--- a/test/bench/shootout/timing.log
+++ b/test/bench/shootout/timing.log
@@ -1022,3 +1022,12 @@ mandelbrot (much slower, due to unrelated http://codereview.appspot.com/6209077)
meteor 2098
gc meteor-contest 0.13u 0.00s 0.13r # -13%
gc_B meteor-contest 0.13u 0.00s 0.13r # -7%
+
+# After http://codereview.appspot.com/6261051, restoring old code generated
+# for floating-point constants. Mandelbrot is back to its previous numbers.
+
+mandelbrot 16000
+ gcc -O2 mandelbrot.c 36.07u 0.00s 36.16r
+ gccgo -O2 mandelbrot.go 41.72u 0.01s 41.90r
+ gc mandelbrot 60.62u 0.00s 60.76r
+ gc_B mandelbrot 60.68u 0.00s 60.82r
コアとなるコードの解説
追加された行は、timing.log
ファイル内のベンチマーク結果のセクションを更新しています。
-
# After http://codereview.appspot.com/6261051, restoring old code generated
# for floating-point constants. Mandelbrot is back to its previous numbers.
この2行はコメントであり、今回の変更の理由を説明しています。http://codereview.appspot.com/6261051
で示されるコードレビューが適用された後、浮動小数点定数に対して生成されるコードが以前の状態に戻され、その結果Mandelbrotベンチマークの数値も以前の良好な状態に戻ったことを明記しています。 -
mandelbrot 16000
これはMandelbrotベンチマークの新しいエントリです。16000
という数値は、おそらくベンチマークの入力サイズや、特定の実行条件を示すIDのようなものです。 -
gcc -O2 mandelbrot.c 36.07u 0.00s 36.16r
C言語版のMandelbrotベンチマークの実行結果です。36.07u
: ユーザーCPU時間(user CPU time)0.00s
: システムCPU時間(system CPU time)36.16r
: リアル時間(real time、または経過時間) これらの数値は、C言語版のMandelbrotが約36秒で完了したことを示しています。これは、Go言語版のパフォーマンスを評価するための基準となります。
-
gccgo -O2 mandelbrot.go 41.72u 0.01s 41.90r
Go言語版のMandelbrotベンチマークをgccgo
コンパイラでコンパイルして実行した結果です。gccgo
はGCCのフロントエンドとしてGoをサポートするコンパイラです。約41.9秒で完了しています。 -
gc mandelbrot 60.62u 0.00s 60.76r
Go言語版のMandelbrotベンチマークをGoの公式コンパイラ(gc
)でコンパイルして実行した結果です。約60.76秒で完了しています。 -
gc_B mandelbrot 60.68u 0.00s 60.82r
Go言語版のMandelbrotベンチマークをGoの公式コンパイラ(gc
)で、おそらく特定のビルド構成(例えば、異なる最適化フラグや、より新しい開発ブランチなど)でコンパイルして実行した結果です。約60.82秒で完了しています。
これらの数値がtiming.log
に追加されたことで、Goコンパイラの浮動小数点定数処理の改善が、Mandelbrotベンチマークの実行時間に明確な影響を与え、以前のパフォーマンスレベルに回復したことが公式に記録されました。
関連リンク
- Go言語のコードレビューシステム (Gerrit): https://go-review.googlesource.com/
- The Computer Language Benchmarks Game: https://benchmarksgame-team.pages.debian.net/benchmarksgame/
- Mandelbrot集合 - Wikipedia: https://ja.wikipedia.org/wiki/%E3%83%9E%E3%83%B3%E3%83%87%E3%83%AB%E3%83%96%E3%83%AD%E3%83%BC%E3%83%88%E9%9B%86%E5%90%88
参考にした情報源リンク
http://codereview.appspot.com/6259054
(Go Gerrit CL)http://codereview.appspot.com/6209077
(Mandelbrotベンチマークのパフォーマンス低下に関連する以前のCL)http://codereview.appspot.com/6261051
(浮動小数点定数のコード生成を復元したCL)- Go言語の公式ドキュメント (コンパイラ、ベンチマークに関する情報)
- GCC (GNU Compiler Collection) のドキュメント
- 浮動小数点数に関する一般的なコンピュータサイエンスの知識
- ベンチマークとパフォーマンス測定に関する一般的な知識
- Gitのコミットと差分表示に関する知識
time
コマンドの出力(user, system, real time)に関する知識- Go言語における浮動小数点定数の最適化に関するWeb検索結果