以下、図面を用いて本発明の実施の形態について説明する。
(第1の実施形態)
本発明の第1の実施形態では、コンテキストスイッチ時にPC(Program Counter)が示す値(以下、「PC値」という。)を取得し、取得されたPC値に基づいてプロファイル情報を作成し、作成されたプロファイル情報に基づいてメモリ上の命令の配置を最適化する方法について説明する。なお、PCとは、次に実行すべき命令のメモリ上のアドレスを格納しているCPUのレジスタ(カウンタ)である。
すなわち、本発明の第1の実施形態のメモリ管理方法は、コンテキストスイッチ時にPC値を取得するステップと、プロファイル情報を作成するステップと、メモリ上の命令の配置を最適化するステップとを含む。
以下、本発明の第1の実施形態の最適化可能なソフトウェアが稼働できるハードウェア環境、PC値を取得するステップ、プロファイル情報を作成するステップ、メモリ上の命令の配置を最適化するステップについて、順に説明する。
(ハードウェア環境)
図1は、本発明の第1の実施形態の計算機1のハードウェア構成の一例を示す図である。図1に示すように、本発明の第1の実施形態の最適化可能なソフトウェアが稼働できる計算機1は、少なくともCPU100、キャッシュ110及びメモリ120を備える。なお、計算機1は、CPU100、キャッシュ110及びメモリ120以外の構成要素を備えてよい。
CPU100は、メモリ120に記憶されている命令やデータを読み出して実行することによって、計算機1を制御する演算処理装置である。このCPU100は、必要な命令やデータがキャッシュ110上にある場合には、キャッシュ110から命令やデータを読み出す。
キャッシュ110は、命令やデータの一時的な格納場所である。キャッシュ110は、命令を格納するためのi‐cache111、データを格納するためのd−cache112を備える。なお、d‐cache112を備えなくてもよい。
メモリ120は、CPU100によって実行される命令やデータを記憶するRAM(Random Access Memory)等の記憶装置である。メモリ120は、キャッシュ110より低速であるが、キャッシュ110よりも容量は大きい。
CPU100とキャッシュ110とはバス130で接続され、キャッシュ110とメモリ120とはバス131で接続されている。そのため、互いに命令やデータを伝送することが可能である。
なお、本発明の第1の実施形態では、CPU100がシングルコア及びシングルCPUである場合を例に説明するが、本発明はマルチコア及びマルチCPUに対しても適用可能である。さらに、本発明はキャッシュ110が複数の階層で構成されている場合や、メモリ120が複数のメモリから構成されている場合に対しても適用可能である。すなわち、様々なハードウェア構成上で利用可能である。
以上に示す構成において、本発明の第1の実施形態の計算機1では、メモリ120上の命令格納メモリ420(図6等参照)における命令の配置を、i−cache111に格納するのに適した態様に最適化する。
以下、PC値を取得するステップについて、図2、図3及び図4を用いて説明する。
(PC値の取得)
図2は、本発明の第1の実施形態の計算機1で実行されるコンテキストスイッチの概要を示す図である。
コンテキストスイッチとは、CPU100によって実行されるマルチタスクOS(Operating System)が有する機能であって、プロセスの切替え処理を実行する機能である。具体的には、プロセスの切替え時に、CPU100のレジスタ等の状態を保存し、再開する際に保存しておいた状態を復元する機能である。なお、マルチタスクOSとは、複数のタスク(プロセス)を並列処理するオペレーティングシステムである。タスクとは、計算機1上においてOSから見た処理の実行単位をいう。プロセスとは、OSからメモリ領域等を割り当てられた実行中のプログラムをいう。
図2を用いて、マルチタスクOS(CPU100)がプロセスA220を実行中にタイマ割込み200が発生した場合に、実行対象のプロセスをプロセスA220から、休止中のプロセスB230に切替える処理を説明する。
まず、マルチタスクOSは、CPU100のコンテキスト(状態)210に関する情報を、実行中のプロセスA220が有するタスク構造体A221に保存する。次に休止中のプロセスB230が有するタスク構造体B231から、コンテキスト210に関する情報を取り出し、CPU100のコンテキスト210に格納する。これにより、CPU100のコンテキスト210を復元する。その結果、プロセスA220は休止状態になり、プロセスB230が実行状態になる。
ここで、タスク構造体A221には、プロセスA220が休止状態になった瞬間のコンテキスト210に関する情報が保存される。そのため、次にプロセスA220が実行状態になったときには、休止前の処理から再開することができる。
すなわち、マルチタスクOSは、タイマ割込み200をトリガーとして、複数のプロセス(図2ではプロセスA220、プロセスB230)がCPU100を共有できるように、CPU100のコンテキスト210を保存したり、復元したりすることができる。
なお、詳細には後述するが、本発明の第1の実施形態では、タスク構造体A221、B231の拡張がユーザによって自由に実施可能であることを利用し、タスク構造体A221、B231にPC取得フラグ310、PC履歴ポインタ320(図3参照)を追加する。また、マルチタスクOS(CPU100)は、コンテキストスイッチを実行する度に、PC値をPC履歴330(図3参照)に保存する。
通常、PCはコンテキストスイッチを実行する度に上書きされるので、最新の値のみを記憶する。しかしながら、本発明の第1の実施形態によれば、マルチタスクOS(CPU100)は、コンテキストスイッチを実行する度に、PC値を保存(記録)する。これにより、コンテキストスイッチ時のPC値の履歴を取得することができる。
図3は、本発明の第1の実施形態のタスク構造体300のデータ構造の一例を示す図である。タスク構造体300とは、プロセス毎に状態やIDなどを格納する構造体である。
タスク構造体300は、プロセス状態、プロセスID、使用メモリ量、PC取得フラグ310、PC履歴ポインタ320等を含む。すなわち、一般的なタスク構造体300の構成要素(プロセス状態、プロセスID、使用メモリ量等)に、PC取得フラグ310、PC履歴ポインタ320が拡張されている。ここでは、拡張された構成要素であるPC取得フラグ310、PC履歴ポインタ320について説明する。
PC取得フラグ310は、コンテキストスイッチ時にPC値を取得するか否かを決定するフラグである。PC取得フラグ310のON/OFFの切替え方法については後述する。PC履歴ポインタ320は、PC履歴330へのポインタである。
PC履歴330は、PC値、すなわち、次に実行すべき命令が格納されたアドレスの値の履歴を記録する領域である。つまり、計算機1上でソフトウェアが実行された際の命令の実行履歴を抽出した情報が記録される。
以上のように、本発明の第1の実施形態によれば、タスク構造体300がPC取得フラグ310及びPC履歴ポインタ320の構成要素を含む。これにより、コンテキストスイッチ時のPC値を過去に遡って取得することができる。
図4は、本発明の第1の実施形態のCPU100、メモリ120、標的プロセス400及びPC履歴330の関係を示す図である。
図4において、標的プロセス400とは、最適化すべきソフトウェア(プログラム)を実行しているプロセスである。この標的プロセス400は、メモリ120上にタスク構造体300を有する。また、この標的プロセス400は、メモリ120上の命令格納メモリ420を参照し、命令格納メモリ420に格納された命令を実行する。なお、命令格納メモリ420は、PC410によっても参照されている。
(PC取得フラグ310の切替え方法について)
ここで、PC取得フラグ310の切替え方法について説明する。
本発明の第1の実施形態では、CPU100によって実行されるマルチタスクOSのカーネルに、例えばPR_CONTROLという名前のシステムコールを追加する。これにより、マルチタスクOS(CPU100)は、当該システムコールによって任意の標的プロセス400のPC取得フラグ310のON/OFFを切替える。
なお、この切替えは、ユーザがキーボード等の入力装置を介して、コマンドライン等のインターフェースにおいて切替え指示を入力することによって、任意のタイミングで実行することができる。
具体的には、PC値の取得処理を開始する場合には、PC値を取得したい標的プロセス400に対してPR_CONTROLを実行することによって、当該標的プロセス400のPC取得フラグ310をONにする。そうすると、マルチタスクOS(CPU100)は、PC410が示す値をPC履歴330に保存する。これにより、指定した標的プロセス400のみでPC410が示す値を取得させることが可能になる。
一方、PC値の取得処理を終了する場合には、任意の標的プロセス400に対してPR_CONTROLを実行することによって、当該標的プロセス400のPC取得フラグ310をOFFにする。そうすると、マルチタスクOS(CPU100)は、PC410が示す値をPC履歴330に保存しない。
以上に示す方法により、PC取得フラグ310を切替えることによって、PC値の取得処理の削減とPC履歴330の領域の節約が可能になる。なお、PC取得フラグ310の切替え方法は、PR_CONTROLに限定されるものではない。また、PCを取得するか否かを決定する方法は、PC取得フラグ310に限定されるものではない。例えば、後述するPC履歴ポインタ320にPC履歴330へのポインタを設定するかNULLポインタを設定するかによって切替えてもよい。
(PC履歴ポインタ320について)
次に、PC履歴ポインタ320について説明する。
本発明の第1実施形態では、標的プロセス400のタスク構造体300は、PC履歴330の実体を保持するのではなく、PC履歴330に対するポインタであるPC履歴ポインタ320を保持する。これにより、複数の同種の標的プロセス400がある場合に、各標的プロセス400は互いのPC履歴330を共有することができる。なお、複数の同種の標的プロセス400がある場合、各標的プロセス400が参照している命令格納メモリ420は同一であり、同一の領域のPC履歴330にアドレスを保存しても良い。
以上に示すように、PC履歴ポインタ320という変数を使用することによって、例えばPC410が示す値を一定数収集するために必要な時間を削減できる。また、PC履歴330が分散してしまうことによって、CPU100のd−cache112のキャッシュヒット率が低下するのを防ぐことができる。また、PC履歴330を格納するためのメモリ量を削減することができる。また、PC履歴ポインタ320にNULLポインタを格納することによって、PC履歴330の領域が確保されていない場合にも対応できる。
なお、本発明はPC履歴330を複数の標的プロセス400間で共有しない場合にも適用可能である。さらに、タスク構造体300がPC履歴ポインタ320ではなく、PC履歴330の実体を保持する場合にも適用可能である。
(各標的プロセス400間でのPC履歴330の共有方法)
複数の標的プロセス400がある場合に、各標的プロセス400によってPC履歴330を共有する方法について説明する。
まず、マルチタスクOS(CPU100)は、procなどの仮想ファイルシステムにPC履歴330のアドレスを出力可能に設定し、初期値をNULLにする。次に、標的プロセス400がPC値の取得処理を開始する際に、仮想ファイルシステムに設定されたPC履歴330のアドレスがNULLである場合には、新しくPC履歴330の領域を確保し、確保されたPC履歴330のアドレスを仮想ファイルシステムに出力する。一方、仮想ファイルシステムに設定されたPC履歴330のアドレスがNULLでない場合には、既にPC履歴330の領域が確保されているため、確保されているPC履歴330のアドレスをPC履歴ポインタ320に設定する。これにより、各標的プロセス400はPC履歴330を共有する。
(PC履歴330の誤解放の防止について)
複数の標的プロセス400がPC履歴330を共有している場合に、PC履歴330の領域の誤解放を防ぐための方法について説明する。
PC履歴330において、当該PC履歴330へのポインタの数(参照数)を記録する参照カウンタを追加してもよい。これにより、PC履歴330の領域が誤って解放されてしまうのを防ぐことができる。
すなわち、マルチタスクOS(CPU100)は、例えばPC値の取得処理を開始する場合には、PC履歴ポインタ320にPC履歴330のアドレスを格納するとともに、参照カウンタを1増やす。一方、PC値の取得処理を終了する場合には、PC履歴ポインタ320にNULLポインタを格納するとともに、参照カウンタを1減らす。そして、参照カウンタが0になった場合にのみ、PC履歴330を解放する。
また、マルチタスクOS(CPU100)は、PC履歴ポインタ320がPC履歴330を参照している場合に、PC410が示す値をPC履歴330に格納する。一方、PC履歴ポインタ320がNULLポインタを参照している場合に、PC410が示す値をPC履歴330に格納しない。このように切替えることにより、PC取得フラグ310の領域を節約することができる。
図5は、本発明の第1の実施形態のタイマ割込み発生時の制御ロジックを示すフローチャートである。ここでは、CPU100によって実行されるマルチタスクOSが、タイマ割込み発生時に、コンテキストスイッチを実行する際の動作を説明する。
まず、タイマ割込みが発生すると(ステップ500)、マルチタスクOS(CPU100)は、コンテキストスイッチが必要か否かを判定する(ステップ510)。
具体的には、例えばプロセス毎に予め設定された優先度に基づいて、コンテキストスイッチが必要か否かを判定する。すなわち、処理待ちのプロセスの優先度が実行中のプロセスの優先度よりも高い場合には、コンテキストスイッチは必要であると判定する。一方、処理待ちのプロセスの優先度が実行中のプロセスの優先度よりも低い場合には、コンテキストスイッチは不要であると判定する。
マルチタスクOS(CPU100)は、コンテキストスイッチが必要でないと判定した場合(ステップ510で“N”)、処理を終了する。一方、コンテキストスイッチが必要であると判定した場合(ステップ510で“Y”)、PC取得フラグ310がONであるか否かを判定する(ステップ520)。
マルチタスクOS(CPU100)は、PC取得フラグ310がOFFである場合(ステップ520で“N”)、ステップ540に進む。一方、PC取得フラグ310がONである場合(ステップ520で“Y”)、PC履歴330にPC値を格納する(ステップ530)。具体的には、図4に示すように、PC410が指すメモリ120上の命令格納メモリ420に格納された命令のアドレスを、PC履歴330に格納する。最も単純な格納方法としては、図3に示すように線形リストでよい。
その後ステップ540において、マルチタスクOS(CPU100)は、通常のコンテキストスイッチ処理を実行する(ステップ540)。その後、処理を終了する。
以上に示す処理のうち、特にステップ520及びステップ530の処理により、マルチタスクOS(CPU100)は、コンテキストスイッチ処理の実行時に、PC履歴330にPC値を格納している。
以上に示すように、マルチタスクOS(CPU100)は、PC履歴330を自動的に取得することができる。そのため、PC履歴330を取得するためのソフトウェア使用者や標的プロセス400の作成者による設定及びソフトウェアの変更は不要である。例えば、PC履歴330を取得するための新しい割込みの追加が不要である。また、タスク構造体300にPC取得フラグ310やPC履歴ポインタ320のための新しい領域を確保し、コンテキストスイッチ時にステップ520及びステップ530の処理を追加するだけで、PC履歴330を取得することができる。そのため、PC値を取得する際の処理が急激に遅くなることもない。また、追加するシステムコールは、PC取得フラグ310のON/OFFを切替えるPR_CONTROLのみであって、このシステムコールは標的プロセス400の起動時に1回だけ起動すればよい。そのため、このシステムコールによる負荷は小さい。
なお、ステップ530では、PC履歴330へのPC値の格納方法として線形リストを挙げたが、PC履歴330は特定のデータ構造に限定されるものではない。すなわち、格納すべきPC値の量が多い場合にはハッシュマップ、少ない場合には線形リストのように、状況に応じて最適なデータ構造を選択してもよい。
また、ステップ530では、必要に応じてPC履歴330にPC値以外の情報、例えばコンテキストスイッチ処理が実行された時刻情報を格納してもよい。これにより、以降PC履歴330に基づいて生成されるプロファイル情報に、時間的局所性を含めることができる。
また、PC値を取得するタイミングは、標的プロセス400を中断する時点と再開する時点のいずれのタイミングでもよい。また、タイマ割込みの頻度はマルチタスクOSに依存するが、本発明はタイマ割込みの頻度に依らず適用できる。また、PC値の取得回数の増加に従い、PC履歴330の容量が大きくなる。そのため、例えば保持するPC値の最大個数を予め指定し、取得されたPC値が最大個数を超えた場合には、古い順に上書きしてもよい。
図6は、本発明の第1の実施形態のメモリ120上の配置の最適化の流れの概要を示す図である。図6を用いて、PC履歴330を用いてメモリ120上の命令(ここでは関数単位)の配置を最適化する流れについて説明する。関数とは、プログラム中の手続きを意味や内容毎に一つの手続きとしてまとめたものである。
メモリ120上の関数の配置を最適化するステップは、プロファイル情報610を作成するステップ、最適化情報620を生成するステップ、命令格納メモリ420において関数をコピーするステップ、及び、関数アドレステーブル640を更新するステップを含む。図6〜図9を用いて順に説明する。
(プロファイル情報610を作成するステップ)
マルチタスクOS(CPU100)が、PC履歴330を統計処理することによって、プロファイル情報610を生成するステップについて説明する。プロファイル情報610とは、プログラムの過去及び現在の実行状況に関する統計情報であって、PC履歴330に基づいて生成される。
マルチタスクOS(CPU100)は、まずプロファイル情報610を作成するためのスレッド(最適化スレッド600)を一つ生成する。なお、最適化スレッド600は、例えば最適化プロセスとして生成しても良い。
なお、最適化スレッド600を生成する主体は、マルチタスクOSのみならず標的プロセス400であってもよい。そして、最適化スレッド600を生成することによって、自動的に又は任意のタイミングで最適化を開始できる。なお、スレッドとして生成しているので、最適化スレッド600と標的プロセス400とを並列に動作させることができる利点がある。
また、最適化スレッド600は、標的プロセス400が参照している命令格納メモリ420の内容を書き換えない。そのため、マルチCPU又はマルチコアの環境では、最適化スレッド600に関するロック(排他制御)は不要であり、標的プロセス400の性能を全く落とさないなどの利点がある。なお、最適化スレッド600を生成する代わりに、例えば別プロセスを生成してもよい。
次に、生成された最適化スレッド600(CPU100)は、標的プロセス400のタスク構造体300や仮想ファイルシステムから、PC履歴330を取得し、必要に応じて取得されたPC履歴330をコピー(複製)する。これにより、PC値の取得が継続されていてPC履歴330が更新中であっても、プロファイル情報610を生成できる。
図7Aは、本発明の第1の実施形態のPC履歴330の一例を示す図である。図7Aに示す例では、PC履歴330は、PC値の履歴として、アドレス331、332、333等を含む。
その後、最適化スレッド600(CPU100)は、取得されたPC履歴330と、関数マッピング情報700とに基づいて、プロファイル情報610を生成する。プロファイル情報610とは、最適化情報620を生成するために利用される統計情報であって、例えば関数毎の使用回数である。
図7Bは、本発明の実施形態の関数マッピング情報700の一例を示す図である。関数マッピング情報700は、関数名701と、メモリ上の配置720との対応関係を示す情報が格納されたテーブルである。
図7Bに示すテーブルでは、標的プロセス400が利用するfuncA613、funcB614及びfuncC615それぞれの関数のメモリ120上の配置(先頭アドレスと終端アドレス)721、722、723を示している。
このような関数マッピング情報700は、例えばダイナミックリンクライブラリのdllファイルやsoファイルから取得できる。なお、dllファイルやsoファイルからは各関数の先頭アドレスを直接取得できるが、各関数の終端アドレスを直接取得することができない。そこで、各関数は命令格納メモリ420上で連続して配置されているという特徴に基づいて、任意の関数が配置されている領域は、その先頭アドレスから次の関数の先頭アドレスの直前までの領域と判断し、当該関数の終端アドレスを決定することができる。なお、同様の手順で関数の名前も取得できる。しかしながら、関数の名前が不要である場合には、関数マッピング情報700から関数名701を削除することによって、メモリ120を節約してもよい。また、関数マッピング情報700の取得方法は、dllファイルやsoファイルからの取得に限定されるものではない。
図6に戻って、最適化スレッド600(CPU100)は、前述したように、PC履歴330と関数マッピング情報700とに基づいて、プロファイル情報610を生成する。具体的には、PC履歴330に記録されている各アドレス(PC値)が、関数マッピング情報700のどの領域に含まれているかを調べることによって、関数毎の使用回数を求める。
例えばPC履歴330のアドレス331(図7A参照)は0x01001234であって、図7Bのメモリ上の配置721に含まれる。そのため、funcA613が呼び出されたと判定できる。上記の手順を繰り返すことによって、関数毎の使用回数を示すプロファイル情報610を作成できる。なお、本発明のプロファイル情報610は、関数単位の使用回数に限定されるものではない。
なお、最適化スレッド600(CPU100)は、必要に応じて最新のN個(例えば10個)のPC履歴330に基づくプロファイル情報610や特定の関数(例えばfuncB614)に限定したプロファイル情報610を生成してもよい。また、複数のプロファイル情報610を生成してもよい。さらに、PC履歴330に基づいてプロファイル情報610を生成できなかった場合は、プロファイル情報610にNULLを格納してもよい。
また、PC履歴330にアドレス(PC値)以外の情報を格納することにより、プロファイル情報610により詳細な統計情報を組み込むことができる。例えば、PC値の取得時刻が格納されたPC履歴330を統計処理することにより、プロファイル情報610に時間的局所性を組み込むことができる。
また、最適化スレッド600(CPU100)は、予め作成された関数マッピング情報700を保持し、当該関数マッピング情報700を用いて、マルチタスクOSによるPC値の取得と同時にプロファイル情報610を作成することもできる。これにより、プロファイル情報610を常に最新の状態にすることができ、最適化に関する精度を向上することができる。
(最適化情報620を生成するステップ)
最適化スレッド600(CPU100)が、プロファイル情報610に最適化アルゴリズムを適用することによって、最適化情報620を生成するステップについて説明する。なお、最適化アルゴリズムとは、メモリ120上の関数の配置を最適化するための処理手順である。また、最適化情報620とは、メモリ120上の関数の配置を最適化するために利用される情報である。
図8は、本発明の第1の実施形態の最適化アルゴリズムの制御ロジックを示すフローチャートである。ここでは、最適化スレッド600が、図8に示す最適化アルゴリズムに従って最適化情報620を生成する処理を説明する。
まず、最適化スレッド600による最適化アルゴリズムが開始すると(ステップ800)、最適化スレッド600(CPU100)は、プロファイル情報610から任意の関数Xを選択する(ステップ810)。
ステップ810において、具体的には、最適化スレッド600は、プロファイル情報610に登録された関数であるfuncA613、funcB614、funcC615のいずれかを選択する。なお、プロファイル情報610における統計情報の登録単位が関数単位ではない場合には、登録単位に応じて選択してもよい。
次に、最適化スレッド600(CPU100)は、関数Xが存在するか否かを判定する(ステップ820)。関数Xが存在しない場合(ステップ820で“N”)、処理を終了する。一方、関数Xが存在する場合(ステップ820で“Y”)、関数Xの使用回数が予め定めた閾値Tより大きいか否かを判定する(ステップ830)。
ここでいう閾値Tとは、プロファイル情報610に登録された1又は複数の関数から最適化対象の関数を抽出するために、メモリ120の容量の大きさや最適化の度合いに応じて決定される値である。例えば、プロファイル情報610に登録された各関数の使用回数の平均値である。なお、メモリ120の空き容量が大きい場合には閾値Tを小さくしてよい。これにより、最適化対象の関数を増やすよう調整できる。
また、ステップ830では、関数Xの使用回数の代わりに、例えば関数Xの使用時刻を用いてもよい。この場合、関数Xが最後に使用された時刻が、プロファイル情報610に登録された各関数が最後に使用された時刻の平均値よりも新しいか否かを判定する。これにより、最後に使用された時刻が新しい関数Xを、最適化対象の関数として抽出することができる。
また、ステップ830では、関数Xの使用回数の代わりに、例えば関数Xの使用時刻に基づいて算出される使用間隔(時間)を用いてもよい。この場合、関数Xの使用間隔が、プロファイル情報610に登録された各関数の使用間隔の平均値よりも小さいか否かを判定する。これにより、使用間隔が小さい関数Xを、最適化対象の関数として抽出することができる。
さらに、ステップ830では、最適化スレッド600(CPU100)は、例えば関数Xの使用回数をプロファイル情報610に登録された各関数の使用回数の合計値で割った値が、予め定めた閾値Tより大きいか否かを判定することにより、関数Xの使用割合を考慮して最適化対象の関数を抽出してもよい。
また、使用回数や使用時刻、使用間隔など複数の要素に重み付けし、組み合わせて判定することもできる。
以上のように、ステップ830では、最適化スレッド600(CPU100)は、プロファイル情報610に登録された1又は複数の関数から、最適化対象の関数を抽出している。
関数Xの使用回数が閾値Tより小さい場合(ステップ830で“N”)、ステップ850に進む。一方、関数Xの使用回数が閾値Tより大きい場合(ステップ830で“Y”)、ステップ840に進み、最適化スレッド600(CPU100)は、関数Xとその使用回数を、最適化情報620に優先度順で追加する(ステップ840)。
ここでいう優先度とは、メモリ120上の関数の配置を最適化する際の基準値(評価値)である。すなわち、優先度が高い関数の順に、メモリ120上の配置を最適化する。
なお、優先度は、最適化アルゴリズムで利用しているパラメータによって決定できる。例えば、利用しているパラメータが各関数の使用回数である場合、優先度は使用回数とすることができる。この場合、最適化スレッド600(CPU100)は、使用回数が多い順に、関数Xとその使用回数を最適化情報620に追加する。また例えば、利用しているパラメータが各関数の使用時刻である場合、優先度は使用時刻とすることができる。ここで、時間的局所性から最後に使用された時刻が新しいほど再度利用される可能性が高いため、最後に使用された時刻が新しい順に優先度を高くする。すなわち、最適化スレッド600は、最後に使用された時刻が新しい順に、関数Xとその使用回数を最適化情報620に追加する。なお、関数の使用時刻から算出される使用間隔(時間)が小さいほど再度利用される可能性が高いので、使用間隔が小さい順に優先度を高くしてもよい。すなわち、最適化スレッド600は、使用間隔が小さい順に、関数Xとその使用回数を最適化情報620に追加する。これにより、時間の経過とともに各関数の使用頻度が変化する場合でも対応可能である。
また、利用しているパラメータが複数(例えば使用回数及び使用時刻)存在する場合、優先度は複数のパラメータの組み合わせとすることができる。この場合、最適化スレッド600は、例えば各関数の使用回数に、最後に使用された時刻が最も新しい関数に100を加算、2番目に新しい関数に99を加算する等のように重みを付けた値の大きい順に、関数Xとその使用回数を最適化情報620に追加する。
また、関数マッピング情報700から得られる関数のサイズが小さいほどキャッシュを有効に活用できるため、関数のサイズが小さい順に優先度を高くしてもよい。
その後ステップ850において、最適化スレッド600(CPU100)は、プロファイル情報610から、別の関数Xを選択し(ステップ850)、ステップ820の処理に戻る。以降、ステップ820からステップ850の処理を繰り返し、関数Xが存在しなくなった時点で(ステップ820で“N”)、最適化アルゴリズムを終了する(ステップ860)。
以上に示す処理により、最適化スレッド600(CPU100)は、プロファイル情報610に基づいて最適化情報620を生成する。
例えば、図6のプロファイル情報610に示すように、funcA613、funcB614及びfuncC615の使用回数612がそれぞれ100、3、80であり、閾値Tが50である場合、最適化情報620は、funcA613及びfuncC615とその優先度622となる。
なお、プロファイル情報610がNULLの場合や全ての関数Xの使用回数612が閾値Tより小さい場合は、最適化スレッド600(CPU100)は、最適化情報620にNULLを格納してもよい。また、閾値Tは最適アルゴリズムの中で動的に決定してもよい。
また、図8に示すような特定の最適化アルゴリズムに限定されるものではなく、様々な最適化アルゴリズムが利用可能である。例えば、時間を多く費やしている関数が最適化情報620に多く含まれるように重み付けしてもよい。
(命令格納メモリ420において関数をコピーするステップ)
最適化スレッド600(CPU100)が、最適化情報620に基づいて、命令格納メモリ420において関数をコピーするステップについて説明する。具体的には、最適化情報620に含まれる各関数を、命令格納メモリ420上の別アドレスに連続した状態でコピーすることによって、命令格納メモリ420における各関数の配置を最適化する。
図6に示す例では、最適化情報620に含まれる関数はfuncA613とfuncC615である。そこで、最適化スレッド600は、funcA613及びfuncC615を、元のオブジェクトコードが格納された命令格納メモリ420上のアドレス領域630から、別アドレス領域631にコピーする。なお、関数マッピング情報700(図7B参照)における各関数の開始アドレスと終端アドレスを参照することによって、別アドレス領域631上で任意の関数を連続させて配置できる。
具体的には、まず最適化スレッド600は、最適化情報620を最適化情報710(図7C参照)に更新する。
図7Cは、本発明の第1の実施形態の最適化情報710の一例を示す図である。図7Cに示すように、最適化情報710は、最適化情報620にコピー先アドレス711とコピー元アドレス712とが追加されたものである。
すなわち、最適化スレッド600は、最適化情報620にコピー先アドレス711とコピー元アドレス712を追加することによって、最適化情報710に更新する。
次に最適化スレッド600は、最適化情報710を用いて、コピー元アドレス712に対応する命令格納メモリ420上のアドレス領域630に格納された関数を、コピー先アドレス711に対応する命令格納メモリ420上の別アドレス領域631にコピーする。そうすると、CPU100(図6において不図示)は、別アドレス領域631にコピーされた関数を、i‐cache111に格納する。
なお、最適化スレッド600は、最適化情報620がNULLの場合は、上記コピーを実行しない。また、メモリ120とは別にメモリがある場合、別メモリにコピーしてもよい。
また、本発明は仮想記憶に対しても適用可能である。従って、コピーすべき命令の量がメモリ120の空き容量よりも大きい場合であっても、ソフトウェアの実行速度を高速化することができる。ただし、コピーすべき命令の量がメモリ120の空き容量に対して非常に大きい場合には、ハードディスク(図1において不図示)へのアクセス回数が増加することによって、ソフトウェアの実行速度が低速になる可能性がある。そこで、最適化アルゴリズムにおいて、メモリ120の空き容量に関する情報を組込む、又は、コピーする命令の量を調整する最適化レベルを指定できるようにすることによって、コピーする命令の量を削減する対策が可能である。
(関数アドレステーブル640を更新するステップ)
最適化スレッド600(CPU100)が、最適化情報710(図7C参照)に基づいて、関数アドレステーブル640を更新するステップについて説明する。
図9は、本発明の第1の実施形態の関数アドレステーブル640の更新の制御ロジックを示すフローチャートである。なお、関数アドレステーブル640とは、関数名641に示す関数と、当該関数が格納されたメモリ120上の先頭メモリアドレス642とのマッピングを示したテーブルである。
まず、最適化スレッド600によるアドレス更新が開始すると(ステップ900)、最適化スレッド600(CPU100)は、古い最適化情報710があるか否か判定する(ステップ910)。古い最適化情報710がある場合とは、上記PC値の取得とメモリ120上の関数の配置の最適化を繰り返した場合に、別アドレス領域631上に古い最適化情報710に従ってコピーされた関数が残っている場合である。この状態で別アドレス領域631が書き換えられるとメモリ領域の解放漏れが発生する。
古い最適化情報710がない場合(ステップ910で“N”)、ステップ950に進む。一方、古い最適化情報710がある場合(ステップ910で“Y”)、最適化スレッド600(CPU100)は、ステップ950による関数アドレステーブル640の更新処理の前に、ステップ920からステップ940の処理を実行する。
すなわち、まずステップ920において、最適化スレッド600(CPU100)は、古い最適化情報710のコピー元アドレス712に基づいて、関数アドレステーブル640を更新する(ステップ920)。具体的には、関数アドレステーブル640の関数名641に示す各関数の先頭メモリアドレス642を、古い最適化情報710のコピー元アドレス712に更新する。これにより、標的プロセス400は命令格納メモリ420上のアドレス領域630を参照し、処理を継続することができる。
その後ステップ930において、最適化スレッド600(CPU100)は、古い最適化情報710に従って確保されたメモリ領域を解放する(ステップ930)。具体的には、古い最適化情報710に従ってコピーされた関数が格納されている命令格納メモリ420上の別アドレス領域631を解放する。
以上ステップ920及びステップ930に示すように、最適化スレッド600(CPU100)は、関数アドレステーブル640の先頭メモリアドレス642を更新した後に、別アドレス領域631を解放する。これにより、並列に動作している標的プロセス400の不具合を回避できる。
その後ステップ940において、最適化スレッド600(CPU100)は、古い最適化情報710に含まれる全ての関数が格納された領域の解放が終了したので、古い最適化情報710を削除する(ステップ940)。
その後ステップ950において、最適化スレッド600(CPU100)は、新しい最適化情報710のコピー先アドレス711に基づいて、関数アドレステーブル640を更新する(ステップ950)。具体的には、関数アドレステーブル640の関数名641に示す各関数の先頭メモリアドレス642を、新しい最適化情報710のコピー先アドレス711に更新する。その後、処理を終了する(ステップ960)。
例えば、図7Cに示すように、最適化情報710に含まれる関数がfuncA613とfuncC615である場合、図9に示す処理によって、関数アドレステーブル640のアドレス643〜645のうち、アドレス643及びアドレス645が更新される。
以上に示す処理により、以後、標的プロセス400は関数を呼び出す場合、更新後の関数アドレステーブル640に従って、命令格納メモリ420上の別アドレス領域631に格納された関数を呼び出す。その結果、CPU100によるi−cache111への書き換え回数を減少させ、不具合を引き起こさずにソフトウェアの実行速度を高速化することができる。
なお、関数アドレステーブル640の更新後であっても、命令格納メモリ420上のアドレス領域630には、関数の元々のオブジェクトコードが残っている。そのため、標的プロセス400は、アドレス領域630を参照した場合であっても、関数の不存在による不具合を発生することなく動作できる。
なお、メモリ120上の関数アドレステーブル640を更新しても、関数アドレステーブル640がキャッシュ110上に存在する場合は、関数の元々のオブジェクトコードが参照される。そのため、通常は不具合対策としてキャッシュクリアを実行する必要がある。この場合、関数アドレステーブル640以外のキャッシュもクリアされ、一時的に処理速度が遅くなる。そこで、本発明の第1の実施形態では、キャッシュクリアを実行してもよいが、実行しなくてもよい。キャッシュクリアを実行しない場合であっても、元々のオブジェクトコードが残っているため、関数の不存在による不具合が発生しない。なお、キャッシュ110上の関数アドレステーブル640の更新を待ってもよい。
以上説明してきた第1の実施形態によれば、ソースプログラム又はオブジェクトコードの修正やコンパイル環境を必要とすることなく、システムの動作中に動的にメモリ120上の命令(ここでは関数単位)の配置を最適化することができる。
(第2の実施形態)
第1の実施形態では、関数毎にメモリ120上の配置を最適化する形態について説明した。第2の実施形態では、関数同士の依存関係を利用して、関数の組み合わせ毎にメモリ120上の配置を最適化する形態について説明する。なお、以下では、前述の第1の実施形態と同様である部分の説明を適宜省略する。
図10は、本発明の第2の実施形態のメモリ120上の配置の最適化の流れの概要を示す図である。図10を用いて、PC履歴330を用いてメモリ120上の関数の配置を最適化する流れについて説明する。なお、以下では前述の第1の実施形態(図6参照)と同様の機能を果たす部分には同一の符号を付して重複する説明を適宜省略する。
前述の第1の実施形態と同様に、メモリ120上の関数の配置を最適化するステップは、プロファイル情報610を作成するステップ、最適化情報620を生成するステップ、命令格納メモリ420において関数をコピーするステップ、及び、関数アドレステーブル640を更新するステップを含む。
なお、以下では、前述の第1の実施形態との差異点を中心に説明する。
最適化情報620を生成するステップにおいて、第2の実施形態の最適化スレッド600(CPU100)は、関数同士の依存関係を考慮した最適化アルゴリズムをプロファイル情報610に適用することによって、最適化情報620を生成する。関数同士の依存関係とは、図10の依存関係1000に示すように、関数同士の呼び出しと呼び出される関係をまとめたものである。
なお、関数の呼び出し関係は、ソフトウェアのソースコードやオブジェクトコードから取得できる。最適化スレッド600(CPU100)は、このような関数同士の依存関係を取得し、同一の関数を含む複数の最適化パターンを含む最適化情報620を生成する。
図10に示す例では、依存関係1000に示すように、funcD1001からfuncE1002、funcF1003及びfuncG1004の呼出し回数は、それぞれ100回、1回、80回である。
この場合、最適化情報620を生成するステップにおいて、最適化スレッド600(CPU100)は、呼出し回数が閾値(例えば50回)より大きい関数の組み合わせ、例えばfuncD1001とfuncE1002の組、及び、funcD1001及びfuncG1004の組を抽出する。
その後、命令格納メモリ420において関数をコピーするステップにおいて、第2の実施形態の最適化スレッド600(CPU100)は、最適化情報620に含まれる各関数の組み合わせを、命令格納メモリ420上の別アドレスに連続した状態でコピーすることによって、命令格納メモリ420における各関数の組み合わせの配置を最適化する。
図10に示す例では、最適化スレッド600は、別アドレス1011に示すように、funcD1001とfuncE1002の組、及び、funcD1001及びfuncG1004の組を、元のオブジェクトコードが格納された命令格納メモリ420上のアドレス1010から、別アドレス1011に連続するようにコピーする。そうすると、CPU100(図10において不図示)は、別アドレス1011にコピーされたfuncD1001をi−cache111に格納するとともに、funcE1002及びfuncG1004を格納できる。これにより、i−cache111の書き換え回数を減少できる。
なお、その後の関数アドレステーブル640を更新するステップでは、最適化スレッド600(CPU100)は、優先度が高い最適化パターン(例えば呼出し回数が最も大きいfuncD1001とfuncE1002の関数の組み合わせ)に基づいて、関数アドレステーブル640を更新する。なお、その後適切なタイミングで関数アドレステーブル640を更新してもよい。適切なタイミングとは、例えばfuncE1002が100回呼び出された時である。また、複数の最適化パターンに基づく更新を実行することによって、i−cache111の書き換え回数をさらに減少させてもよい。
以上説明してきた第2の実施形態によれば、前述の第1の実施形態に加え、メモリ120の命令格納メモリ420上に、複数の最適化パターンを配置することができる。また、命令格納メモリ420上に配置された隣接する関数同士に依存関係があるので、前述の第1の実施形態に比して、i−cache111の書き換え回数を減少できる。そのため、更なるソフトウェアの実行速度を高速化することができる。
なお、メモリ120の使用量に制限がある場合や関数の依存関係の取得が困難である場合は第1の実施形態のメモリ管理方法を適用し、メモリ120の使用量に制限がない場合や関数の依存関係の取得が容易である場合は第2の実施形態のメモリ管理方法を適用するように、第1の実施形態と第2の実施形態とを切替えることも好ましい。
以上、本発明の各実施形態について説明したが、上記各実施形態は本発明の適用例の一つを示したものであり、本発明の技術的範囲を上記各実施形態の具体的構成に限定する趣旨ではない。
例えば、上記各実施形態では、CPU100によって実行されるマルチタスクOSを例に説明してきたが、この場合には限らない。例えばシングルタスクOSでもよい。この場合、コンテキストスイッチを実行する毎ではなく、ユーザによる設定等に基づく定期的なタイミング毎にPC値を取得すればよい。