(57)【要約】【課題】コンパイル及びリンクによりプログラムを生成する際に、複数のメモリにおけるアクセス速度の違いを考慮した最適化を実現するプログラム生成装置、プログラム生成方法及びプログラムを提供する。【解決手段】アクセス速度の異なる複数のメモリを有するコンピュータで動作されるプログラムを生成するプログラム生成装置であって、１回目のコンパイル及びリンクによりプログラムを生成し、そのプログラムをコンピュータ上で動作させた際のメモリに対するアクセスの監視結果と、複数のメモリのアクセス速度を示す情報とに基づいて、頻繁にアクセスされるデータを優先的にアクセス速度が速い方のメモリに配置するようにして、２回目のコンパイル及びリンクによりプログラムを生成することを特徴とする。【選択図】図１
2012247827.tif 000002
【特許請求の範囲】
【請求項１】
アクセス速度の異なる複数のメモリを有するコンピュータで動作されるプログラムを生成するプログラム生成装置であって、
１回目のコンパイル及びリンクによりプログラムを生成し、
当該プログラムを前記コンピュータ上で動作させた際のメモリに対するアクセスの監視結果と、前記複数のメモリのアクセス速度を示す情報とに基づいて、頻繁にアクセスされるデータを優先的にアクセス速度が速い方のメモリに配置するようにして、２回目のコンパイル及びリンクによりプログラムを生成することを特徴とするプログラム生成装置。
【請求項２】
前記複数のメモリは、第１メモリ及びそれよりアクセス速度が速い第２メモリであり、
前記コンピュータにて前記１回目のコンパイル及びリンクで生成したプログラムを動作させることで得られた前記監視結果としての、アクセスされた所定範囲のアドレス毎の読み出し回数と書き込み回数を含む第１プロファイルデータを取得し、
前記第１メモリ及び前記第２メモリ毎に前記アクセス速度としての読み出し速度と書き込み速度を含む第１メモリデバイス情報を取得し、
前記２回目のコンパイル及びリンクによりプログラムを生成する際に、
前記アクセスされた所定範囲のアドレス毎に、当該所定範囲のアドレスに配置されていたデータが前記第１メモリに仮に配置された場合に読み出し及び書き込みにかかる第１読み書き合計時間と、当該データが前記第２メモリに仮に配置された場合に読み出し及び書き込みにかかる第２読み書き合計時間とを、前記第１プロファイルデータと前記第１メモリデバイス情報に基づいてそれぞれ算出し、
前記アクセスされた所定範囲のアドレス毎に、前記第１読み書き合計時間と前記第２読み書き合計時間との差分を算出し、
前記差分が大きいアドレスから順に、当該アドレスに配置されていたデータを前記第２メモリに配置することを特徴とする請求項１記載のプログラム生成装置。
【請求項３】
前記第１メモリとしてメインメモリ、前記第２メモリとしてキャッシュメモリを有するコンピュータで動作されるプログラムを生成する場合、
前記コンピュータにて前記１回目のコンパイル及びリンクで生成したプログラムを動作させることで得られた、アクセスされたアドレス毎の、当該アクセスのサイズ、当該アクセスが読み出しか書き込みかをアクセス順に含む第２プロファイルデータを、前記第１プロファイルデータの代わりに取得し、
前記メインメモリの読み出し速度、書き込み速度、及び、前記キャッシュメモリのキャッシュサイズ、キャッシュライン数、キャッシュウェイ数、読み出し速度、書き込み速度を含む第２メモリデバイス情報を、前記第１メモリデバイス情報の代わりに取得し、
前記２回目のコンパイル及びリンクによりプログラムを生成する際に、
前記第２プロファイルデータを基に前記キャッシュメモリの動作をシミュレートし、キャッシュヒット率が最も低いラインを求め、
前記キャッシュヒット率が最も低いラインにキャッシュされるデータのうち、アクセス数が最も多いデータＡを前記キャッシュメモリから追い出した回数が最も多いデータＢを探し、
前記データＡと前記データＢのキャッシュラインが一致するように、前記データＢと前記データＡの近傍にある複数のデータとのアドレスの入れ替えをそれぞれ行い、
前記キャッシュメモリの動作をシミュレートしながら、前記第２メモリデバイス情報を基に、前記アドレスの入れ替えそれぞれにおけるアクセス時間の総計を計算し、
前記アクセス時間の総計が最短となった前記アドレスの入れ替えを採用することを特徴とする請求項２記載のプログラム生成装置。
【請求項４】
アクセス速度が前記第１メモリよりも速く、前記第２メモリよりも遅い第３メモリをさらに有するコンピュータで動作されるプログラムを生成する場合、
前記コンピュータにて前記１回目のコンパイル及びリンクで生成したプログラムを動作させることで得られた、前記第２プロファイルデータを取得し、
前記第２メモリアドバイス情報に加えて前記第３メモリの読み出し速度、書き込み速度を含む第３メモリデバイス情報を、前記第２メモリデバイス情報の代わりに取得し、
前記２回目のコンパイル及びリンクによりプログラムを生成する際に、
前記アクセスされたアドレス毎に、当該アドレスに配置されていたデータが前記第１メモリに仮に配置された場合に読み出し及び書き込みにかかる第１読み書き合計時間と、当該データが前記第３メモリに仮に配置された場合に読み出し及び書き込みにかかる第３読み書き合計時間とを、前記第２プロファイルデータと前記第３メモリデバイス情報に基づいてそれぞれ算出し、
前記アクセスされたアドレス毎に、前記第１読み書き合計時間と前記第３読み書き合計時間との差分を算出し、
前記差分が大きいアドレスから順に、当該アドレスに配置されていたデータを前記第３メモリに配置するようにし、
前記第２プロファイルデータを基に前記キャッシュメモリの動作をシミュレートし、キャッシュヒット率が最も低いラインを求め、
前記キャッシュヒット率が最も低いラインにキャッシュされるデータのうち、アクセス数が最も多いデータＡを前記キャッシュメモリから追い出した回数が最も多いデータＢを探し、
前記データＡと前記データＢのキャッシュラインが一致するように、前記データＢと前記データＡの近傍にある複数のデータとのアドレスの入れ替えをそれぞれ行い、
前記キャッシュメモリの動作をシミュレートしながら、前記第３メモリデバイス情報を基に、前記アドレスの入れ替えそれぞれにおけるアクセス時間の総計を計算し、
前記アクセス時間の総計が最短となった前記アドレスの入れ替えを採用することを特徴とする請求項３記載のプログラム生成装置。
【請求項５】
前記第１メモリと対になる第１プロセッサを備えた第１ノードと、前記第２メモリと対になる第２プロセッサを備えた第２ノードとを有するコンピュータで動作されるプログラムを生成する場合、
前記コンピュータにて前記１回目のコンパイル及びリンクで生成したプログラムを前記第１プロセッサ又は前記第２プロセッサにより動作させることで得られた、前記第２プロファイルデータを取得し、
前記第１メモリアドバイス情報を取得し、
前記２回目のコンパイル及びリンクによりプログラムを生成する際に、
前記プログラムが動作するプロセッサを前記第１プロセッサ又は前記第２プロセッサのいずれかに固定し、
前記アクセスされたアドレス毎に、当該アドレスに配置されていたデータが前記第１メモリに仮に配置された場合に読み出し及び書き込みにかかる第１読み書き合計時間と、当該データが前記第２メモリに仮に配置された場合に読み出し及び書き込みにかかる第２読み書き合計時間とを、前記第２プロファイルデータと前記第１メモリデバイス情報に基づいてそれぞれ算出し、
前記アクセスされたアドレス毎に、前記第１読み書き合計時間と前記第２読み書き合計時間との差分を算出し、
前記差分が大きいアドレスから順に、当該アドレスに配置されていたデータを、前記固定されたプロセッサと対になるメモリに配置することを特徴とする請求項２記載のプログラム生成装置。
【請求項６】
前記コンピュータで動作されるプログラムとして、マルチスレッドプログラムを生成する場合、
前記コンピュータにて前記１回目のコンパイル及びリンクで生成したマルチスレッドプログラムを前記第１プロセッサ又は前記第２プロセッサにより動作させることで得られた、アクセスされた所定範囲のアドレス毎の、各スレッドの読み出し回数と書き込み回数を含む第３プロファイルデータを、第２プロファイルデータの代わりに取得し、
前記第１メモリアドバイス情報を取得し、
前記２回目のコンパイル及びリンクによりプログラムを生成する際に、
前記第３プロファイルデータを基に、全てのスレッドからアクセスされている所定範囲のアドレスを特定するとともに、当該全てのスレッドの中で最も読み出し回数と書き込み回数が多いスレッドを特定し、当該特定したスレッドが動作するプロセッサを、前記第１プロセッサ又は前記第２プロセッサのいずれかに固定し、
前記第３プロファイルデータを基に、一のスレッドのみからアクセスされている所定範囲のアドレスを特定し、当該一のスレッドが動作するプロセッサを、前記第１プロセッサ又は前記第２プロセッサのいずれかに固定し、
前記アクセスされた所定範囲のアドレス毎に、当該所定範囲のアドレスに配置されていたデータが前記第１メモリに仮に配置された場合に読み出し及び書き込みにかかる第１読み書き合計時間と、当該データが前記第２メモリに仮に配置された場合に読み出し及び書き込みにかかる第２読み書き合計時間とを、前記第３プロファイルデータと前記第１メモリデバイス情報に基づいてそれぞれ算出し、
前記アクセスされた所定範囲のアドレス毎に、前記第１読み書き合計時間と前記第２読み書き合計時間との差分を算出し、
前記差分が大きいアドレスから順に、当該所定範囲のアドレスに配置されていたデータを、前記固定されたプロセッサと対になるメモリに配置することを特徴とする請求項５記載のプログラム生成装置。
【請求項７】
前記第１ノード及び前記第２ノードのそれぞれにキャッシュメモリをさらに有するコンピュータで動作されるプログラムを生成する場合、
請求項４又は５に記載の一連の動作の後で、請求項２に記載の一連の動作を行うことを特徴とする請求項５又は６記載のプログラム生成装置。
【請求項８】
アクセス速度の異なる複数のメモリを有するコンピュータで動作されるプログラムを生成するプログラム生成方法であって、
１回目のコンパイル及びリンクによりプログラムを生成し、
当該プログラムを前記コンピュータ上で動作させた際のメモリに対するアクセスの監視結果と、前記複数のメモリのアクセス速度を示す情報とに基づいて、頻繁にアクセスされるデータを優先的にアクセス速度が速い方のメモリに配置するようにして、２回目のコンパイル及びリンクによりプログラムを生成することを特徴とするプログラム生成方法。
【請求項９】
アクセス速度の異なる複数のメモリを有するコンピュータで動作されるプログラムを生成するプログラムであって、
１回目のコンパイル及びリンクによりプログラムを生成する処理と、
当該プログラムを前記コンピュータ上で動作させた際のメモリに対するアクセスの監視結果と、前記複数のメモリのアクセス速度を示す情報とに基づいて、頻繁にアクセスされるデータを優先的にアクセス速度が速い方のメモリに配置するようにして、２回目のコンパイル及びリンクによりプログラムを生成する処理と、
をコンピュータに実行させることを特徴とするプログラム。
【発明の詳細な説明】
【技術分野】
【０００１】
本発明は、コンパイル、リンクを行ってプログラムを生成するプログラム生成装置、プログラム生成方法及びプログラムに関する。
【背景技術】
【０００２】
所定のプログラムを生成する際に、ソースコードからオブジェクトファイルを生成するコンパイル、オブジェクトファイルから実行可能ファイルを生成するリンクを行うプログラム生成装置（例えば情報処理装置、コンピュータ）が知られている。プログラム生成装置では、コンパイラと呼ばれるソフトウェアによりコンパイルが実行され、リンカと呼ばれるソフトウェアによりリンクが実行される。
【０００３】
このようなプログラム生成装置において、プログラムのコンパイル、リンクが行われるときに、そのプログラムのパフォーマンスに関する最適化が行われるようにすることは難しい。なぜならば、プログラムを実際にコンピュータ上で動作させてみないことには、どのような最適化を行えばよいかの情報が得られないからである。
【０００４】
そこで、プログラム生成装置においてコンパイラ及びリンカが、コンパイル及びリンクを行って一旦プログラムを生成し、そのプログラムをコンピュータ（プログラム生成装置自身又は他の情報処理装置）上で実際に動作させることで得られたデータ（プロファイルデータという）を取得し、そのプロファイルデータに基づいて望ましい最適化を行いつつコンパイル及びリンクを行ってプログラムを生成する技術が知られている。
【０００５】
このような技術は、例えば特許文献１に開示されている。特許文献１には、一旦プログラムを生成し、そのプログラムについてベンチマーク試験を行ってパフォーマンスを測定し、その測定結果を用いて再度プログラムを生成することにより、プログラムの最適化を実現する構成が開示されている。
【発明の概要】
【発明が解決しようとする課題】
【０００６】
しかしながら、上述した「プロファイルデータに基づいて望ましい最適化を行いつつコンパイル及びリンクを行ってプログラムを生成する技術」では、最適化の範囲が限定されており、メモリアクセス（メモリに対するアクセス）に関する最適化は行われていなかった。
【０００７】
例えば、マルチコアシステムの一形態であるＮＵＭＡにおいては、アクセス速度が速いローカルメモリと、アクセス速度が遅いリモートメモリとが存在するが、このアクセス速度の違いを考慮して最適化を行うコンパイラ及びリンカは存在しない。また、キャッシュメモリを有するシステムにおいても、キャッシュメモリとメインメモリとではアクセス速度の違いがあるが、このアクセス速度の違いを考慮して最適化を行うコンパイラ及びリンカは存在しない。
【０００８】
このように従来では、コンパイル及びリンクにおいて動的なプロファイルデータを用いた最適化が行われる際に、複数のメモリにおけるアクセス速度の違いを考慮した最適化が行われていなかった。
【０００９】
本発明は、上記事情に鑑みてなされたものであり、コンパイル及びリンクによりプログラムを生成する際に、複数のメモリにおけるアクセス速度の違いを考慮した最適化を実現するプログラム生成装置、プログラム生成方法及びプログラムを提供することを目的とする。
【課題を解決するための手段】
【００１０】
かかる目的を達成するために、本発明の第１の態様は、アクセス速度の異なる複数のメモリを有するコンピュータで動作されるプログラムを生成するプログラム生成装置であって、１回目のコンパイル及びリンクによりプログラムを生成し、そのプログラムをコンピュータ上で動作させた際のメモリに対するアクセスの監視結果と、複数のメモリのアクセス速度を示す情報とに基づいて、頻繁にアクセスされるデータを優先的にアクセス速度が速い方のメモリに配置するようにして、２回目のコンパイル及びリンクによりプログラムを生成することを特徴とする。
【００１１】
本発明の第２の態様は、アクセス速度の異なる複数のメモリを有するコンピュータで動作されるプログラムを生成するプログラム生成方法であって、１回目のコンパイル及びリンクによりプログラムを生成し、プログラムをコンピュータ上で動作させた際のメモリに対するアクセスの監視結果と、複数のメモリのアクセス速度を示す情報とに基づいて、頻繁にアクセスされるデータを優先的にアクセス速度が速い方のメモリに配置するようにして、２回目のコンパイル及びリンクによりプログラムを生成することを特徴とする。
【００１２】
本発明の第３の態様は、アクセス速度の異なる複数のメモリを有するコンピュータで動作されるプログラムを生成するプログラムであって、１回目のコンパイル及びリンクによりプログラムを生成する処理と、プログラムをコンピュータ上で動作させた際のメモリに対するアクセスの監視結果と、複数のメモリのアクセス速度を示す情報とに基づいて、頻繁にアクセスされるデータを優先的にアクセス速度が速い方のメモリに配置するようにして、２回目のコンパイル及びリンクによりプログラムを生成する処理と、をコンピュータに実行させることを特徴とする。
【発明の効果】
【００１３】
本発明によれば、コンパイル及びリンクによりプログラムを生成する際に、複数のメモリにおけるアクセス速度の違いを考慮した最適化を実現することによって、生成されるプログラムの更なるパフォーマンス向上を実現できる。
【図面の簡単な説明】
【００１４】
【図１】本発明の第１の実施形態に係り、プログラム生成装置におけるメモリアクセスの最適化の一例の概要について説明する図である。
【図２】本発明の第１の実施形態に係り、プログラム生成装置におけるメモリアクセスの最適化の動作例を示すフローチャートである。
【図３】本発明の第１の実施形態に係り、動作コンピュータにおけるプログラムのメモリアクセスを監視する仕組みの一例について説明する図である。
【図４】本発明の第１の実施形態に係り、動作コンピュータにて得られるプロファイルデータの例を示す図である。
【図５】本発明の第１の実施形態に係り、予め作成されるメモリデバイス情報の例を示す図である。
【図６】本発明の第１の実施形態に係り、プログラム生成装置におけるメモリアクセスの最適化に用いられる表の一例を示す図である。
【図７】本発明の第２の実施形態に係り、動作コンピュータにて得られるプロファイルデータの例を示す図である。
【図８】本発明の第２の実施形態に係り、予め作成されるメモリデバイス情報の例を示す図である。
【図９】本発明の第２実施形態に係り、プログラム生成装置におけるキャッシュメモリのヒット率向上のためのメモリアクセスの最適化の動作例を示すフローチャートである。
【図１０】本発明の第４の実施形態に係り、動作コンピュータの構成例を示す図である。
【図１１】本発明の第５の実施形態に係り、動作コンピュータにて得られるプロファイルデータの例を示す図である。
【発明を実施するための形態】
【００１５】
以下、本発明を実施するための形態（実施形態）について添付図面を参照して詳細に説明する。なお、以下に記載する各実施形態の説明はあくまで一例であり、本発明を限定するものではない。
【００１６】
〔第１の実施形態〕
図１は、本実施形態のプログラム生成装置におけるメモリアクセスの最適化の一例の概要について説明する図である。本実施形態のプログラム生成装置は、例えばＰＣ（Personal Computer）などの、コンパイラ及びリンカが動作する情報処理装置、コンピュータである。なお、以下の説明では、コンパイラ及びリンカをまとめて「コンパイラ・リンカ」と表記し、別体として扱うときはそれぞれ「コンパイラ」、「リンカ」と表記する（コンパイル及びリンクについても同様）。
【００１７】
図１に示すように、本実施形態のプログラム生成装置（例えば開発用ＰＣ）において、コンパイラ・リンカは、ソースコードを入力として受け取り、通常のコンパイル・リンク（１回目のコンパイル・リンク）を行い、一旦プログラムを生成する。
【００１８】
上記生成されたプログラムは、動作コンピュータ（例えば組み込み用ボード）上で動作させられる。このとき、動作コンピュータでは、その動作の際のメモリアクセスについてのプロファイルデータが得られる。プロファイルデータの詳細は後述する。なお、動作コンピュータは、必ずしもプログラム生成装置と別体である必要はなく、プログラム生成装置と同一であってもよい。
【００１９】
コンパイラ・リンカは、動作コンピュータからプロファイルデータを取得する。
【００２０】
また、コンパイラ・リンカは、これから最適化を行って生成するプログラムが実行される情報処理装置に備えられる複数のメモリについてのメモリデバイス情報を取得する。メモリデバイス情報の詳細は後述する。
【００２１】
そして、コンパイラ・リンカは、プロファイルデータ、メモリデバイス情報、ソースコードを入力として受け取り、メモリアクセスが最適に行われるように、再度プログラムの生成を行う。つまり、２回目のコンパイル・リンクが行われる。この際、頻繁にアクセスされるデータはアクセス速度が速いメモリに配置されるように決定され、そうでないデータはアクセス速度が速くないメモリに配置されるように決定される。このように本実施形態では、２回目のコンパイル・リンクのときにデータの再配置が実行されることで、メモリアクセスの最適化が実現される。
【００２２】
上述した本実施形態のプログラム生成装置の概要を整理すると、図２に示すフローチャートの流れとなる。
【００２３】
まず、プログラム生成装置において、１回目のコンパイル・リンクが行われる。すなわち、コンパイラ・リンカは、ソースコードを入力として受け取り、通常のコンパイル・リンクを行ってプログラムを生成する（ステップ１）。このとき、メモリアクセスの最適化は行われない。すなわちリンカは、メモリアクセスの対象となるデータを適当なアドレスに配置する。なお、ここでいう「配置する」とは、「未確定であったアドレスを確定する」という意味である。よって、「リンカがデータを所定のアドレス（メモリ）に配置する」ということは、「リンクの実行時に、プログラムが実行された際にデータが所定のアドレス（メモリ）に配置されるように決定する」という意味である。この意味は以下の説明においても同様とする。
【００２４】
次に、動作コンピュータにおいて、１回目のコンパイル・リンクにより生成されたプログラムを動作させ、動作コンピュータ上のメモリプロファイラを使用して実行中のプログラムのメモリアクセスを逐一監視し、ストレージデバイス上のファイルにアクセス記録をログする（ステップ２）。このログが、プロファイルデータとなる。動作コンピュータにおいてプログラムを十分な時間動作させたら、ログを終了させる。
【００２５】
次に、プログラム生成装置において、２回目のコンパイル・リンクが行われる。まず、コンパイラ・リンカは、ソースコード、プロファイルデータ及びメモリデバイス情報を入力として受け取る（ステップ３−１）。
【００２６】
次に、コンパイラは、ソースコードから、通常のコンパイルを行って、プログラムを生成する（ステップ３−２）。もしも、ステップ１でプログラムを生成した際のオブジェクトファイルがプログラム生成装置上に残っている場合、このステップは省略して構わない。
【００２７】
リンカは、ステップ３−２（又はステップ１）で生成したオブジェクトファイルをベースに最適化を行う。プロファイルデータには、プログラムの動作時にアクセスされたメモリのアドレスとその頻度が含まれている。また、メモリデバイス情報には、動作コンピュータ上に搭載されているメモリデバイス毎に、アドレス範囲、読み出し（ＲＥＡＤ）時のアクセス速度及び書き込み（ＷＲＩＴＥ）時のアクセス速度が含まれている。リンカは、これらのプロファイルデータ及びメモリデバイス情報に基づいて、ベースとなるオブジェクトファイル上のデータについて再配置を行う（ステップ３−３）。このとき、頻繁にアクセスされるデータはアクセス速度が速いメモリに配置されるように決定され、そうでないデータはアクセス速度が速くないメモリに配置されるように決定される。このようにして決定された再配置情報に基づき、リンカは、オブジェクトファイルを結合して、プログラムを生成する。
【００２８】
なお、通常、アクセス速度が速いメモリは総容量が少ないケースが多いため、全てのデータをアクセス速度が速いメモリ上に配置できるとは限らない。その場合は、アクセス頻度の高いデータから優先的にアクセス速度が速いメモリ上に配置されていくように決定される。
【００２９】
ここで、上記図２のステップ２の具体例について図３を用いて説明する。図３は、動作コンピュータ上でプログラムのメモリアクセスを監視する仕組みについて説明する図である。
【００３０】
図３に示すように、動作コンピュータには、ハードウェアとして、ＣＰＵ（Central Processing Unit）、メモリ１（第１メモリの一例）、メモリ２（第２メモリの一例）、ストレージデバイスが備えられており、ソフトウェアとして、メモリプロファイラが備えられている。
【００３１】
このような構成において、１回目のコンパイル・リンクで生成されたプログラムが実行される。その際、プログラム（ＣＰＵ）のメモリ１、２に対するアクセスは、メモリプロファイラにより逐次監視され、その監視結果がログとしてストレージデバイスのファイルに蓄えられる。この蓄えられたデータがプロファイルデータである。このプロファイルデータは後に、ストレージデバイスから取り出され、コンパイラ・リンカへ出力される。
【００３２】
なお、本明細書において「プログラムのメモリアクセス」とは、「ＣＰＵが、プログラムを実行する際に、メモリの所定アドレスに配置されたデータ（プログラム上のデータ）に対してアクセスすること」を意味する。
【００３３】
メモリプロファイラは、プログラム中の命令コードを１命令ずつ解釈しながらプログラムを実行するソフトウェアである。このような動作をするソフトウェアは、ＤＢＡ（Dynamic Binary Analysis）ツールとして知られている技術である。ＤＢＡツールは、プログラムの挙動を完全に把握することが可能であり、従ってメモリアクセスに関してもプログラムからの各アクセスについて、完全に掌握することができる。このように、メモリプロファイラは、ＤＢＡ技術を使用して実現することができる。
【００３４】
次に、動作コンピュータにて得られたプロファイルデータの具体例を説明する。図４は、プロファイルデータ（第１プロファイルデータの一例）の一部の例を示す図である。
【００３５】
図４において、各データエントリ（項目）は、開始アドレス、終端アドレス、読み出し回数、書き込み回数、の４つの情報から成る。図４の例では、１つのエントリがカバーするアドレス範囲（開始アドレスから終端アドレスまで）は、１６バイトである。
【００３６】
なお、アドレス範囲は、４バイトでも３２バイトでも、あるいは１Ｋバイトでも構わない。１エントリがカバーするアドレス範囲をあまりに狭くしてしまうと、プロファイルデータのデータ量が多くなってしまうが、２回目のコンパイル・リンクにおいて精度よく最適化を行うことができる。逆に、１エントリがカバーするアドレス範囲をあまりに広くしてしまうと、プロファイルデータのデータ量は少なくなるが、２回目のコンパイル・リンクにおいてあまり精度の良い最適化は行えない。
【００３７】
このようなことから、アドレス範囲はデフォルトとして１６バイトに設定しておき、ユーザが必要に応じてメモリプロファイラにおいてその設定を変更できるようにしてもよい。
【００３８】
メモリプロファイラは、例えばアドレス0x80000000（に配置されたデータ）に対する読み出しのメモリアクセスを検知したとすると、図４において、開始アドレスが0x80000000のエントリの読み出し回数を１増加させる。また、メモリプロファイラは、例えばアドレス0x80000014（に配置されたデータ）に対する書き込みのアクセスを検知したとすると、図４において、開始アドレスが0x80000010のエントリの書き込み回数を１増加させる。
【００３９】
このようにしてプロファイルデータは、図３に示す動作コンピュータ上のストレージデバイス上にファイルとして作成される。その後、プロファイルデータは、ストレージデバイスから取り出され、最適化コンパイル・リンク処理、すなわち２回目のコンパイル・リンクで使用される。
【００４０】
次に、上記プロファイルデータと同様に２回目のコンパイル・リンクで使用される、メモリデバイス情報の例について説明する。図５は、メモリデバイス情報（第１メモリデバイス情報の一例）の一例を示す図である。
【００４１】
メモリデバイス情報は、動作コンピュータ上に搭載されているメモリデバイス（プログラムが使用可能なメモリデバイス）に関する情報であり、動作コンピュータ毎に固有のものである。ユーザは、２回目のコンパイル・リンクにより生成されるプログラムを動作させたい動作コンピュータ（例えば図１、図３に示すもの）の仕様書やＯＳ（Operating System）の仕様書を参照して、メモリデバイス情報を作成しておく。
【００４２】
図５において、各データエントリは、メモリデバイス、開始アドレス、終端アドレス、読み出し速度、書き込み速度、の５つの情報から成る。図５では、２つのメモリデバイス（例えば図３に示すメモリ１、２）を例としている。開始アドレス、終端アドレスの間の領域が、プログラムからアクセスできるメモリ領域である。
【００４３】
これらのアドレスが物理アドレスであるか、仮想アドレスであるかは、プログラムが動作するコンピュータのＣＰＵアーキテクチャおよびＯＳに依存する。仮想アドレスである場合は、アドレスマッピングは基本的にはＯＳが行うものと想定するが、部分的にプログラムからＯＳ ＡＰＩを通じてマッピングさせることも可能である。読み出し速度、書き込み速度は、メモリデバイスに読み出し要求もしくは書き込み要求を発行してから、その要求が完了するまでの時間である。
【００４４】
図５では、メモリ２がメモリ１よりもメモリアクセスが速い例としている。なお、図５では、メモリ１、２のそれぞれにおいて、読み出し速度と書き込み速度を同じ値としたが、異なる値であってもよい。
【００４５】
次に、上記図２のステップ３−３の具体例について図６を用いて説明する。図６は、リンカがデータの再配置を行うときに用いる表の一例を示す図である。
【００４６】
リンカは、ステップ３−３におけるデータの再配置を行うにあたり、まず、図２のステップ３−１にて入力されたプロファイルデータ（例えば図４に示すもの）及びメモリデバイス情報（例えば図５に示すもの）から、図６に示す表を作成する。
【００４７】
例えば、図４に示すプロファイルデータから、開始アドレス0x80000000〜終端アドレス0x80000010のエントリの読み出し回数が280204回、書き込み回数が5439回という情報が得られたとする。また、図５に示すメモリデバイス情報から、メモリ１の読み込み時間が200ns、書き込み時間が200ns、メモリ２の読み込み時間が10ns、書き込み時間が10nsという情報が得られたとする。このときリンカは、アドレス範囲（0x80000000〜0x80000010）に置かれていたデータを仮にメモリ１に配置した場合と仮にメモリ２に配置した場合のそれぞれにおける、読み出し及び書き込みにかかる合計時間（読み書き合計時間）の算出を行う。
【００４８】
仮にデータをメモリ１に配置したとするならば、280204×200＋5439×200により、読み書き合計時間は57128600nsとなる。また、仮にデータをメモリ２に配置したとするならば、280204×10＋5439×10により、読み書き合計時間は2856430nsとなる。よって、リンカは、図６に示すように、0x80000000〜0x80000010のエントリにおいて読み書き合計時間57128600nsと2856430nsを記録する。
【００４９】
このようにして、リンカは、プロファイルデータに記載されている全てのアドレス範囲に対して、メモリ１に配置された場合、メモリ２に配置された場合の各々の読み書き合計時間を算出し、図６に示すように記録していく。
【００５０】
次に、リンカは、アドレス範囲のエントリ毎に、メモリ１に配置した場合とメモリ２に配置した場合の読み書き合計時間の差分を計算していく。例えば0x80000000〜0x80000010のエントリの場合、57128600−2856430により、差分は54272170nsとなる。
【００５１】
そして、リンカは、算出した差分の値が大きい順に、アクセス速度の速いメモリ２にデータを配置していく。例えば、0x80000000〜0x80000010における差分が他よりも大きいために、リンカが、0x80000000〜0x80000010に置かれていたデータをメモリ２に配置することを決定した場合、実際の配置アドレスを、図５に示されているメモリ２の開始アドレス0x84000000〜終端アドレス0x84008000の間のアドレスになるように再配置を行う。
【００５２】
容量の問題でメモリ２に配置できなくなったら、リンカは、残りのデータをメモリ１に配置するようにする。このようにリンカが、図６の表に基づいてデータを再配置していき、プログラムを生成する。このようにして生成されたプログラムは、メモリアクセス時間が最短となる最適化されたプログラムとなる。
【００５３】
以上説明したように、本実施形態によれば、コンパイル及びリンクによりプログラムを生成する際に、複数のメモリにおけるアクセス速度の違いを考慮した最適化を実現できる。その結果、生成されるプログラムの更なるパフォーマンス向上を実現できる。
【００５４】
〔第２の実施形態〕
本実施形態では、速度差の異なるキャッシュメモリとメインメモリを備えたコンピュータでの動作を想定したプログラムを生成する場合に、キャッシュメモリのヒット率を向上させるメモリアクセスの最適化を実現する例について説明する。
【００５５】
プログラム生成装置は、まず１回目のコンパイル・リンクを行う。つまり、コンパイラ・リンカは、第１の実施形態における図２のステップ１と同様に、ソースコードを入力として受け取り、通常のコンパイル・リンク（メモリアクセスの最適化は行わない）を行ってプログラムを生成する。
【００５６】
上記生成されたプログラムは、第１の実施形態における図２のステップ２と同様に、動作コンピュータにおいて実行され、メモリプロファイラによってメモリアクセス（読み出し、書き込み）を監視され、ログとしてプロファイルデータが取得される。本実施形態における動作コンピュータの構成は、図３において、メモリ１がＲＡＭ（Random Access Memory。メインメモリの一例）、メモリ２がキャッシュメモリとなる。高速なキャッシュメモリは、アドレス空間にマップされることなく、低速なＲＡＭの一部をコピーとして保持し、メモリアクセスを高速化させる。
【００５７】
そして、プログラム生成装置は、２回目のコンパイル・リンクを行う。つまり、コンパイラは、第１の実施形態における図２のステップ３−１、３−２と同様に、上記プロファイルデータと、ユーザにより予め作成されたメモリデバイス情報とを入力として受け取り、通常のコンパイルを行い、オブジェクトファイルを生成する（上述したように、前に生成したオブジェクトファイルがある場合、この動作は省略されてもよい）。
【００５８】
その後、プログラム生成装置は、リンカによりキャッシュメモリのヒット率を向上させるためのメモリアクセスの最適化を行うことになるが、ここで、本実施形態におけるプロファイルデータ及びメモリデバイス情報の具体例について以下にそれぞれ説明する。
【００５９】
まず、図７を用いてプロファイルデータ（第２プロファイルデータの一例）の例について説明する。図７は、アドレス空間において、１回目のコンパイル・リンクで生成されたプログラム（ＣＰＵ）がどのような順序で、どのようなアドレスにアクセスを行ったかについて、メモリプロファイラが記録した例を示している。
【００６０】
動作コンピュータにおいて１回目のコンパイル・リンクで生成されたプログラムの動作が開始されると、メモリプロファイラは、そのプログラムの実行によるメモリアクセスを監視する。そして、メモリプロファイラは、メモリアクセスを検知すると、アクセス先のアドレス（アクセスアドレス）、アクセスのサイズ（アクセスサイズ）、アクセスが読み出しであるか書き込みであるか（ＲＥＡＤ／ＷＲＩＴＥ）を、時系列に逐次記録する。
【００６１】
ここで、アクセスされたアドレスは実際にはＲＡＭかキャッシュメモリになるわけであるが、メモリプロファイラは、それを関知せず、アクセスアドレス、アクセスサイズ、ＲＥＡＤ／ＷＲＩＴＥのみを記録する。図７の例では、最初にアドレス0x8049000に４バイトのサイズで読み出しアクセスがあり、次にアドレス0x8049020に２バイトの読み出しアクセスがあったことが記録されている。
【００６２】
このように、実行されたメモリアクセスは、順次記録されていく。キャッシュメモリのヒット率を向上させるためのメモリアクセスの最適化には、図７に示すプロファイルデータが必要となる。
【００６３】
なお、第１の実施形態における図４のプロファイルデータと、本実施形態における図７のプロファイルデータは、どちらもメモリプロファイラが取得したデータであるが、性格がかなり異なる。図４では、アドレス範囲毎の読み書き総数が記録されているが、読み書きの順番は記録されていない。一方、図７では、読み書きの順番を記録すべく、読み書き毎に逐一記録を行っている。すなわち、１つのメモリアクセスにつき記録が１行増えることになる。よって、図７は、図４に比べて、データ量が膨大になる。
【００６４】
このようなことから、動作コンピュータ上のストレージデバイスでは容量が不足するおそれもある。よって、図７のプロファイルデータは、動作コンピュータの外部のストレージデバイスに蓄えられるようにしてもよい。
【００６５】
次に、図８を用いてメモリデバイス情報（第２メモリデバイス情報の一例）の例について説明する。図８に示すメモリデバイス情報も、第１の実施形態における図５のメモリデバイス情報と同様にして、ユーザにより予め作成される。
【００６６】
図８に示すように、本実施形態におけるメモリデバイス情報は、メモリデバイス毎に、開始アドレス、終端アドレス、キャッシュサイズ、キャッシュライン数、キャッシュウェイ数、読み出し速度、書き込み速度の情報を持つ。
【００６７】
図８において、ＲＡＭは、キャッシュサイズ、キャッシュライン数、キャッシュウェイ数の情報は持たない。読み出し速度は、キャッシュメモリ上にキャッシュライン単位でＲＡＭからリフィルされる時の速度である。書き込み速度は、キャッシュメモリ上からキャッシュライン単位でＲＡＭへ書き出される時の速度である。
【００６８】
図８において、キャッシュメモリは、開始アドレス、終端アドレスの情報は持たない。キャッシュサイズは、キャッシュメモリ全体の容量である。このキャッシュサイズをキャッシュライン数で割った値が、１つのキャッシュラインのサイズとなる。図８の例では、１６ＫＢ／５１２＝３２バイトが１つのキャッシュラインのサイズになる。読み出し速度は、書き込み速度は、キャッシュヒットした場合の読み書きの速度である。
【００６９】
ここで、図８に示すキャッシュウェイ数について以下に説明する。キャッシュは、メモリアクセスが行われる際に、アドレスからタグと呼ばれる情報を生成して、アドレスがどのキャッシュラインに対応するかを判別する。タグは、キャッシュヒットかキャッシュミスかを高速に判別する目的で使用され、アドレスから一意に決まる。
【００７０】
例えば、アドレスと0xF0のマスクを以てタグとする。タグに一致するキャッシュラインに紐付けされているアドレスが、アクセスアドレスと一致すればキャッシュヒットとなる一方で、アクセスアドレスと一致しなければキャッシュミスとなる。キャッシュミスの場合は、キャッシュライン上にあるデータをＲＡＭに戻しキャッシュラインから追い出して、新しいアクセスに対応してＲＡＭからデータを読み出して、そのデータをキャッシュラインにフィルする。キャッシュミスはパフォーマンス上のペナルティになるので、できるだけキャッシュミスが起こらないような方式が考案されている。
【００７１】
例えば、１つのタグで複数のキャッシュラインを持たせる方式が考案されており、ｎウェイセットアソシアティブ方式と呼ばれている。このｎウェイセットアソシアティブ方式では、タグが一致するキャッシュラインが、ｎ個同時に存在できる。キャッシュヒット・キャッシュミスは、タグに一致するキャッシュラインをウェイごとに調べ、キャッシュラインに紐付されたアドレスとアクセスアドレスが一致するかどうかを、最大ｎ回比較する。このように、同一タグで複数のキャッシュラインを持つとき、その数をキャッシュウェイ数と言う。
【００７２】
以上説明した図７のプロファイルデータ及び図８のメモリデバイス情報を使用することで、リンカは、キャッシュメモリのヒット率を向上させるためのメモリアクセス最適化を行う。この概要について以下に説明する。
【００７３】
リンカは、プロファイルデータ及びメモリデバイス情報から、メモリアクセスにかかった総計時間（メモリアクセス総計時間）を算出する。この算出は、キャッシュサイズ、キャッシュライン数、キャッシュウェイ数を考慮してキャッシュの動作をシミュレートすることによって可能である。この際、リンカは、ライン毎のキャッシュヒット率も算出しておく。キャッシュヒット率とは、メモリアクセスが行われた際に、データがキャッシュメモリ上にあった場合の割合である。
【００７４】
なお、メモリアクセス総計時間が最短となるように理論的に最適化するのは非常に困難であるので、データのアドレス配置を入れ替えながら試行し、メモリアクセス総計時間が最短となるようなアドレス配置を探していく手法をとることが好ましい。
【００７５】
ここで、上述した概要の具体例について図９を用いて説明する。図９は、リンカによって行われる、キャッシュメモリのヒット率を向上させるためのメモリアクセス最適化の動作例の一例を示すフローチャートである。図９に示すフローは、図２においてステップ３−３の代わりに行われる。
【００７６】
リンカは、まず、プロファイルデータを基に、キャッシュメモリの動作をシミュレートし、キャッシュヒット率が最も低いラインを求める（Ｓ１１）。このステップの例として、図７のプロファイルデータを用いた、キャッシュメモリ動作のシミュレートについて以下に説明する。ここで、タグはアドレスと0xF0のマスクで求められるとし、キャッシュラインサイズを１６バイトとする。
【００７７】
リンカは、0x8049000のタグ0x00(0x8049000 & 0xF0 = 0x00)のウェイ0-ウェイ3に、0x8049000がヒットするか確認する。ヒットしなければ、リンカは、ウェイ0-ウェイ3が空いているか確認する。初めてのメモリアクセスなので、ヒットはせず、ウェイはすべて空いており、リンカは、タグ0x00のウェイ0に0x8049000を紐付する。このアクセスはキャッシュミスとして記録される。
【００７８】
リンカは、0x8049020のタグ0x20(0x4809020 & 0xF0 = 0x20)のウェイ0-ウェイ3に、0x8049020がヒットするか確認する。ヒットしなければ、リンカは、ウェイ0-ウェイ3が空いているか確認する。タグ0x20のウェイはすべて空いており、リンカは、ウェイ0に0x8049020を紐付する。このアクセスはキャッシュミスとして記録される。
【００７９】
リンカは、0x8050048のタグ0x40のウェイ0-ウェイ3に、0x8050048がヒットするか確認する。ヒットしなければ、リンカは、ウェイ0-ウェイ3が空いているか確認する。タグ0x40のウェイはすべて空いており、リンカは、ウェイ0に0x8050040（0x8050048が入るキャッシュラインの先頭アドレス）を紐付する。このアクセスはキャッシュミスとして記録される。
【００８０】
リンカは、0x8049424のタグ0x20のウェイ0-ウェイ3に、0x8049424がヒットするか確認する。ヒットしなければ、リンカは、ウェイ0-ウェイ3が空いているか確認する。タグ0x20はウェイ0が0x8049020に紐付けられて使用中であり、ウェイ1-ウェイ3が空いているため、リンカは、ウェイ1に0x8049420(0x8049424が入るキャッシュラインの先頭アドレス)を紐付する。このアクセスはキャッシュミスとして記録される。
【００８１】
リンカは、0x8050120のタグ0x20がウェイ0-ウェイ3にヒットするか確認する。ヒットしなければ、リンカは、ウェイ0-ウェイ3が空いているか確認する。タグ0x20はウェイ0、ウェイ1が使用中であり、残りのウェイは空いているため、リンカは、ウェイ2に0x8050120を紐付する。このアクセスはキャッシュミスとして記録される。
【００８２】
リンカは、0x8050121のタグ0x20がウェイ0-ウェイ3にヒットするか確認する。ウェイ2にヒットするので、キャッシュヒットである。この場合は、紐付に関しては、リンカは、何もしない。このアクセスはキャッシュヒットとして記録される。
【００８３】
このようにリンカは、１アクセス毎に、タグを生成し、キャッシュにヒットするかどうか、ヒットしないならばウェイが空いているかどうか、逐一調べていく。この後、同様にアクセスを追跡していくと、キャッシュヒット、キャッシュミスが起こる。ウェイ0-ウェイ3がすべて紐付されている状態でキャッシュミスが起こると、ウェイ0-ウェイ3のいずれかがＲＡＭに戻され、キャッシュラインから追い出される。このように、メモリアクセスを順に追っていくことによって、キャッシュヒット、キャッシュミスをシミュレートすることができる。
【００８４】
以上のシミュレートを図７に示される全アクセスに対して行うと、キャッシュライン毎のキャッシュヒット率が求められる。また、リンカは、どのデータがどのアドレスに配置されるかを知っているので、どのデータが何回キャッシュヒットしたか、何回キャッシュミスしたか、どのデータアクセスによってキャッシュから追い出されたかを知ることができる。また、図８を用いることによって、アクセス時間の総計（メモリアクセス総計時間）も算出することができる。
【００８５】
次に、リンカは、キャッシュヒット率が最も低いラインにキャッシュされるデータのうち、アクセス数が最も多いデータＡをキャッシュから追い出した回数が最も多いデータＢを探す（Ｓ１２）。リンカは、上述したようにどのデータがどのアドレスに配置されるかを知っているので、Ｓ１１で求めたキャッシュヒット率が最も低いキャッシュラインに属するデータはどれなのかを、知ることができる。
【００８６】
そして、リンカは、それら複数のデータのうち、アクセス数が最も多いデータをデータＡとして特定する。リンカは、上述したようにどのデータアクセスによってキャッシュから追い出されたかを知ることができるので、特定したデータＡがどのアクセスにより最もキャッシュから追い出されたかを知ることができる。よって、リンカは、データＡをキャッシュから追い出した回数の最も多いアクセスによるデータをデータＢとして特定する。
【００８７】
次に、リンカは、データＢのアドレス配置を、データＡの近傍のデータと入れ替え、データＡとデータＢが同一キャッシュ上に載るようにする（Ｓ１３）。ここでいう「データＡの近傍のデータ」とは、「データＡが配置されたアドレスの近傍にあるアドレスに配置されたデータ」のことである。また、ここでいう「同一キャッシュ上に載る」とは、「キャッシュラインが一致する」ことである。
【００８８】
タグは一致するが、アドレスが一致しない場合、キャッシュラインが追い出される可能性がある。同じキャッシュライン上にデータＡ、データＢが存在すれば、お互いを追い出してしまうことはない。例えば、キャッシュラインサイズが１６バイトの時、データＡのアドレスが0x8049000で、データＢのアドレスが0x8049004であれば、データＡとデータＢは同一キャッシュライン上に存在する。このような状態を「同一キャッシュ上に載る」という。
【００８９】
次に、リンカは、キャッシュメモリの動作をシミュレートしながら、新しいデータ配置でのアクセス時間の総計（メモリアクセス総計時間）を計算し、それと同時にライン毎のキャッシュヒット率も計算しておく（Ｓ１４）。ここでのシミュレートは、上述したＳ１１の方法と同様である。また、メモリアクセス総計時間の計算には、図８のメモリデバイス情報が用いられる。また、ここでいう「新しいデータ配置」とは、Ｓ１３で行ったデータＢのアドレス配置をデータＡの近傍に入れ替えた状態である。
【００９０】
ここで、Ｓ１４におけるメモリアクセス総計時間の計算について説明する。リンカは、キャッシュヒットをシミュレートし、アクセス毎にキャッシュヒットかキャッシュミスかを判定し、その都度アクセスにかかる時間を加算していく。１アクセスにつき、以下の時間がかかる。なお、以下の各時間は、図８に示す読み出し速度及び書き込み速度を基に算出される。
読み出しキャッシュヒット⇒キャッシュメモリの読み出し時間
書き込みキャッシュヒット⇒キャッシュメモリの書き込み時間
読み出しキャッシュミス⇒ＲＡＭの読み出し時間
書き込みキャッシュミス⇒ＲＡＭの書き込み時間
【００９１】
図７のプロファイルデータには全てのアクセスについて読み出しアクセスなのか、書き込みアクセスなのかが記録されており、また、上記キャッシュメモリ動作のシミュレートではキャッシュヒット／キャッシュミスの判別がつくので、上記アクセスにかかる時間を加算していけば、リンカは、全てのアクセスに要した時間、すなわちメモリアクセス総計時間を算出することができる。
【００９２】
なお、Ｓ１４におけるライン毎のキャッシュヒット率の計算は、上述したＳ１１の方法と同様のキャッシュメモリ動作のシミュレートによって実現される。ここでの計算結果は、このＳ１４以降において再度Ｓ１２に戻った場合に、キャッシュヒット率が最も低いラインの特定に用いられる。
【００９３】
次に、リンカは、データＡの近傍で入れ替えを試していない箇所がないかを判断する（Ｓ１５）。ここでいう「近傍」とは、「データＡと同一キャッシュラインに載る範囲」である。例えば、データＡ、データＢの大きさを４バイト、キャッシュラインサイズを１６バイトとすると、データＡの近傍は１２バイト分になる。よって、データＢの置き換え（入れ替え）は、３回行われる。すなわち、図９において、Ｓ１５／ＮＯ〜Ｓ１３〜Ｓ１４というループが３回行われることになる。
【００９４】
例として、データＡの近傍の１２バイトを４バイトずつ、仮にＡ２、Ａ３、Ａ４とした場合、リンカは、Ａ２とＢを置き換えてキャッシュシミュレートを行い、キャッシュヒット率及びメモリアクセス総計時間を算出する。次に、リンカは、Ａ３とＢを置き換えて同様にキャッシュシミュレートを行い、キャッシュヒット率及びメモリアクセス総計時間を算出する。最後に、リンカは、Ａ４とＢを置き換えて同様にキャッシュシミュレートを行い、キャッシュヒット率及びメモリアクセス総計時間を算出する。この最後の計算が終わると、リンカは、データＡの近傍で全ての入れ替えを試したと判断する（Ｓ１５／ＹＥＳ）。
【００９５】
次に、リンカは、アクセス時間最短となった時の、データＢとデータＡの近傍とのアドレス入れ替えを採用する（Ｓ１６）。すなわち、リンカは、データＢを、データＡの近傍のアドレス（アクセス時間が最短となったもの）に配置するようにし、かつ、そのデータＡの近傍のアドレスに配置されていたデータを、データＢが配置されていたアドレスに配置するようにする。
【００９６】
例えば、上記Ｓ１５で例示したように、データＡの近傍がＡ２、Ａ３、Ａ４であり、それらＡ２、Ａ３、Ａ４とＢとを置き換えてメモリアクセス総計時間をそれぞれ算出した場合、リンカは、置き換えを行わなかった場合のメモリアクセス総計時間と、置き換えを行ってシミュレートした３回それぞれのメモリアクセス総計時間とを比較し、メモリアクセス総計時間が最も短くなる置き換え方法を採用する。つまり、リンカは、Ａ２とＢの置き換え、Ａ３とＢの置き換え、Ａ４とＢの置き換えのうち、メモリアクセス総計時間が最も短くなる置き換えを採用する。
【００９７】
リンカは、Ｓ１６による置き換え（入れ替え）の結果、メモリアクセス総計時間が短縮したかを判断する（Ｓ１７）。メモリアクセス総計時間が短縮しなかった場合（置き換えた方が逆にメモリアクセス総計時間が長くなってしまった場合）（Ｓ１７／ＮＯ）、一連のステップを終了する。
【００９８】
メモリアクセス総計時間が短縮した場合（Ｓ１７／ＹＥＳ）、リンカは、キャッシュヒット率が最も低いラインは、データＡが載っているラインとは異なるラインになったかを判断する（Ｓ１８）。キャッシュヒット率が最も低いキャッシュラインが変わらない場合は（Ｓ１８／ＮＯ）、一連のステップを終了する。
【００９９】
キャッシュヒット率が最も低いキャッシュラインが変わった場合は（Ｓ１８／ＹＥＳ）、リンカは、Ｓ１２以降のステップを、予め定められた所定回数繰り返したかどうかを判断する（Ｓ１９）。リンカは、Ｓ１２以降のステップを所定回数繰り返したら（Ｓ１９／ＹＥＳ）、一連のステップを終了する。
【０１００】
上述した図９のフローに従えば、メモリアクセス総計時間の短縮が見込まれる。データのアドレス入れ替え試行数が多ければ多いほど、より短いアクセス総計時間が見つかる可能性が高いが、上記説明では実装し易い単純な例を示した。
【０１０１】
以上説明したように、本実施形態によれば、コンパイル及びリンクによりプログラムを生成する際に、キャッシュメモリとメインメモリにおけるアクセス速度の違いを考慮した最適化を実現できる。その結果、キャッシュヒット率を向上させ、生成されるプログラムの更なるパフォーマンス向上を実現できる。
【０１０２】
〔第３の実施形態〕
上記第２の実施形態では、アクセス速度の異なるキャッシュメモリとメインメモリとしてのＲＡＭを備えた動作コンピュータでの動作を想定したプログラムを生成する場合について説明した。本実施形態では、キャッシュメモリとＲＡＭの他に、ＳＲＡＭ（Static RAM。第３メモリの一例）を追加した動作コンピュータでの動作を想定したプログラムを生成する場合について説明する。アクセス速度は、キャッシュメモリが最も速く、その次にＳＲＡＭが速く、ＲＡＭが最も遅いとする。
【０１０３】
本実施形態におけるプログラム生成の際のメモリアクセスの最適化の概要について説明する。ＳＲＡＭはキャッシュメモリと違い、プログラム空間にマップされ自由にデータを配置できる。そこでまず、アクセス頻度（アクセス回数）の高いデータを、頻度の高い順にＳＲＡＭに配置するよう、再配置を行う。その上で、上述の第２の実施形態で説明した図９のフローを行うようにする。これにより、キャッシュメモリとＲＡＭの他にＳＲＡＭを備えた動作コンピュータでの動作を想定したプログラムを生成する際にメモリアクセスの最適化を行うことができる。
【０１０４】
上記概要について具体例を用いて説明する。本実施形態ではまず、上記第１の実施形態で説明した図２のステップ１〜３−２までが行われる。
【０１０５】
なお、ステップ３−１において、プロファイルデータは例えば図７に示すものとし、メモリデバイス情報は例えば図５に示すもの及び図８に示すものの両方とする。
【０１０６】
そして、ステップ３−２の後、リンカは、ステップ３−３の代わりとして、以下の動作を行う。
【０１０７】
なお、本実施形態でのメモリデバイス情報については、説明の便宜上図５と図８を分けて説明するが、それら両方を統合したものであってもよい。また、本実施形態でのメモリデバイス情報（第３メモリデバイス情報の一例）は、図５及び図８において、「メモリデバイス」の欄に「ＳＲＡＭ」が追加され、そのＳＲＡＭについて各種情報（開始アドレス、終端アドレス、読み出し速度、書き込み速度）が追加されているとする。
【０１０８】
まず、リンカは、全てのデータがどのアドレスに配置されるかを知っているので、図７のプロファイルデータの１行１行において、どのデータに対するアクセスが行われたかを知ることができる。そのようにして図７のプロファイルデータを全て調べることにより、リンカは、データ毎のアクセス頻度を知ることができる。よって、リンカは、アクセス頻度の高いデータを特定できる。
【０１０９】
次に、リンカは、図７のプロファイルデータ及び図５のメモリデバイス情報を基に、上記第１の実施形態において図６を用いて説明した動作を行う。この動作において、リンカはまず、図７に示すデータ（アクセスアドレス）毎に、読み出し回数及び書き込み回数を集計する。
【０１１０】
次にリンカは、その集計の結果と図５に示される読み出し速度及び書き込み速度を基に、図７に示すデータ毎に、そのデータが仮にＲＡＭに配置された場合と仮にＳＲＡＭに配置された場合それぞれの読み書き合計時間を算出する。この算出には、図５の読み出し速度、書き込み速度が用いられる（読み書き合計時間＝読み出し回数×読み出し速度＋書き込み回数×書き込み速度）。
【０１１１】
次にリンカは、図７に示すデータ毎に、算出した２つの読み書き合計時間（仮にＲＡＭに配置された場合の読み書き合計時間と仮にＳＲＡＭに配置された場合の読み書き合計時間）の差を算出する。
【０１１２】
そして、リンカは、図７に示すデータのうち、差が大きいデータから順にＳＲＡＭに配置するようにする。このようにして、アクセス頻度の高いデータを、頻度の高い順にＳＲＡＭに配置する再配置が行われる。なお、ＳＲＡＭに配置されなかったデータは、ＲＡＭに配置される。
【０１１３】
次に、リンカは、上記再配置後の全てのデータ、すなわちＳＲＡＭに配置するようにしたデータ及びＲＡＭに配置するようにしたデータの両方を対象に、上記第２の実施形態で説明した図９のフローを行う。なお、図９のフローを行う対象を全てのデータとする理由は、キャッシュメモリは、アクセスが、ＲＡＭに対するものであろうが、ＳＲＡＭに対するものであろうが、分け隔てなくキャッシュヒット、キャッシュミスの処理を行う為である。
【０１１４】
図９のフローは、上記第２の実施形態で説明したのと同様に行われる。ただし、Ｓ１４においてアクセス時間の総計を計算する際には、キャッシュメモリ、ＳＲＡＭ、ＲＡＭそれぞれについての算出が必要となる。そのため、その算出に用いられる図８のメモリデバイス情報には、ＳＲＡＭについての情報（少なくとも読み出し速度及び書き込み速度を含む）が追加されている必要がある。
【０１１５】
以上説明したように、本実施形態によれば、コンパイル及びリンクによりプログラムを生成する際に、キャッシュメモリ、メインメモリ及びＳＲＡＭにおけるアクセス速度の違いを考慮した最適化を実現できる。その結果、ＳＲＡＭの有効利用及びキャッシュヒット率の向上によって、生成されるプログラムの更なるパフォーマンスの向上を実現できる。
【０１１６】
なお、本実施形態では、データの再配置を行うにあたり、図７のプロファイルデータを用いるものとしたが、図４を用いるようにしてもよい。ただし、図４はアドレス範囲毎のアクセス回数を記録したものであるので、図４を用いる場合は、図７を用いたときの１バイト／２バイト／４バイト単位での再配置ではなく、１６バイト単位での再配置となる。また、図４を用いる場合、データ毎のアクセス頻度は特定できないため、リンカは、図４に示すアドレス範囲毎に、読み出し回数及び書き込み回数を集計したり、所定のアドレス範囲に置かれていたデータが仮にＲＡＭに配置された場合と仮にＳＲＡＭに配置された場合それぞれの読み書き合計時間を算出したりする（この点は第１の実施形態と同様）。
【０１１７】
〔第４の実施形態〕
本実施形態では、ＮＵＭＡ（Non-Uniform Memory Access）を採用したコンピュータでの動作を想定したプログラムを生成する場合について説明する。
【０１１８】
図１０にＮＵＭＡの構成例を示す。図１０のように、ＮＵＭＡにおいては、ＣＰＵとメモリの対から成るノードが複数存在する。図１０の例では、ノード１（第１ノードの一例）、ノード２（第２ノードの一例）のそれぞれにおいて、メモリ１とＣＰＵ１（第１プロセッサの一例）とが対、メモリ２とＣＰＵ２（第２プロセッサの一例）とが対となっている。あるＣＰＵから見た場合、同じノードにあるメモリは速くアクセスできるが、他のノードにあるメモリへのアクセスは遅い。
【０１１９】
まず本実施形態の概要について説明する。ＮＵＭＡ環境においてメモリアクセスを最適化するために、本実施形態では、プログラムが動作するＣＰＵを固定した上で、頻繁にアクセスされるデータは、そのプログラムが動作しているのと同じノードのメモリに配置するようにする。ＣＰＵを固定しないとすると、他のノード上のＣＰＵで動作してしまう可能性があり、この場合は逆にメモリアクセスが遅くなってしまう。そのため、ＮＵＭＡ環境における最適化は、プログラムが動作するＣＰＵを固定する。例えば、プログラムが動作するＣＰＵをノード１のＣＰＵに固定し、頻繁にアクセスされるデータはメモリ１に配置し、そうではないデータはメモリ２に配置するようにする。
【０１２０】
上記概要について具体例を用いて説明する。本実施形態ではまず、上記第１の実施形態で説明した図２のステップ１〜３−２までが行われる。
【０１２１】
なお、ステップ１の１回目のコンパイル・リンクのときは、特にプログラムを実行するＣＰＵを固定しない。よって、ステップ２で１回目のコンパイル・リンクで生成されたプログラムは、図１０に示すＮＵＭＡを採用した動作コンピュータにおいて、ＣＰＵを固定されないまま実行、動作される。
【０１２２】
また、ステップ３−１において、プロファイルデータは例えば図７に示すものとし、メモリデバイス情報は例えば図５に示すものとする。
【０１２３】
また、ステップ３−２において、コンパイラは、プログラムが動作するＣＰＵが実行中に変わらないようにするために、ＣＰＵの固定を行う。すなわちコンパイラは、複数あるＣＰＵのうちいずれかを選択し、プログラムの先頭において、選択したＣＰＵを固定する専用命令を発行するようにした上でコンパイルを行い、リンカに渡す。これにより、リンカは、メモリ１又はメモリ２のどちらが、コンパイラにより固定されたＣＰＵと同じノードにあるメモリであるかを知ることができる。
【０１２４】
そして、ステップ３−２の後、リンカは、ステップ３−３の代わりとして、以下の動作を行う。基本的には、上記第３の実施形態と同様である。
【０１２５】
まず、リンカは、全てのデータがどのアドレスに配置されるかを知っているので、図７のプロファイルデータの１行１行において、どのデータに対するアクセスが行われたかを知ることができる。そのようにして図７のプロファイルデータを全て調べることにより、リンカは、データ毎のアクセス頻度を知ることができる。よって、リンカは、アクセス頻度の高いデータを特定できる。
【０１２６】
次に、リンカは、図７のプロファイルデータ及び図５のメモリデバイス情報を基に、上記第１の実施形態において図６を用いて説明した動作を行う。この動作において、リンカはまず、図７に示すデータ（アクセスアドレス）毎に、読み出し回数及び書き込み回数を集計する。
【０１２７】
次にリンカは、その集計の結果と図５に示される読み出し速度及び書き込み速度を基に、図７に示すデータ毎に、そのデータが仮にメモリ１に配置された場合と仮にメモリ２に配置された場合それぞれの読み書き合計時間を算出する。この算出には、図５の読み出し速度、書き込み速度が用いられる（読み書き合計時間＝読み出し回数×読み出し速度＋書き込み回数×書き込み速度）。
【０１２８】
次にリンカは、図７に示すデータ毎に、算出した２つの読み書き合計時間（仮にメモリ１に配置された場合の読み書き合計時間と仮にメモリ２に配置された場合の読み書き合計時間）の差を算出する。
【０１２９】
そして、リンカは、図７に示すデータのうち、差が大きいデータから順に、コンパイラにより固定されたＣＰＵと同じノードにあるメモリ（同一ノードにおいて、固定されたＣＰＵと対となっているメモリ）に配置するようにする。メモリ１又はメモリ２のどちらが、コンパイラにより固定されたＣＰＵと同じノードにあるメモリであるかは、リンカが、コンパイラにより発行された専用命令を参照することで認識できる。
【０１３０】
このようにして、アクセス頻度の高いデータを、頻度の高い順に、プログラムが実行されるノードのメモリに配置する再配置が行われる。なお、プログラムが実行されるノードのメモリに配置されなかったデータは、別のノードのメモリに配置される。
【０１３１】
以上説明したように、本実施形態によれば、コンパイル及びリンクによりプログラムを生成する際に、ＮＵＭＡにおける複数のメモリのアクセス速度の違いを考慮した最適化を実現できる。その結果、生成されるプログラムの更なるパフォーマンスの向上を実現できる。
【０１３２】
なお、本実施形態では、データの再配置を行うにあたり、図７のプロファイルデータを用いるものとしたが、図４を用いるようにしてもよい。図４を用いる場合、リンカは、図４に示すアドレス範囲毎に、読み出し回数及び書き込み回数を集計したり、所定のアドレス範囲に置かれていたデータが仮にメモリ１に配置された場合と仮にメモリ２に配置された場合それぞれの読み書き合計時間を算出したりする（この点は第１の実施形態と同様）。
【０１３３】
〔第５の実施形態〕
本実施形態では、ＮＵＭＡを採用したコンピュータでの動作を想定したプログラムとして、マルチスレッドプログラムを生成する場合について説明する。
【０１３４】
まず本実施形態の概要について説明する。本実施形態では、スレッド間で共有される共有データは、その共有データにアクセスする回数が最も多いスレッドが動作するＣＰＵと同じノードのメモリに配置するようにし、また、あるスレッドのみからアクセスされる非共有データは、なるべくそのスレッドが動作するＣＰＵと同じノードのメモリに配置するようにする。このようにすることによって、ＮＵＭＡで動作するマルチスレッドプログラムのメモリアクセスを最適化する。
【０１３５】
上記概要について具体例を用いて説明する。本実施形態ではまず、上記第１の実施形態で説明した図２のステップ１〜３−２までが行われる。
【０１３６】
なお、ステップ１の１回目のコンパイル・リンクのときは、マルチスレッドプログラムが生成される。このとき、そのプログラムを実行するＣＰＵは固定されない。よって、ステップ２で１回目のコンパイル・リンクで生成されたマルチスレッドプログラムは、図１０に示すＮＵＭＡを採用した動作コンピュータにおいて、ＣＰＵを固定されないまま実行、動作される。
【０１３７】
また、ステップ３−１において、プロファイルデータは例えば図１１に示すものとし、メモリデバイス情報は例えば図５に示すものとする。
【０１３８】
図１１に示すプロファイルデータは、動作コンピュータ上のメモリプロファイラがメモリアクセスを監視することで得られるのは、これまで説明した各実施形態と同様である。ただし、図１１のプロファイルデータは、図４や図７で例示したものと中身が異なる。すなわち、図１１のプロファイルデータでは、開始アドレスと終端アドレスとで示されるアドレス範囲毎に、各スレッドの読み出し回数と書き込み回数が対応付けられて記録された情報となっている。
【０１３９】
また、ステップ３−２では、第４の実施形態と同様に、コンパイラは、プログラムが動作するＣＰＵが実行中に変わらないようにするために、ＣＰＵの固定を行う。ただし、本実施形態では、コンパイラは、図１１のプロファイルデータを基に、共有データをアクセスする回数が最も高いスレッドを特定した上で、そのスレッドが動作するＣＰＵを固定する。スレッドの特定について以下に説明する。
【０１４０】
コンパイラは、図１１において、アドレス範囲毎に、全てのスレッドがアクセスしているか調べる。図１１の例では、アドレス範囲0x80000000-0x80000010のデータが、スレッド0xA0、0xC0、0xF0の全部からアクセスされているので、コンパイラは、そのデータを共有データとみなす。
【０１４１】
次に、コンパイラは、図１１において、その共有データに対する読み出し回数と書き込み回数を参照し、最もアクセス回数の多いスレッドを特定する。図１１の例では、アドレス範囲0x80000000-0x80000010の共有データに最もアクセスが多いのはスレッドID 0xC0のスレッドである。
【０１４２】
次に、コンパイラは、特定したスレッド0xC0が動作するＣＰＵを、図１０のＣＰＵ１又はＣＰＵ２のいずれかに固定する。
【０１４３】
また、コンパイラは、アドレス範囲毎に、特定のスレッドのみがアクセスしているかも調べる。図１１の例では、アクセス範囲0x80000010-0x80000020のデータは、スレッド0xA0のみからアクセスされているため、非共有データとみなされ、スレッド0xA0が動作するＣＰＵを、図１０のＣＰＵ１又はＣＰＵ２のいずれかに固定する。
【０１４４】
以上のようなステップ３−２の後、リンカは、ステップ３−３の代わりとして、以下の動作を行う。
【０１４５】
リンカは、図１１のプロファイルデータ及び図５のメモリデバイス情報を基に、上記第１の実施形態において図６を用いて説明した動作を行う。この動作において、リンカはまず、図１１に示すアドレス範囲毎に、読み出し回数及び書き込み回数を集計する。このとき、読み出し回数は、全てのスレッド（図１１では0xA0、0xC0、0xF0）の読み出し回数の合計となり、書き込み回数も、全てのスレッドの書き込み回数の合計となる。
【０１４６】
次にリンカは、その集計の結果と図５に示される読み出し速度及び書き込み速度を基に、図１１に示すアドレス範囲毎に、そのアドレス範囲に置かれていたデータが仮にメモリ１に配置された場合と仮にメモリ２に配置された場合それぞれの読み書き合計時間を算出する。この算出には、図５の読み出し速度、書き込み速度が用いられる（読み書き合計時間＝読み出し回数×読み出し速度＋書き込み回数×書き込み速度）。
【０１４７】
次にリンカは、図１１に示すアドレス範囲毎に、算出した２つの読み書き合計時間（仮にメモリ１に配置された場合の読み書き合計時間と仮にメモリ２に配置された場合の読み書き合計時間）の差を算出する。
【０１４８】
そして、リンカは、図１１に示すアドレス範囲のうち、差が大きいアドレス範囲に置かれていたデータ（共有データ及び非共有データ）から順に、コンパイラにより固定されたＣＰＵと同じノードにあるメモリ（同一ノードにおいて、固定されたＣＰＵと対となっているメモリ）に配置するようにする。メモリ１又はメモリ２のどちらが、コンパイラにより固定されたＣＰＵと同じノードにあるメモリであるかは、リンカが、コンパイラにより発行された専用命令を参照することで認識できる。
【０１４９】
このようにして、アクセス頻度の高いデータ共有データ及び非共有データについて、頻度の高い順に、プログラムが実行されるノードのメモリに配置する再配置が行われる。なお、プログラムが実行されるノードのメモリに配置されなかったデータは、別のノードのメモリに配置される。
【０１５０】
以上説明したように、本実施形態によれば、コンパイル及びリンクによりＮＵＭＡで動作するマルチスレッドプログラムを生成する際に、共有データ、非共有データに対するメモリアクセスの最適化を実現できる。その結果、生成されるプログラムのパフォーマンス向上を実現できる。
【０１５１】
〔第６の実施形態〕
本実施形態では、ＮＵＭＡを採用した図１０に示す構成において、ノード１及びノード２のそれぞれにキャッシュメモリを備えたコンピュータでの動作を想定したプログラムを生成する場合について説明する。
【０１５２】
本実施形態では、まず、上述した第４の実施形態の動作又は第５の実施形態の動作を行う。次に、ノード毎に、上述した第２の実施形態の動作（図９のフロー）を行い、キャッシュメモリのヒット率を向上させる。ただし、先行する第４の実施形態の動作又は第５の実施形態の動作の際に、後続の第２の実施形態の動作で必要な情報（プロファイルデータ及びメモリデバイス情報）をコンパイラ・リンカが取得できた場合は、第２の実施形態の動作において、先行動作と重複するステップ（例えば、図３のステップ１〜ステップ３−２）を省略してもよい。
【０１５３】
第２の実施形態の動作を行うにあたり、ノード１においては、メモリ１に配置されるようにした以外のデータ（リモートメモリ（メモリ２）に配置されるようにしたデータ）と、メモリ１に配置されるようにしたデータ（ローカルメモリ（メモリ１）に配置されるようにしたデータ）の両方を対象にする必要がある。また、第２の実施形態の動作を行うにあたり、ノード２においては、メモリ２に配置されるようにした以外のデータ（リモートメモリ（メモリ１）に配置されるようにしたデータ）と、メモリ２に配置されるようにしたデータ（ローカルメモリ（メモリ２）に配置されるようにしたデータ）の両方を対象にする必要がある。これは、第３の実施形態で説明したキャッシュメモリ、ＲＡＭ、ＳＲＡＭの関係と同じである。
【０１５４】
すなわち、キャッシュメモリは、アクセスがローカルメモリに対するものであろうが、リモートメモリに対するものであろうが、分け隔てなくキャッシュヒット、ミスの処理を行うため、ローカルメモリへ配置するようにしたデータと、リモートメモリへ配置するようにしたデータの両方を、第２の実施形態の動作を行う対象にする必要がある。
【０１５５】
なお、本実施形態で行われる第２の実施形態の動作として図９のフローの流れに変わりはないが、アクセス時間の総計を計算する際には、キャッシュ、ローカルメモリ、リモートメモリの読み書きアクセス時間が必要になる。従って、図８のメモリデバイス情報では、キャッシュメモリ、ローカルメモリ、リモートメモリの情報が必要になる。例えば、図８において、「ＲＡＭ」の代わりに「メモリ１」、「メモリ２」とし、それぞれについて各種情報（開始アドレス、終端アドレス、読み出し速度、書き込み速度）が定義されればよい。
【０１５６】
以上説明したように、本実施形態によれば、コンパイル及びリンクによりプログラムを生成する際に、ＮＵＭＡにおいて各ノードにキャッシュメモリを含む場合の、複数のメモリのアクセス速度の違いを考慮した最適化を実現できる。その結果、キャッシュヒット率を向上させ、生成されるプログラムの更なるパフォーマンス向上を実現できる。
【０１５７】
以上、本発明の各実施形態について説明したが、上記各実施形態に限定されるものではなく、その要旨を逸脱しない範囲において種々の変形が可能である。
【０１５８】
例えば、上述した実施形態における動作は、ハードウェア、または、ソフトウェア、あるいは、両者の複合構成によって実行することも可能である。
【０１５９】
ソフトウェアによる処理を実行する場合には、処理シーケンスを記録したプログラムを、専用のハードウェアに組み込まれているコンピュータ内のメモリにインストールして実行させてもよい。あるいは、各種処理が実行可能な汎用コンピュータにプログラムをインストールして実行させてもよい。
【０１６０】
例えば、プログラムは、記録媒体としてのハードディスクやＲＯＭ（Read Only Memory）に予め記録しておくことが可能である。あるいは、プログラムは、ＣＤ−ＲＯＭ（Compact Disc Read Only Memory）、ＭＯ（Magneto Optical）ディスク、ＤＶＤ（Digital Versatile Disc）、ＵＳＢ（Universal Serial Bus）メモリ、磁気ディスク、半導体メモリなどのリムーバブル記録媒体に、一時的、あるいは、永続的に格納（記録）しておくことが可能である。このようなリムーバブル記録媒体は、いわゆるパッケージソフトウエアとして提供することが可能である。
【０１６１】
なお、プログラムは、上述したようなリムーバブル記録媒体からコンピュータにインストールする他、ダウンロードサイトから、コンピュータに無線転送してもよい。または、ＬＡＮ（Local Area Network）、インターネットといったネットワークを介して、コンピュータに有線で転送してもよい。コンピュータでは、転送されてきたプログラムを受信し、内蔵するハードディスク等の記録媒体にインストールすることが可能である。
【０１６２】
また、上記実施形態で説明した処理動作に従って時系列的に実行されるのみならず、処理を実行する装置の処理能力、あるいは、必要に応じて並列的にあるいは個別に実行するように構築することも可能である。
【先行技術文献】
【特許文献】
【０１６３】
【特許文献１】特表２００７−５１８１７６号公報
【図１】
2012247827.tif 000003
【図２】
2012247827.tif 000004
【図３】
2012247827.tif 000005
【図４】
2012247827.tif 000006
【図５】
2012247827.tif 000007
【図６】
2012247827.tif 000008
【図７】
2012247827.tif 000009
【図８】
2012247827.tif 000010
【図９】
2012247827.tif 000011
【図１０】
2012247827.tif 000012
【図１１】
2012247827.tif 000013