(57)【要約】  コンピュータプログラムの性能プロファイリングのためのソースコード計測の方法は、親関数内の子関数の呼び出しサイトの近くに計測コードを生成し（１４）、挿入する（１９）ことを含む。計測コードは、タイミングレコードなど一意の計測レコードへの参照（１３）を使用する。計測コードは、親関数内の前の呼び出しサイトの出口時刻をその呼び出しサイトの入口時刻として使用するよう最適化され得る（１５）。計測コードは、子関数の呼び出し階層内のレベルに応じて挿入され、実行時における計測コードの実行の可否は、表示インターフェースを介して設定することのできる使用可能フラグの状態に応じて決まる。計測バージョンと非計測バージョンの２つのバージョンの子関数が生成され（１８）、どちらのバージョンが実行されるかは使用可能フラグによって決まる。【選択図】  図２
2009529742.tif 000002
【特許請求の範囲】
【請求項１】
コンピュータプログラムにおける、親関数によって呼び出される子関数の計測の方法であって、前記親関数内の前記子関数の呼び出しサイトの近くに計測コードを挿入するステップを含む方法。
【請求項２】
前記呼び出しサイトと前記子関数の組み合わせに固有の計測レコードへの参照を決定するステップと、
前記計測コードを、前記子関数の前記計測のための前記参照を使用するように構成するステップと
をさらに含む請求項１に記載の方法。
【請求項３】
前記参照が表中の前記計測レコードの場所を指し示す請求項２に記載の方法。
【請求項４】
前記計測レコードがタイミングレコードを含む請求項２または３に記載の方法。
【請求項５】
前記計測コードを、前記親関数内の前の呼び出しサイトの出口時刻を前記呼び出しサイトの入口時刻として使用するように最適化するステップをさらに含む請求項１〜４のいずれか一項に記載の方法。
【請求項６】
前記子関数の呼び出し階層のレベルに応じて前記計測コードを挿入するステップをさらに含む請求項１〜５のいずれか一項に記載の方法。
【請求項７】
前記計測コードを、前記コンピュータプログラムの実行時における前記計測コードの実行の可否が使用可能フラグの状態によって決まるように構成するステップをさらに含む請求項１〜６のいずれか一項に記載の方法。
【請求項８】
前記子関数の、一方が計測バージョンであり他方が非計測バージョンである２つのバージョンを生成するステップをさらに含む請求項１〜７のいずれか一項に記載の方法。
【請求項９】
前記計測コードを、前記コンピュータプログラムの実行時における前記計測コードの実行の可否が使用可能フラグの状態によって決まるように構成する前記ステップが、前記計測コードを、前記使用可能フラグの状態に応じて、前記子関数の前記計測バージョンまたは前記子関数の前記非計測バージョンを呼び出すように構成するステップをさらに含む請求項８に記載の方法。
【請求項１０】
表示インターフェースを、前記コンピュータプログラムの前記計測の結果を表示するように構成するステップと、
前記表示インターフェースの状態に応答して前記使用可能フラグを設定するステップと
をさらに含む請求項７〜９のいずれか一項に記載の方法。
【請求項１１】
前記計測コードを、生の時間測定を記録するように構成するステップと、
前記表示インターフェースの状態に応答して実行時に前記生の時間測定の一部をスケーリングするステップと
をさらに含む請求項１〜１０のいずれか一項に記載の方法。
【請求項１２】
少なくとも１台のコンピュータに前記請求項のいずれか一項の方法を実行させるプログラム命令を含む少なくとも１つのコンピュータプログラム。
【請求項１３】
記録媒体または読取り専用メモリ上で実施され、少なくとも１つのコンピュータメモリに格納され、あるいは電気的搬送信号上で搬送される請求項１２に記載の少なくとも１つのコンピュータプログラム。
【請求項１４】
請求項１〜１１のいずれか一項の方法を実行するように構成されたプロファイラ。
【請求項１５】
コンピュータにロードされると請求項１４に記載のプロファイラを構成するプログラム命令を含む少なくとも１つのコンピュータプログラム。
【請求項１６】
記録媒体または読取り専用メモリ上で実施され、少なくとも１つのコンピュータメモリに格納され、あるいは電気的搬送信号上で搬送される請求項１５に記載の少なくとも１つのコンピュータプログラム。
【発明の詳細な説明】
【技術分野】
【０００１】
本発明はコンピュータプログラムの性能プロファイリングに関し、詳細には性能プロファイリングのためのコンピュータプログラムの計測に関する。
【背景技術】
【０００２】
コンピュータプログラムの性能プロファイリングの分野では、関数の計測を使って、関数を実行するのに費やされる時間などといった性能情報が測定され、記録される。しかし、計測は、プロファイルされるプログラムの性能に影響を及ぼす。
【０００３】
性能への影響を低減するために、多くのプロファイリングツールは非リアルタイムで動作し、その場合、あるステップでタイミングが収集され、次いで別のステップで収集されたタイミングが表示される。ある特定の種類のプログラムではこれで十分であるが、ゲームの性能プロファイルは経時的に変化する傾向があり、一貫したフレーム率を達成するのに「フレーム時間」の概念が非常に重要であるため、ゲーム開発者にとっては、ゲームが実行されている間にタイミングを表示することのできるリアルタイムプロファイラの方がはるかに有用である。
【０００４】
既存のプロファイラでの別の問題は、それらが、様々な精度／完全性のトレードオフを行うことを必要とするが、ユーザは必ずしも行われるべきトレードオフを調整することができるとは限らず、したがって大部分の解決法では開発者に、せいぜいそのゲームの性能プロファイルの一部の状況が残されるにすぎない。
【０００５】
既存のプロファイリングツールは、おおまかに以下の２つの主な種類に分けることができる。
・計測プロファイラ
・サンプリングプロファイラ
以下でこれら２つのプロファイラの限界について簡単に論じる。
【０００６】
計測プロファイラは、プログラムのコードの各関数の先頭と末尾にタイミングルーチンを注入することによって動作する。各関数の先頭に加えられるルーチンは入口時刻をログ記録し、末尾に加えられるルーチンは出口時刻をログ記録する。
【０００７】
簡単にいうと、その場合、各関数に費やされた時間が出口時刻から入口時刻を差し引いたものとして計算される。
【０００８】
大部分の計測プロファイラは二進計測を使用し、その場合、プログラムのコンパイル済みのオブジェクトファイルが直接変更される。残念なことに、この二進計測はそうしたプロファイラの展開を、そのための二進計測システムが設計されているシステムだけに限定し、このためにほとんどすべての既存の二進計測プロファイラがゲームコンソールでの使用から除外される。
【０００９】
二進計測の代替法は、ソースコード計測を使用するものであり、その場合、プログラムのソースコードは、コンパイラに渡される前にオンザフライで変更される。このソースコード計測は、プロファイラを任意のプラットフォーム上で容易に展開させることを可能にする。
【００１０】
計測プロファイラは、大部分のプログラムで非常に正確な結果を達成することができるだけでなく、プログラムで行われるすべての関数呼び出しの階層ビューを示すそのプログラムの呼び出しグラフを取り込むこともできる。
【００１１】
この呼び出しグラフは、多くの異なる詳細レベルで、プログラムにおいてすべての時間がどこに費やされるかについての非常に完璧な状況説明を与えることができる。任意の所与の関数について、開発者は、どの関数がその関数を呼び出したか（および各関数が何回呼び出され、どれ程の時間を要したか）、ならびにその関数がどの関数を呼び出したか（および何回呼び出し、それぞれにどれ程の時間を費やしたか）を求めることができる。
【００１２】
この種の情報は、どこに大部分の最適化労力を集中すべきか決定するのに不可欠である。例えば、プロファイラが、プログラムがその時間の４０％を関数ｆに費やすと示すものとする。一見したところでは、開発者はｆを最適化するのにその労力を費やすべきであるように思われる。しかし、開発者が呼び出しグラフを調べると、ｆが実際には非常に高速であるが、呼び出される回数が非常に多いことに気づくこともある。その場合開発者は、可能であれば、ｆが呼び出される回数を低減することに労力を費やすことが最善であると判断し得る。
【００１３】
タイミングルーチンは実行時に以下を行う必要がある。
・現在時刻を獲得する。
・どの親関数が現在の関数を呼び出したか突き止める。
・この関数と親関数の組み合わせに固有の記憶スロットを作成／検索する。
【００１４】
計測プロファイラの問題は、そうした複雑なタイミングルーチンをあらゆる関数に加えることにより、実行時にプログラムに対して著しく余分な処理負荷がかかることであり、ほとんどの場合、このためにプログラムが数倍遅くなる。多くの用途ではこれは大きな問題ではないが、ゲームでは以下の２つの理由できわめて重大な問題である。
【００１５】
１）対話性  プロファイリングルーチンがゲームを過度に遅くする場合、プレーすることが不可能になり、そのために正常にプロファイルすることが困難に、または不可能になり得る。また、これにより、あらゆる形のリアルタイムタイミング結果も得られにくくなる。
２）非同期ハードウェア  プロファイラはプログラムコードをより遅く走らせるが、非同期ハードウェア（ＧＰＵなど）は引き続きこれの通常の速度で走り続ける。これは、このハードウェアが相対的に実際よりもずっと速い印象を与え、そのためにタイミング結果が著しく歪曲され、開発者を困惑させることになり得る。
【００１６】
計測プロファイラの代替手段がサンプリングプロファイラである。サンプリングプロファイラは、タイミングルーチンを繰り返し呼び戻す高分解能タイマを走らせることによって動作する。これらの呼び戻しはメインプログラムを中断させる。
【００１７】
呼び出されると、タイミングルーチンは、それが直前にどの関数／スレッド／プロセスを中断させたか突き止め、その関数（およびスレッド／プロセス）のサンプルヒットをログ記録する。サンプリング間隔が終了すると、プロファイラは、これらのヒットカウントを使って、各関数（およびスレッド／プロセス）にプログラムの時間のどの割合が費やされたか判定する。
【００１８】
サンプリングプロファイラの主要な利点は、サンプリングプロファイラが計測プロファイラよりもプログラムの性能にずっと影響を及ぼしにくく、よって、計測プロファイラを悩ます対話性および非同期ハードウェアに伴う問題が少なくなることである。
【００１９】
しかし、サンプリングプロファイラの１つの基本的な問題は、タイミングの精度が呼び戻しタイマの頻度に依存することである。すなわち、この頻度が低すぎると、小さい関数ほどより少なく数えられることになりがちであり、完全に飛ばされることにさえなりかねない。残念ながら、タイマ頻度を上げすぎると、性能は計測プロファイラの性能まで落ち始めることになり、よって、計測プロファイラに優るサンプリングプロファイラの主要な利点がなくなる。
【００２０】
残念ながら、サンプリングプロファイラの基本的な問題はこれだけではない。サンプリングプロファイラのもう１つの主要な問題は、サンプリングプロファイラがプログラムの呼び出しグラフ情報を容易に、かつ／または正確に取り込むには、疑いなくサンプリングプロファイラが計測プロファイラに優る性能利得を著しく阻害しなければならないことである。
【発明の開示】
【発明が解決しようとする課題】
【００２１】
本発明の一目的は、計測されるコンピュータプログラムに対する計測の影響を低減することである。
【課題を解決するための手段】
【００２２】
本発明の第１の態様によれば、コンピュータプログラムにおける、親関数によって呼び出される子関数の計測の方法であって、親関数内の子関数の呼び出しサイトの近くに計測コードを挿入するステップを含む方法が提供される。
【００２３】
したがって、計測コードは、子関数を実際に呼び出すのにかかる時間を取り込む。
【００２４】
好ましくは、この方法は、
呼び出しサイトと子関数の組み合わせに固有の計測レコードへの参照を決定するステップと、
計測コードを、子関数の計測の参照を使用するように構成するステップと
をさらに含む。
【００２５】
好ましくは、参照は、表中の計測レコードの場所を指し示す。
【００２６】
好ましくは、計測レコードは、タイミングレコードを含む。
【００２７】
したがって、子関数にはもはやその親関数と子関数の組み合わせでのタイミングスロットへの参照を決定することを求める要件がないため、プロファイリングの実行時性能が改善される。
【００２８】
好ましくは、本方法は、計測コードを、親関数内の前の呼び出しサイトの出口時刻を、その呼び出しサイトの入口時刻として使用するように最適化するステップをさらに含む。
【００２９】
したがって、連鎖呼び出し間の比較的高価なシステムクロック値を獲得する動作が不要になり、これにより計測性能オーバーヘッドが低減する。
【００３０】
好ましくは、本方法は、子関数の呼び出し階層内のレベルに応じて計測コードを挿入するステップをさらに含む。
【００３１】
したがって、関数呼び出しの階層における各関数のレベルに応じて、各関数を選択的に計測したり、しなかったりすることができる。また、子関数が階層内のどこから呼び出されるかに応じて、個々の子関数を実行時の計測ありまたはなしで呼び出すこともできる。
【００３２】
好ましくは、本方法は、計測コードを、コンピュータプログラムの実行時における計測コードの実行の可否が使用可能フラグの状態に応じて決まるように構成するステップをさらに含む。
【００３３】
したがって、グローバルに、または個々の関数について、計測を実行時に動的にオンまたはオフに切換えることができる。
【００３４】
好ましくは、本方法は、子関数の、一方が計測バージョンであり他方が非計測バージョンである２つのバージョンを生成するステップをさらに含む。
【００３５】
好ましくは、計測コードを、コンピュータプログラムの実行時における計測コードの実行の可否が使用可能フラグの状態に応じて決まるように構成するステップは、計測コードを、使用可能フラグの状態に応じて子関数の計測バージョンまたは子関数の非計測バージョンを呼び出すように構成するステップをさらに含む。
【００３６】
好ましくは、本方法は、
表示インターフェースを、コンピュータプログラムの計測の結果を表示するように構成するステップと、
表示インターフェースの状態に応答して使用可能フラグを設定するステップと
をさらに含む。
【００３７】
したがって、実行時に検査される関数のレベルおよびグループについてのみ計測を実行時に動的にオンに切換えることができ、それによってプロファイルされるコンピュータプログラムの実行時のプロファイリングオーバーヘッドが低減する。
【００３８】
好ましくは、本方法は、
計測コードを、生の時間測定を記録するように構成するステップと、
表示インターフェースの状態に応答して実行時に生の時間測定の一部をスケーリングするステップと
をさらに含む。
【００３９】
本発明の第２の態様によれば、少なくとも１台のコンピュータに第１の態様による方法を実行させるプログラム命令を含む少なくとも１つのコンピュータプログラムが提供される。
【００４０】
本発明の第３の態様によれば、第１の態様による方法を実行するように構成されたプロファイラが提供される。
【００４１】
本発明の第４の態様によれば、コンピュータにロードされると、第３の態様によるプロファイラを構成するプログラム命令を含む少なくとも１つのコンピュータプログラムが提供される。
【００４２】
好ましくは、少なくとも１つのコンピュータプログラムは、記録媒体または読取り専用メモリ上で実施され、少なくとも１つコンピュータメモリに格納され、あるいは電気的搬送波信号上で搬送される。
【００４３】
次に本発明を、例として示すにすぎないが、添付の図を参照して説明する。
【００４４】
本発明の各実施形態は、コンパイル／時間メタプログラミングを使ってプログラムのソースコード計測を行う計測方式を提供する。
【００４５】
以下に、従来技術のソースコード計測関数の非常に簡単な一例を提示する。
ｖｏｉｄ  ＡＦｕｎｃｔｉｏｎ（）
｛
／／プロファイラ注入コード
Ｐｒｏｆｉｌｅｒ＿ＲｅｃｏｒｄＥｎｔｒｙ（"ＡＦｕｎｃｔｉｏｎ"）；
／／通常の関数コード
…
／／プロファイラ注入コード
Ｐｒｏｆｉｌｅｒ＿ＲｅｃｏｒｄＥｘｉｔ（"ＡＦｕｎｃｔｉｏｎ"）；
｝
【００４６】
ソースコード計測方式を選択すると、直ちに、事実上すべての展開上の問題が解決される。プロファイリングエンジンおよび計測ルーチンはソースコードに組み込まれるため、プロファイラは、本質的に、ターゲットコンパイラによって無償で展開されることになる。必要とされる唯一のプラットフォーム特有の作業は、ターゲットシステムのクロックを読み取るルーチンの作成だけであり、これは相対的に微々たるものにすぎない。
【００４７】
また、計測方式の使用は、正確で完全な結果が保証され得ることも意味する。しかし、性能の問題、およびリアルタイム動作に影響を及ぼす関連問題は依然として残る。
【００４８】
計測プロファイラの性能を、サンプリングプロファイラによって達成される性能レベルまで（およびそれ以上に）高めるためには、まず、サンプリングプロファイラが一般に実施に際して大幅に安くつくのはなぜか考察する必要がある。
【００４９】
その違いは以下のとおりである。
・実行時の演算が安くつくサンプリングプロファイラは、各タイミング演算に際してその近くのどこでも同量の作業を行う必要がない。
・演算数が少ないサンプリングプロファイラは、はるかに少数のタイミング演算を生じる傾向にある。
【００５０】
本発明は、以下で論じるように、それぞれ順に、これら両方の違いを目標とするものである。
【００５１】
サンプリングプロファイラの実行時のタイミング演算がより安くつく理由は、サンプリングプロファイラには行うべき動作がほとんどないことである。非常に単純なサンプリングプロファイラは、各演算ごとバッファの末尾にプログラムカウンタを格納するだけでよい。複数のスレッドおよびプロセスと共に動作するより完全なバージョンでは、現在のスレッドおよびプロセスを決定し、スレッド及びプロセスを格納することも必要になるが、それでもなお、ほとんどの場合これは全く少量の作業ですむ。
【００５２】
これと比較すると、前述のように、計測プロファイラは、実行時に以下を行う必要がある。
・現在時刻を獲得する。
・どの親関数が現在の関数を呼び出したか突き止める。
・この関数と親関数の組み合わせに固有の記憶スロットを作成／検索する。
【００５３】
後の２つのステップが必要とされるのは、図１に示すように、（呼び出しグラフを生成する目的で）親関数と子関数の各組み合わせごとに別々のタイミングを格納するためである。図１には、親関数と子関数の各組み合わせごとの固有のタイミングの格納が示されている。
【００５４】
図１を参照すると、関数Ｃ１の２組のタイミングレコードがタイミング表２に格納されており、１つのレコード３は関数Ｃ１が親関数Ａ４によっていつ呼び出されるかについてであり、別のレコード５は関数Ｃ１が親関数Ｂ６によっていつ呼び出されるかについてである。
【００５５】
このステップの高価な部分は、実行時に、その親／子の組み合わせにどのスロットを使用すべきか決定する際のものである。
【００５６】
以下のコード部分で、タイミングスロットを直接参照するプロファイリング呼び出しが、呼び出される関数の先頭および末尾に置かれるときの問題を示す。
ｖｏｉｄ  Ｆｕｎｃｔｉｏｎ＿Ｃ（）
｛
Ｐｒｏｆｉｌｅｒ＿ＲｅｃｏｒｄＥｎｔｒｙ（６５）；
…
Ｐｒｏｆｉｌｅｒ＿ＲｅｃｏｒｄＥｘｉｔ（６５）；
｝
【００５７】
この例では、プロファイラレコード関数（これらの関数は例示のために示すものにすぎず、実際には、通常インラインコードである）への呼び出しは、所定のスロット番号（６５）を使用し、この番号は偶然にもＡ／Ｃ関数組み合わせのスロット番号である。これに伴う問題は、Ｂ／Ｃ関数組み合わせも記録しようとする場合に、その組み合わせのスロット番号と共にＦｕｎｃｔｉｏｎ＿Ｃの別のコピーが必要になることである。これは、特にＦｕｎｃｔｉｏｎ＿Ｃが大きい場合には、ずいぶんと無駄である。
【００５８】
本発明によれば、プロファイラレコード呼び出しは、むしろ、以下に示すように親関数内の呼び出しサイトの近く（すなわち、この実施形態では、Ｆｕｎｃｔｉｏｎ＿ＡとＦｕｎｃｔｉｏｎ＿Ｂの内部）に置かれる。
ｖｏｉｄ  Ｆｕｎｃｔｉｏｎ＿Ａ（）
｛
…
Ｐｒｏｆｉｌｅｒ＿ＲｅｃｏｒｄＥｎｔｒｙ（６５）；
Ｆｕｎｃｔｉｏｎ＿Ｃ（）；
Ｐｒｏｆｉｌｅｒ＿ＲｅｃｏｒｄＥｘｉｔ（６５）；
…
｝
ｖｏｉｄ  Ｆｕｎｃｔｉｏｎ＿Ｂ（）
｛
…
Ｐｒｏｆｉｌｅｒ＿ＲｅｃｏｒｄＥｎｔｒｙ（１４３）；
Ｆｕｎｃｔｉｏｎ＿Ｃ（）；
Ｐｒｏｆｉｌｅｒ＿ＲｅｃｏｒｄＥｘｉｔ（１４３）；
…
｝
【００５９】
この場合、Ｆｕｎｃｔｉｏｎ＿Ｃへの呼び出しごとに一意のプロファイラレコード呼び出しの対があり、対の１つはＦｕｎｃｔｉｏｎ＿Ａからのものであり、１つはＦｕｎｃｔｉｏｎ＿Ｂからのものであり、各対は独自の一意のスロット番号を有し、実行時には何も計算されない。
【００６０】
よって、本発明の一実施形態のソースコード計測は、実行時に計算を行うことを全く必要とせずに、全プログラム内のほとんどあらゆる親／子呼び出しパスを事前に計算し、正しいタイミングスロットを使用するコードを注入する。
【００６１】
この手法の利点は、結果として生じるタイミングが、関数を実際に呼び出すのにかかる時間を考慮に入れることである。従来技術の手法ではこの情報が失われるが、この情報は、プログラム性能を改善するために関数がインライン化されるべきかどうか判断しようとするときに役立ち得る。
【００６２】
呼び出しサイトタイミングを使用すれば、計測プロファイリングの性能を改善する機会がさらに開かれる。コードは、一般には、様々な量の論理で隔てられた関数呼び出しのシーケンスからなるため、以下の例に示すように、計測されるコードの多くのセクションが時間的に連続した関数呼び出しのシーケンスからなることは理にかなっている。
（ｖｏｉｄ  ＦｕｎｃｔｉｏｎＡ（）
｛
Ｐｒｏｆｉｌｅｒ＿ＲｅｃｏｒｄＥｎｔｒｙ（６５）；
Ｆｕｎｃｔｉｏｎ＿Ｂ（）；
Ｐｒｏｆｉｌｅｒ＿ＲｅｃｏｒｄＥｘｉｔ（６５）；
Ｐｒｏｆｉｌｅｒ＿ＲｅｃｏｒｄＥｎｔｒｙ（３３）；
Ｆｕｎｃｔｉｏｎ＿Ｃ（）；
Ｐｒｏｆｉｌｅｒ＿ＲｅｃｏｒｄＥｘｉｔ（３３）；
Ｐｒｏｆｉｌｅｒ＿ＲｅｃｏｒｄＥｎｔｒｙ（１３４）；
Ｆｕｎｃｔｉｏｎ＿Ｄ（）；
Ｐｒｏｆｉｌｅｒ＿ＲｅｃｏｒｄＥｘｉｔ（１３４）；
Ｐｒｏｆｉｌｅｒ＿ＲｅｃｏｒｄＥｎｔｒｙ（１１）；
Ｆｕｎｃｔｉｏｎ＿Ｅ（）；
Ｐｒｏｆｉｌｅｒ＿ＲｅｃｏｒｄＥｘｉｔ（１１）；
｝
【００６３】
プロファイラレコードステップはそれぞれシステムクロック値を獲得する必要があり、これは、特に親／子スロット計算オーバーヘッドを除去してしまっている以上、ステップの残りの部分と比べて相対的に高価な動作である。
【００６４】
例示のコードを見ると、（最後の関数以外のすべての関数で）ある関数呼び出しの末尾のところのＲｅｃｏｒｄＥｘｉｔ呼び出しの直後に次の呼び出しのＲｅｃｏｒｄＥｎｔｒｙ呼び出しが続いていることが分かる。隣接するＲｅｃｏｒｄＥｘｉｔ呼び出しとＲｅｃｏｒｄＥｎｔｒｙ呼び出しの間には測定可能な時間差がないため、次のＲｅｃｏｒｄＥｎｔｒｙ呼び出しにはＲｅｃｏｒｄＥｘｉｔ呼び出しからの記録時間値を使用すれば十分なはずである。
【００６５】
実際、２つの関数呼び出しの中間に何らかの論理がある場合にも、これらの間には測定可能な時間が経過していないと仮定することも許容される。
【００６６】
以下のコードで少量の論理によって隔てられた関数呼び出しのシーケンスを示す。
ｖｏｉｄ  ＦｕｎｃｔｉｏｎＡ（）
｛
ｂｏｏｌ  ｂ  ＝Ｆｕｎｃｔｉｏｎ＿Ｂ（）；
ｉｆ（ｂ）
Ｆｕｎｃｔｉｏｎ＿Ｃ（）；
Ｆｕｎｃｔｉｏｎ＿Ｄ（）；
｝
【００６７】
本発明に従って計測されるときには、以下のようなプロファイルされる関数呼び出しの連鎖シーケンスが獲得され、出口時刻が後続の入口時刻に再利用される。
ｖｏｉｄ  ＦｕｎｃｔｉｏｎＡ（）
｛
ｕｎｓｉｇｎｅｄ  ｉｎｔ  ｔｉｍｅ；
Ｐｒｏｆｉｌｅｒ＿ＲｅｃｏｒｄＥｎｔｒｙ（６５）；
ｂｏｏｌ  ｂ  ＝Ｆｕｎｃｔｉｏｎ＿Ｂ（）；
ｔｉｍｅ  ＝Ｐｒｏｆｉｌｅｒ＿ＲｅｃｏｒｄＥｘｉｔ（６５）；
ｉｆ（ｂ）
｛
Ｐｒｏｆｉｌｅｒ＿ＲｅｃｏｒｄＥｎｔｒｙ（３３，ｔｉｍｅ）；
Ｆｕｎｃｔｉｏｎ＿Ｃ（）；
ｔｉｍｅ  ＝Ｐｒｏｆｉｌｅｒ＿＿ＲｅｃｏｒｄＥｘｉｔ（３３）；
｝
Ｐｒｏｆｉｌｅｒ＿ＲｅｃｏｒｄＥｎｔｒｙ（７６，ｔｉｍｅ）；
Ｆｕｎｃｔｉｏｎ＿Ｄ（）；
Ｐｒｏｆｉｌｅｒ＿ＲｅｃｏｒｄＥｘｉｔ（７６）；
｝
【００６８】
コードからわかるように、この場合、システムクロックを再度照会する代わりに使用すべき時間値を受け入れるＲｅｃｏｒｄＥｎｔｒｙのバージョンがある。このバージョンは、この小規模な例でさえも２つの機会に使用され、その１つは、２つの連続する関数呼び出しの合間に少量の論理が入ることを許容するものである。
【００６９】
２つの関数呼び出しを異なる入口／出口時刻を有するものであるとみなすまでに受け入れるべき分離論理の量については議論の余地がある。この議論は、ユーザが受け入れられる量を制御することによって回避され得る。
【００７０】
これまでは、ＲｅｃｏｒｄＥｎｔｒｙ呼び出しおよびＲｅｃｏｒｄＥｘｉｔ呼び出しを関数呼び出しとして示してきたが、前述のように、これらを関数呼び出しとして実施する必要は全くなく、直接インライン化されたコード断片として実施されてもよい。
【００７１】
標準の入口コード断片は、（親／子スロット番号を６５とすると）以下のようなものになる。
ｔｉｍｅｓｌｏｔ［６５］＋＝ＧｅｔＳｙｓｔｅｍＣｌｏｃｋ（）；
【００７２】
また、対応する出口コード断片は以下のようになる。
ｔｉｍｅｓｌｏｔ［６５］  −＝ＧｅｔＳｙｓｔｅｍＣｌｏｃｋ（）；
【００７３】
加算の結合的特性のおかげで、単にクロック値全部を加算し次いで減算することによって、入口時刻と出口時刻の間の差を計算するために中間時刻を格納しなくてもよくなることに留意されたい。また、これはスロット６５が、（再帰的関数などにおいて）コードのこれら２行の間で再使用される場合でさえも当てはまる。
【００７４】
前述のような連鎖した出口／入口対を有する場合には、以下のようなコードになる。
ｕｎｓｉｇｎｅｄ  ｉｎｔ  ＿ｓｔｏｐＴｉｍｅ＿００５  ＝
ＧｅｔＳｙｓｔｅｍＣｌｏｃｋ（）；
ｔｉｍｅｓｌｏｔ［６５］  −＝＿ｓｔｏｐＴｉｍｅ＿００５；
ｔｉｍｅｓｌｏｔ［１５２］＋＝＿ｓｔｏｐＴｉｍｅ＿００５；
【００７５】
変数「＿ｓｔｏｐＴｉｍｅ＿００５」は、現在のプログラム有効範囲内で一意であることが保証される生成変数である。また、あらゆる連鎖対に一意の変数を使用するのではなく、可能な場合にはこれらを再利用する。ほとんどの場合、実際にはただ１つの変数ですむ。
【００７６】
これらの例には、依然としてＧｅｔＳｙｓｔｅｍＣｌｏｃｋ（）という明らかな関数呼び出しがある。またこの呼び出しはコードの中に直接インライン化されるが、使用される正確なコードはシステムによって異なる。
【００７７】
以下の例で、Ｉｎｔｅｌ  ｘ８６ＣＰＵを備え、システムクロックが、アセンブリ言語およびＲＤＴＳＣ（ＲｅａＤ  Ｔｉｍｅ  Ｓｔａｍｐ  Ｃｏｕｎｔｅｒ）命令を使ってインラインでサンプリングされるシステム上で表示される際の入口コード断片を示す。
＿ｉｎｔ６４  ＿ｔｉｍｅ；
＿ａｓｍ
｛
ｒｄｔｓｃ
ｍｏｖ  ｅｓｉ，＿ｔｉｍｅ
ｍｏｖ［ｅｓｉ  ］，ｅａｘ
ｍｏｖ［ｅｓｉ＋４］，ｅｄｘ
｝
ｔｉｍｅＳｌｏｔ［６５］＋＝＿ｔｉｍｅ；
【００７８】
例で分かるように、これはかなり短いコードシーケンスである。アセンブリ命令はすべて比較的高速であり、そのため、各関数呼び出しの先頭および末尾におけるこのコードシーケンスの有無がプログラムの性能に及ぼす可能な影響は最小限ですむ。
【００７９】
ｘ８６サンプルコードから分かるように、入口／出口シーケンスの費用は絶対最小値に保たれ、これはプロファイラの性能への影響を最小限に抑えるのに役立つ。
【００８０】
残念ながら、システムクロックから返される値がプログラムタイミングの計算に直接役立つことはまれである。
【００８１】
例えば、Ｉｎｔｅｌ  ｘ８６プロセッサ上のＲＤＴＳＣ命令は、現在時刻をクロック刻みとして返すが、例えば、実時間の１秒間に対応するクロック刻みの数は、ＣＰＵのクロック速度に左右される。大部分のシステムで同種の表示差が生じる。
【００８２】
この問題を解決する標準的手法は、１秒間（または他の何らかの標準時間単位）に対して何クロック単位が対応するかをどうにかして求め、次いでこの関係を使って、クロック単位を時間単位に変換するための乗数値を求めるものである。この乗数値は、通常、一度計算するだけでよいが、実際の乗算はクロック値ごとに行われる必要がある。
【００８３】
この場合入口／出口シーケンスに１つ余分な乗算を加えることは大きな問題でないように思われるが、残念ながらこれは見かけほど単純ではない。変換プロセスがただ１つの乗算命令からなることはまれであり、本発明の目標は、これらの演算の費用を可能な限り低減することである。
【００８４】
この問題に対する解決法は、標準時間単位の値が実際に必要になるときまで変換を遅らせることであり、この値が必要になる回数は、プログラムが走っている間に生じる入口／出口呼び出しの合計数よりもずっと少ない。
【００８５】
この背後にある大前提は、標準時間単位のタイミングが必要になる状況においてのみ、それらのタイミングが人間に提示されるというものである。人間は何百万ものタイミングを一度に全部読み取ることができないため、ただユーザがその時々に見ている少数のタイミングについて標準単位に変換しさえすればよいのである。
【００８６】
この場合、ユーザが多くのより小さい関数のタイミングの集合を含む最上位関数を見ている可能性もあるが、そうした場合には、個々のタイミング値ではなく総合計に対する時間変換を行いさえすればよい。百分率についても同じことがいえる。合計時間のうちのある関数の百分率を計算しようとするときには、この計算をクロック時間で全く同様に簡単に行うことができる。
【００８７】
このように時間変換要件を最小限に抑えることによって、本発明では入口／出口コードシーケンスを可能な限り短く保つ。
【００８８】
前述のように、本発明の手法は、すべての親／子関数の組み合わせのタイミングを最小限の命令数でうまく記録する。特に、本発明の手法によって使用される命令の数はもはや、親／子関係でさえも把握しないサンプリングプロファイラによって通常使用される命令数よりも少ない。
【００８９】
しかし、これ自体では、本発明のプロファイラの性能をサンプリングプロファイラの性能まで高めるのに完全に十分とはいえない。というのは、サンプリングプロファイラは、一般に、演算数がより少なくてすむからであり、これについて以下で論じる。
【００９０】
サンプリングプロファイラは、通常、十分に有用な結果をもたらす頻度で実行されるように設定しさえすればよいため、計測プロファイラよりもタイミング演算数が少なくてすむ。この頻度は、普通、あらゆる関数の入口／出口を記録する計測プロファイラで見るはずのタイミング演算の頻度より若干小さい。
【００９１】
この戦略はある点まではかなりうまく働くが、結果としてサンプリングプロファイラの絶対精度は、計測プロファイラの精度よりも著しく低いものとなる。精度損失の大部分は、あまり頻繁に呼び出されない関数におけるものであり、そのためこれは妥当なトレードオフである。というのは、これらの関数はプログラム全体の性能プロファイルにさほど関与しないからである。
【００９２】
計測プロファイラで行うことができるのは、計測プロファイラが測定するプログラムの対象範囲を限定することである。すなわち、測定する範囲が狭いほど性能に与える影響が小さくなる。既存の計測プロファイラはすでにある程度までこれを行っているが、これは単に、ユーザに特定のモジュールおよび／または関数を手作業で除外させることを含むにすぎない。これにより計測プロファイラの使いやすさは向上するが、より自動化された手法の方が望ましい。
【００９３】
本発明は、プロファイラの有効範囲を制御する単純で、直観的なやり方を提供する。このやり方は、プログラマが、ある関数とその関数のすべての子孫（その関数が呼び出す関数および呼び出される関数が呼び出す関数および以下同様のもの）を計測すべきか（または、その方がより好都合な場合には、計測すべきでないか）指定することを可能にする。
【００９４】
二進計測方式でこれを行うための実際的なやり方はないが、本発明のメタプログラミング対応のソース計測方式は、これを非常に有効に達成するのに十分なプログラム情報を記録する。また、この方式は、メタプログラミングベースのものであるため、プログラマがどの関数をそれらのソースコード内で直接計測すべきか指定することも可能にする。
【００９５】
本発明の手法の別の非常に有用な特徴は、プログラマが、使用可能／使用不可切換えをどのレベルの深さまで有効にするか指定することができることである。これによりプログラマは、下位詳細をプロファイルする費用をかけずに、最初のいくつかのレベルの関数呼び出しの計測を使用可能にするだけで、あるサブシステムの全般的プロファイルを調べようとすることを容易に指定できるようになる。代替として、プログラマは、下位関数だけを調べようとしてもよい。
【００９６】
最終的には、プログラマにきるだけ負担をかけないようにするために、本発明の手法は、複数の関数をグループ化し、まとめて使用可能または使用不可にすることを可能にする。プログラマはこの手法を使って、容易に切換えることのできる１組の全般的プロファイリング戦略を構築することができる。
【００９７】
例えば、ゲーム開発者は以下のようなグループを構築し得る。
・メインの最上位関数およびメイン関数の下の３レベルの関数。
・全体の物理サブシステム。
・グラフィックスサブシステム内のメイン関数。
・グラフィックスサブシステム内の下位関数
・上記各グループの何らかの組み合わせ。
【００９８】
このフレキシブルモデルは、実際、熟練開発者が、プログラムをプロファイルし、最適化するときに自然に行いがちな傾向と一致する。熟練開発者はまずプログラム全体の性能プロファイルを調べ、これを使って、どの領域に次の段階の最適化を集中すべきか判断する。特定の領域を選択すると、開発者は、かなり長い間その領域に集中し、またはその領域を掘り下げてから、全体の視点に戻り、加えた変更がそのプログラム全体の性能に対してどんな影響を及ぼしているか調べる。
【００９９】
本発明の手法によれば、開発者はこれを、精度や性能を犠牲にすることなく比較的容易に行うことができる。少々の労力は必要であるが、これは大きな見返りに対する妥当な労力である。
【０１００】
ソースコードのレベルによるこの部分的計測のマイナス面は、計測グループをオンとオフに切換えることにより相当量の再コンパイルが生じ得ることである。
【０１０１】
系統立ったドリルダウン法を使用する熟練したプログラマにとっては、これは大きな問題ではないが、すべてのプログラマが忍耐強く、几帳面であるとは限らないので、発明者らは、コンパイル時間の切換えを事実上完全になくするために、本発明の方法をさらに拡張している。
【０１０２】
本発明は、プログラマおよびプロファイリングビューアの非熟練ユーザが実行時に計測グループをオンとオフに切換えることを可能にする。
【０１０３】
本発明はこれを、プログラム内のあらゆる関数の、計測ありと計測なしの２つのバージョンを生成することによって達成する。また、あらゆる計測グループのルートのところの関数には、そのルート関数の使用可能／使用不可フラグに基づき、どの子関数の組を呼び出すべきか決定する論理も与えられる。
【０１０４】
一例として以下の関数を考察する。これはルート計測関数になる。
ｖｏｉｄ  Ｆｕｎｃｔｉｏｎ＿Ａ（）
｛
Ｆｕｎｃｔｉｏｎ＿Ｂ（）；
Ｆｕｎｃｔｉｏｎ＿Ｃ（）；
｝
【０１０５】
関数Ｂと関数Ｃには、以下のように、２つのバージョンが生成されることになる。
・Ｆｕｎｃｔｉｏｎ＿Ｂ１（計測される）
・Ｆｕｎｃｔｉｏｎ＿Ｂ２（計測されない）
・Ｆｕｎｃｔｉｏｎ＿Ｃ１（計測される）
・Ｆｕｎｃｔｉｏｎ＿Ｃ２（計測されない）
【０１０６】
関数Ｂと関数Ｃは他の関数を呼び出し得る。呼び出される関数ごとに２つのバージョンが生成されることになり、これらの関数のすべての子孫についても同様である。
【０１０７】
任意の所与の関数にはいくつかのパスを介して到達することができるため、任意の関数の複数のコピーの生成は、すでに生成されている関数の生成を回避する関数レジストリを経由してもよい。
【０１０８】
例に戻って、次いでＦｕｎｃｔｉｏｎ＿Ａは、プロファイル実行パスと非プロファイル実行パスの両方を示す、以下のように見えるルート計測関数の拡張バージョンに変更される。
ｖｏｉｄ  Ｆｕｎｃｔｉｏｎ＿Ａ（）
｛
ｉｆ（ｐｒｏｆｉｌｅＥｎａｂｌｅｄ［１７］）
｛
Ｐｒｏｆｉｌｅｒ＿ＲｅｃｏｒｄＥｎｔｒｙ（６５）；
Ｆｕｎｃｔｉｏｎ＿Ｂ１（）；
Ｐｒｏｆｉｌｅｒ＿ＲｅｃｏｒｄＥｘｉｔ（６５）；
Ｐｒｏｆｉｌｅｒ＿ＲｅｃｏｒｄＥｎｔｒｙ（２３）；
Ｆｕｎｃｔｉｏｎ＿Ｃ１（）；
Ｐｒｏｆｉｌｅｒ＿ＲｅｃｏｒｄＥｘｉｔ（２３）；
｝
ｅｌｓｅ
｛
Ｆｕｎｃｔｉｏｎ＿Ｂ２（）；
Ｆｕｎｃｔｉｏｎ＿Ｃ２（）；
｝
｝
【０１０９】
ｐｒｏｆｉｌｅＥｎａｂｌｅｄ［１７］の値は、ルート関数１７（この例のＦｕｎｃｔｉｏｎ＿Ａに対応する）がプロファイルされるべきである場合には真であり、そうでない場合には偽であるブール値である。
【０１１０】
この新しいＦｕｎｃｔｉｏｎ＿Ａは、次いで、この関数のプロファイリングが使用可能とされているか否かに応じて、２つの経路のうちの１つをとる。どちらの経路も論理的観点から見ると同一である（この場合、どちらの経路もＦｕｎｃｔｉｏｎ＿Ｂを呼び出した後に続いてＦｕｎｃｔｉｏｎ＿Ｃを呼び出す）が、一方の経路では各呼び出しの近くでタイミング演算を行い、これらの関数の計測バージョンを呼び出すが、他方の経路ではこれを行わない。
【０１１１】
この場合、Ｆｕｎｃｔｉｏｎ＿Ｂ１とＦｕｎｃｔｉｏｎ＿Ｃ１は、どちらも計測されるため、これらの関数はその呼び出しの時間を測定してその子関数の計測バージョンを呼び出し、以下同様に続く。
【０１１２】
他方、Ｆｕｎｃｔｉｏｎ＿Ｂ２とＦｕｎｃｔｉｏｎ＿Ｃ２は、その関数呼び出しの時間を測定せず、その子関数の非計測バージョンを呼び出し、以下同様に続く。
【０１１３】
このセットアップでは、単にｐｒｏｆｉｌｅＥｎａｂｌｅｄ［１７］の値を変更するだけで、実行時にＦｕｎｃｔｉｏｎ＿Ａの下にある関数呼び出しの木全体を容易にオンとオフに切換えることができる。
【０１１４】
この技法を、深さ制御をサポートするようにさらに拡張することができる。前述のように、深さ制御は、プログラマが、使用可能／使用不可切換えをどのレベルまで有効にするか指定することを可能にする。直前にあげている単純な例では、切換えは必然的にその下のすべてのレベルに影響を及ぼすことになり、これは、プログラマが深さ制限を指定している場合には望ましくない。
【０１１５】
しかし、指定した数のレベルまで関数呼び出しを下にたどり、それらの関数に実行時決定点を自動的に注入することができる。これには深さ制御切換えを通常の切換えより高くつくものにするという影響があるが、深さ制御切換えは全般的な計測関数の数を低減するのに使用されるため、普通は有利なトレードオフである。
【０１１６】
以上では、プログラマが手作業で作成している計測グループの実行時切換えの提供を開示している。
【０１１７】
本発明のメタプログラミングベースの手法を使用すれば、計測システムが、コード全体の呼び出しグラフに基づいて、計測グループの自動配分を生成することも可能である。その場合には、ユーザがその時々に見ている特定の結果に基づいて、これらのグループを自動的にオンとオフに切換えることができる。
【０１１８】
これはきわめて興味深い特性である。というのは、これにより、プログラマの側の労力を全く必要とせず、しかも非常に正確で、完全なタイミング結果をリアルタイムで提供しようとする動作モードが提供されるからである。
【０１１９】
このモードは、手動制御モードと同じ目標を達成するように思われるため、実際に必要な動作モードがこれだけであると主張することも可能であろう。しかし、このモードは非リアルタイムプロファイルでは機能しない。というのは、ユーザがどの計測グループを使用可能にすべきか決定するための対応するインターフェースがないからであり、したがってやはりそのための手動制御モードが必要である。また、ユーザが、手動制御モードの方が実際に使用するのにより適していると判断することもあり得る。
【０１２０】
以上で示しているように、本発明は、精度を損なわず、プログラマにさほど負担をかけることなく、常に、実行される必要なプロファイリング演算数を大幅に低減しようとする。
【０１２１】
より安価な演算を達成する手法と組み合わせると、本発明は、サンプリングプロファイラより高速かつ正確であり、しかも計測プロファイラのすべての利点（呼び出しグラフ情報の取り込みなど）を有するプロファイリングシステムをもたらす。
【０１２２】
プロファイリングシステムの有用な実行時動作を可能にすることの大部分は、タイミング取り込みプロセスを、プログラムの実行時性能に過度に影響を及ぼさないようにうまく行わせて、ユーザが直接タイミング結果を見ながらプログラムを操作することができるようにすることに関わるものである。
【０１２３】
残りの部分は、やはりさほど性能に影響を及ぼさずに、すべての結果を有意味な表示へと照合することができることにかかわるものである。
【０１２４】
本発明の計測されるタイミングの手法によって生成されるデータは、迅速な照合プロセスに非常に適しており、したがってリアルタイムでの使用に非常に適している。
【０１２５】
サンプリングプロファイラとは異なり、本発明の計測の手法では、すでに、すべての関数タイミングを各関数と直接関連付けている。各親／子タイミングを別々に記録するため、各関数ごとの合計時間を取得するためにいくつかの時間を合計する必要はあるが、コンパイル時に時間カウンタを事前に設定しているため、これは、列内の一連の値を合計するだけの単純なものであり、非常に迅速に行われる。また、プログラム全体にわたって１関数当たりの平均の呼び出しパス数が非常に小さい数になる傾向にあることもよくあり、そのため、ほとんどの場合１、２列の値だけしか関連しない。
【０１２６】
また、タイミングデータは階層的であり、ユーザはどの時点においても全データセットの一部を見る傾向にあるため、ユーザが実際にそのデータを見ようとするまでデータの照合とソートの両方を遅らせることができる。ユーザは（画面スペースが限られているため）常に限られた数のタイミングだけしか見ることができないため、これは、照合とソートの量を最小限に保つのに役立つ。
【０１２７】
これらすべての結果として、基本的なリアルタイム表示プロセスは、実行性能に最小限の影響しか及ぼさないことになる。これにより、さらに、時間の経過に対する関数およびサブシステム性能のグラフなどの有用な２次情報や、異なる入力呼び出しパスからの分離されたタイミングを表示することさえも可能になる。
【０１２８】
次に、前述の特徴の多くを組み込んだ本発明の一実施形態を説明する。
【０１２９】
図２を参照すると、ソースコード計測の流れ図が示されている。親関数（またはプロシージャ、モジュール、メソッドなど）が選択され１０、この親関数の呼び出し階層内でのレベルが求められる。計測が必要であると指定された場合１１、関数は、子関数の呼び出しサイトを探す１２ために構文解析される。呼び出しサイトが見つからない場合、次の親が選択される。
【０１３０】
見つかった呼び出しサイトについて、その親関数と子関数の組み合わせに固有の（または、同じ親内で子を複数回呼び出す場合には、親関数および特定の呼び出しサイトに固有の）タイミングレコードへの参照が決定される１３。計測コードが、関数呼び出しまたはその子関数への入口時刻とその子関数からの出口時刻を記録するインラインコードを持つように生成される１４。連鎖した呼び出しサイトの場合には、計測コードは、前の呼び出しサイトの出口時刻をその呼び出しサイトの入口時刻として使用するように最適化される１５。
【０１３１】
現在の関数が計測グループのルートである場合１６、そのルート関数の使用可能／使用不可フラグに基づいて、計測ありと計測なしのどちらの子関数が呼び出されるべきか決定する計測グループ論理が生成される１７。
【０１３２】
計測バージョンと非計測バージョンの２つのバージョンの子関数が生成され１８、計測コードが、計測バージョン内の呼び出しサイトの近くに、生成されている計測グループ論理があればそれと共に挿入される１９。
【０１３３】
図２のステップ１２〜１９のプロセスは、現在の親関数のソースコード内のすべての呼び出しサイトについて繰り返される。各子関数自体も、ソースコードファイルにおいて順を追って、または各子関数が、ソースコード内のそれらの子関数への呼び出しサイトにおいて行われる際に、親関数として処理され得る。
【０１３４】
図３に、計測の実行時切換えを示す。図３を参照すると、ユーザに、本発明に従って計測されているプログラムからの計測結果を表示させる表示インターフェースが提供される。表示用プログラムは、ユーザが表示させる関数のグループを選択する２０ことを可能にし、これは呼び出しグラフ階層内をドリルダウンすることも含む。グループの選択に応答して、選択されたグループの使用可能フラグが変更される２１。使用可能フラグの変更により、計測されるプログラム中のコンパイル済み計測グループ論理が非計測コード２３または計測コード２４を実行する。したがって、プログラムは、ユーザ対話に基づいて計測される。最終的には、表示インターフェースが計測結果を表示する２５。しかし、計測は現在表示されている結果についてのみ使用可能とされるため、プログラムの残りの部分は計測されずにより効率よく走り、計測から生じる性能オーバーヘッドが少なくてすむ。代替として、各グループは、ソフトウェアによってヒューリスティックに選択されてもよい。
【０１３５】
ゲーム開発に適した性能プロファイリングツールにおける主要な要件は以下のとおりである。
・精度  できる限り多くのタイミング情報を、できる限り正確に取り込む。
・完全性  すべての呼び出しグラフ情報を取り込む。
・性能  プログラム実行速度（および非同期ハードウェアの測定）に対する妨げが最小限にとどまる。
・展開  広範なシステム上で展開できる。
・リアルタイム動作  プログラムが実行されている間にタイミング結果を表示に利用することができる。
【０１３６】
プロファイラが行う必要のある主要なトレードオフは、性能に対する精度と完全性の間のものである。本発明はこのトレードオフをある程度まで、または完全に解決し、アプリケーションとゲーム開発の両方で、リアルタイム使用に適した、正確で完全な階層的タイミング解決策を提供する。
【０１３７】
また、本発明のプロファイラの方法は、１つまたは複数のプロセッサ上で走るマルチスレッドソフトウェアをプロファイルすることもできる。
【０１３８】
さらに、本発明は、既存のプロファイリングシステムよりも展開がはるかに容易であり、そのためゲームコンソール上での使用に適するものとして推奨される。
【０１３９】
さらに、本明細書で説明している本発明の範囲を逸脱することなく、改変および改善を加えることもできる。
【図面の簡単な説明】
【０１４０】
【図１】親関数と子関数の各組み合わせごとのタイミング格納を概略的に示す図である。
【図２】本発明の一実施形態によるソースコード計測を概略的に示す図である。
【図３】本発明の一実施形態による計測の実行時切換えを概略的に示す図である。
【図１】
2009529742.tif 000003
【図２】
2009529742.tif 000004
【図３】
2009529742.tif 000005
【国際調査報告】
2009529742.tif 000006
2009529742.tif 000007
2009529742.tif 000008