Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

[インデックス 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集合の計算は、複素数の乗算と加算を繰り返し行うため、浮動小数点演算が非常に頻繁に発生します。もしコンパイラが浮動小数点定数を非効率な方法で処理したり、それらを含む演算に対して最適な機械語命令を生成できなかったりすると、プログラム全体の実行速度に大きな影響が出ます。

例えば、以下のようなケースが考えられます。

  1. 精度の問題: 浮動小数点定数の内部表現が、計算に必要な精度を十分に持たず、実行時に余分な丸め誤差や変換処理が発生した。
  2. 命令選択の非効率化: 特定の浮動小数点演算に対して、CPUのFPUが提供する高速な命令ではなく、より汎用的だが低速な命令が選択された。
  3. レジスタ利用の非最適化: 浮動小数点定数や中間結果が効率的にレジスタに割り当てられず、頻繁なメモリアクセスが発生した。

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ファイル内のベンチマーク結果のセクションを更新しています。

  1. # 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ベンチマークの数値も以前の良好な状態に戻ったことを明記しています。

  2. mandelbrot 16000 これはMandelbrotベンチマークの新しいエントリです。16000という数値は、おそらくベンチマークの入力サイズや、特定の実行条件を示すIDのようなものです。

  3. 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言語版のパフォーマンスを評価するための基準となります。
  4. gccgo -O2 mandelbrot.go 41.72u 0.01s 41.90r Go言語版のMandelbrotベンチマークをgccgoコンパイラでコンパイルして実行した結果です。gccgoはGCCのフロントエンドとしてGoをサポートするコンパイラです。約41.9秒で完了しています。

  5. gc mandelbrot 60.62u 0.00s 60.76r Go言語版のMandelbrotベンチマークをGoの公式コンパイラ(gc)でコンパイルして実行した結果です。約60.76秒で完了しています。

  6. gc_B mandelbrot 60.68u 0.00s 60.82r Go言語版のMandelbrotベンチマークをGoの公式コンパイラ(gc)で、おそらく特定のビルド構成(例えば、異なる最適化フラグや、より新しい開発ブランチなど)でコンパイルして実行した結果です。約60.82秒で完了しています。

これらの数値がtiming.logに追加されたことで、Goコンパイラの浮動小数点定数処理の改善が、Mandelbrotベンチマークの実行時間に明確な影響を与え、以前のパフォーマンスレベルに回復したことが公式に記録されました。

関連リンク

参考にした情報源リンク

  • 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)」として扱われます。これにより、コンパイル時にはfloat32float64といった特定の浮動小数点型の精度を超えた、任意精度(arbitrary precision)で値を保持できます。コンパイラは、これらの型なし定数を含む計算をこの高精度で実行します。値が特定の浮動小数点型(例: float64)に変換されるのは、型付き変数に代入されるか、特定の型を要求するコンテキストで使用される場合のみです。このアプローチにより、中間計算がすぐにfloat32float64の限られた精度に切り捨てられる場合に発生する可能性のある精度損失を最小限に抑えます。

コンパイラの最適化には、以下のようなものがあります。

  • 定数畳み込み (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集合の計算は、複素数の乗算と加算を繰り返し行うため、浮動小数点演算が非常に頻繁に発生します。もしコンパイラが浮動小数点定数を非効率な方法で処理したり、それらを含む演算に対して最適な機械語命令を生成できなかったりすると、プログラム全体の実行速度に大きな影響が出ます。

例えば、以下のようなケースが考えられます。

  1. 精度の問題: 浮動小数点定数の内部表現が、計算に必要な精度を十分に持たず、実行時に余分な丸め誤差や変換処理が発生した。Goの型なし定数は高精度を保ちますが、最終的に型付き変数に変換される際に精度が失われる可能性があります。
  2. 命令選択の非効率化: 特定の浮動小数点演算に対して、CPUのFPUが提供する高速な命令(例: FMA)ではなく、より汎用的だが低速な命令が選択された。
  3. レジスタ利用の非最適化: 浮動小数点定数や中間結果が効率的にレジスタに割り当てられず、頻繁なメモリアクセスが発生した。

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のfloat32float64型は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ファイル内のベンチマーク結果のセクションを更新しています。

  1. # 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ベンチマークの数値も以前の良好な状態に戻ったことを明記しています。

  2. mandelbrot 16000 これはMandelbrotベンチマークの新しいエントリです。16000という数値は、おそらくベンチマークの入力サイズや、特定の実行条件を示すIDのようなものです。

  3. 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言語版のパフォーマンスを評価するための基準となります。
  4. gccgo -O2 mandelbrot.go 41.72u 0.01s 41.90r Go言語版のMandelbrotベンチマークをgccgoコンパイラでコンパイルして実行した結果です。gccgoはGCCのフロントエンドとしてGoをサポートするコンパイラです。約41.9秒で完了しています。

  5. gc mandelbrot 60.62u 0.00s 60.76r Go言語版のMandelbrotベンチマークをGoの公式コンパイラ(gc)でコンパイルして実行した結果です。約60.76秒で完了しています。

  6. gc_B mandelbrot 60.68u 0.00s 60.82r Go言語版のMandelbrotベンチマークをGoの公式コンパイラ(gc)で、おそらく特定のビルド構成(例えば、異なる最適化フラグや、より新しい開発ブランチなど)でコンパイルして実行した結果です。約60.82秒で完了しています。

これらの数値がtiming.logに追加されたことで、Goコンパイラの浮動小数点定数処理の改善が、Mandelbrotベンチマークの実行時間に明確な影響を与え、以前のパフォーマンスレベルに回復したことが公式に記録されました。

関連リンク

参考にした情報源リンク

  • 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検索結果