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

[インデックス 16488] ファイルの概要

このコミットは、Go言語のプロファイリングツールであるpprofにおいて、特定の内部メモリ割り当て関数であるcnewおよびruntime.cnewarrayがプロファイル結果に表示されないようにするための変更です。これらの関数は、Goランタイムの内部でメモリ割り当てをラップするために使用されており、プロファイリングの目的である「ユーザーコードのパフォーマンスボトルネックの特定」においては「興味深い」情報ではないため、プロファイルから除外されるように設定されました。これにより、プロファイル結果がよりクリーンになり、開発者がアプリケーションの実際のパフォーマンス問題に集中できるようになります。

コミット

  • コミットハッシュ: 902ee9ae8f21d2a3bb570f66c0d082b9b1cce76b
  • Author: Rémy Oudompheng oudomphe@phare.normalesup.org
  • Date: Wed Jun 5 00:40:49 2013 +0200
  • コミットメッセージ:
    misc/pprof: register cnew and runtime.cnewarray as malloc wrappers.
    
    These functions were introduced by revision 139919984600
    and should not show up on profiles for consistency.
    
    R=golang-dev, iant
    CC=golang-dev
    https://golang.org/cl/10003043
    

GitHub上でのコミットページへのリンク

https://github.com/golang/go/commit/902ee9ae8f21d2a3bb570f66c0d082b9b1cce76b

元コミット内容

commit 902ee9ae8f21d2a3bb570f66c0d082b9b1cce76b
Author: Rémy Oudompheng <oudomphe@phare.normalesup.org>
Date:   Wed Jun 5 00:40:49 2013 +0200

    misc/pprof: register cnew and runtime.cnewarray as malloc wrappers.
    
    These functions were introduced by revision 139919984600
    and should not show up on profiles for consistency.
    
    R=golang-dev, iant
    CC=golang-dev
    https://golang.org/cl/10003043
---
 misc/pprof | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/misc/pprof b/misc/pprof
index f471c73951..5a43b66d2c 100755
--- a/misc/pprof
+++ b/misc/pprof
@@ -2616,6 +2616,7 @@ sub RemoveUninterestingFrames {
                       'operator new[]',
                       # Go
                       'catstring',
+                      'cnew',
                       'copyin',
                       'gostring',
                       'gostringsize',
@@ -2640,6 +2641,8 @@ sub RemoveUninterestingFrames {
                       'unsafe.New',
                       'runtime.mallocgc',
                       'runtime.catstring',
+                      'runtime.cnew',
+                      'runtime.cnewarray',
                       'runtime.growslice',
                       'runtime.ifaceT2E',
                       'runtime.ifaceT2I',

変更の背景

Go言語のプロファイリングツールであるpprofは、プログラムの実行中にCPU時間やメモリ割り当てなどの情報を収集し、どの関数がリソースを多く消費しているかを可視化するのに役立ちます。しかし、プロファイル結果には、ユーザーが直接記述したコードだけでなく、Goランタイム内部の低レベルな関数も含まれることがあります。

このコミットの背景には、cnewおよびruntime.cnewarrayという関数がGoランタイムに導入されたことがあります。これらの関数は、内部的なメモリ割り当てのラッパーとして機能します。pprofの目的は、開発者がアプリケーションのパフォーマンスボトルネックを特定できるようにすることであり、Goランタイムの内部的なメモリ割り当て処理は、通常、開発者が直接最適化できる対象ではありません。

そのため、これらの内部関数がプロファイル結果に頻繁に表示されると、プロファイルがノイズで埋もれてしまい、本当に重要なユーザーコードのボトルネックが見えにくくなるという問題がありました。この変更は、pprofの出力からこれらの「興味深い」ではないフレームを除外することで、プロファイル結果の一貫性と可読性を向上させることを目的としています。これにより、開発者はより効率的にパフォーマンス分析を行うことができます。

前提知識の解説

pprof (Goプロファイリングツール)

pprofは、Go言語に標準で付属するプロファイリングツールです。Goプログラムの実行中に、CPU使用率、メモリ割り当て、ゴルーチン、ブロック、ミューテックス競合などのプロファイルデータを収集し、それを視覚的に分析するための機能を提供します。

  • CPUプロファイル: プログラムがCPU時間をどこで消費しているかを示します。一定間隔で実行中のスタックトレースをサンプリングすることでデータを収集します。
  • メモリプロファイル: プログラムがどこでメモリを割り当てているかを示します。ヒープ割り当ての情報を記録します。
  • フレームの除外: pprofは、プロファイル結果から特定の関数(フレーム)を除外する機能を持っています。これは、ランタイムの内部関数や、ユーザーが関心を持たない低レベルな処理をプロファイルから取り除くことで、結果をより分かりやすくするために使用されます。

Goランタイム

Goランタイムは、Goプログラムの実行を管理する低レベルな部分です。これには、ガベージコレクタ、スケジューラ、メモリ管理、プリミティブな操作(文字列操作、スライス操作など)が含まれます。Goプログラムがコンパイルされると、Goランタイムのコードもバイナリに組み込まれます。

メモリ割り当て (malloc)

コンピュータプログラムにおいて、メモリ割り当ては、プログラムが実行時に必要なメモリ領域を確保するプロセスです。C言語のmalloc関数のように、多くの言語にはメモリを動的に確保するためのメカニズムがあります。Go言語では、ユーザーが直接mallocを呼び出すことは稀ですが、makenewキーワード、スライスの拡張など、様々な操作の裏でランタイムがメモリ割り当てを行っています。

cnewcnewarray

コミットメッセージによると、cnewruntime.cnewarrayは、Goランタイム内部で導入された関数であり、メモリ割り当てのラッパーとして機能します。これらの関数は、Goの内部的なデータ構造やオブジェクトの生成時に使用される低レベルなプリミティブであると考えられます。例えば、新しいオブジェクトをヒープに割り当てたり、新しい配列を生成したりする際に、これらの関数が内部的に呼び出される可能性があります。

これらの関数がpprofのプロファイルから除外されるのは、それらがGoランタイムの内部実装の詳細であり、通常、アプリケーション開発者がこれらの関数のパフォーマンスを直接改善することはできないためです。プロファイリングの目的は、ユーザーが制御できるコードのボトルネックを特定することにあります。

技術的詳細

このコミットは、pprofスクリプト(Perlで書かれている)のRemoveUninterestingFramesサブルーチンに、cnewruntime.cnew、およびruntime.cnewarrayの3つの関数名を追加することで実現されています。

pprofは、プロファイルデータを解析し、コールスタック(関数呼び出しの連鎖)を分析します。RemoveUninterestingFramesサブルーチンは、プロファイル結果から特定の関数フレームを「興味深い」ではないものとしてフィルタリングするために使用されます。これは、プロファイルデータが生成された後、pprofツールがそのデータを処理する段階で行われます。

具体的には、pprofはプロファイルデータ内の各スタックフレームの関数名をチェックし、RemoveUninterestingFramesサブルーチン内のリストに含まれる関数名と一致する場合、そのフレームをプロファイル結果から除外します。これにより、プロファイルグラフやレポートにこれらの関数が表示されなくなり、開発者はより高レベルなアプリケーションロジックのパフォーマンスに集中できます。

このアプローチは、プロファイリングのオーバーヘッドを減らすのではなく、プロファイル結果の解釈を容易にすることを目的としています。Goランタイムの内部関数は、Goプログラムの実行に不可欠であり、それらの呼び出し自体を避けることはできません。しかし、それらがプロファイル結果に表示されることで、開発者が誤ってそれらを最適化の対象と見なしてしまうことを防ぎます。

コミットメッセージにある「revision 139919984600」は、cnewruntime.cnewarrayが導入されたGoランタイムの特定の変更セットを指しています。このリビジョン番号は、Goの内部的なバージョン管理システム(おそらくMercurialのチェンジセットID)に関連している可能性があり、公開されているGitリポジトリのコミットハッシュとは直接対応しない場合があります。しかし、この記述は、これらの関数が比較的新しく導入されたものであり、それらがpprofのフィルタリングリストに追加される必要が生じたことを示しています。

コアとなるコードの変更箇所

変更はmisc/pprofファイルに対して行われました。

--- a/misc/pprof
+++ b/misc/pprof
@@ -2616,6 +2616,7 @@ sub RemoveUninterestingFrames {
                       'operator new[]',
                       # Go
                       'catstring',
+                      'cnew',
                       'copyin',
                       'gostring',
                       'gostringsize',
@@ -2640,6 +2641,8 @@ sub RemoveUninterestingFrames {
                       'unsafe.New',
                       'runtime.mallocgc',
                       'runtime.catstring',
+                      'runtime.cnew',
+                      'runtime.cnewarray',
                       'runtime.growslice',
                       'runtime.ifaceT2E',
                       'runtime.ifaceT2I',

コアとなるコードの解説

上記のdiffは、misc/pprofスクリプト内のRemoveUninterestingFramesというPerlサブルーチンへの変更を示しています。このサブルーチンは、プロファイル結果から除外すべき関数名のリストを定義しています。

  1. 'cnew', の追加: 'catstring'の下に'cnew'が追加されています。これは、Goランタイムの内部関数であるcnewが、プロファイル結果から除外されるべき「興味深い」ではないフレームとして認識されるようにします。

  2. 'runtime.cnew', の追加: 'runtime.mallocgc'の下に'runtime.cnew'が追加されています。これは、cnewruntimeパッケージ版(または完全修飾名)も同様に除外対象とすることを示しています。

  3. 'runtime.cnewarray', の追加: 'runtime.cnew'のすぐ下に'runtime.cnewarray'が追加されています。これは、配列のメモリ割り当てに関連する内部関数であるruntime.cnewarrayも、プロファイル結果から除外されるべきであることを意味します。

これらの変更により、pprofがプロファイルデータを処理する際に、これらの関数がコールスタックに現れても、それらは自動的にフィルタリングされ、最終的なプロファイルレポートや視覚化には含まれなくなります。これにより、開発者はアプリケーションのビジネスロジックやアルゴリズムに起因するパフォーマンスボトルネックに、より焦点を当てることができるようになります。

関連リンク

参考にした情報源リンク

  • Go言語のコミット履歴 (GitHub): https://github.com/golang/go/commit/902ee9ae8f21d2a3bb570f66c0d082b9b1cce76b
  • コミットメッセージの内容
  • pprofの一般的な動作に関する知識
  • Goランタイムのメモリ管理に関する一般的な知識
  • Web検索(golang revision 139919984600 cnew cnewarray)による情報収集(ただし、特定のrevisionに関する直接的な情報は得られず、一般的なGoランタイムの内部関数としての理解を深めるために利用)