(57)【要約】      （修正有）【課題】マルチスレッドプログラムにおいて、並列処理の実行方法毎に、キャッシュメモリへのアクセスに関するプロファイル情報を高速で取得する技術を提供する。【解決手段】情報処理装置１０は、第１変換部１１と、計測部１２と、第２変換部１３と、生成部１４と、取得部１５とを含む。第１変換部は、対象プログラムのプログラム情報を、イベントカウント情報生成プログラムに変換する。計測部は、イベントカウント情報生成プログラムを実行し、イベント（キャッシュメモリへのアクセス）カウント情報を生成する。第２変換部は、対象プログラムのプログラム情報を、イベント行列情報生成プログラムに変換する。生成部１４は、複数の異なる並列実行方法毎に、イベント行列情報生成プログラムを実行し、イベント行列情報を生成する。取得部は、イベント行列情報の各要素が示すキャッシュメモリへのアクセスの成否に関連するプロファイル情報を生成する。【選択図】図１
2018124892.tif 000002
【特許請求の範囲】
【請求項１】
複数のスレッドが並列処理を実行するプログラムの実行時における、各スレッドから主記憶装置へのアクセス要求に対応するキャッシュメモリへのアクセスを表す行列を、前記並列処理についての複数の異なる実行方法毎に生成する生成部と、
前記実行方法の各々について、前記生成部で生成された行列の要素が示す前記キャッシュメモリへのアクセスの成否に関連する情報を取得する取得部と、
を含む情報処理装置。
【請求項２】
前記取得部は、前記キャッシュメモリへのアクセスの成否に関する情報として、キャッシュミスの回数を取得し、前記キャッシュミスの回数と前記実行方法とを対応付けて出力する請求項１に記載の情報処理装置。
【請求項３】
前記取得部は、前記キャッシュミスの回数が最も少ない場合に対応する前記実行方法を出力する請求項２に記載の情報処理装置。
【請求項４】
前記生成部は、前記アクセスを要求したスレッドと、該アクセスが要求されたタイミングとを対応させた行列であって、各スレッドからアクセスされる前記キャッシュメモリにアクセスするデータのアドレスを要素とする行列を生成する請求項１〜請求項３のいずれか１項記載の情報処理装置。
【請求項５】
前記並列処理は、ループ変数毎の処理を複数のスレッドの各々に割り当ててループを実行する処理である請求項１〜請求項４のいずれか１項に記載の情報処理装置。
【請求項６】
前記実行方法は、並列処理を実行するスレッド数、各スレッドに割り当てるループのチャンクサイズ、及びスレッドのスケジュール方法の種類に基づいて決定される請求項５に記載の情報処理装置。
【請求項７】
前記ループの実行時における前記キャッシュメモリへのアクセス回数をループ変数毎に計測する計測部を含み、
前記生成部は、前記計測部により計測されたループ変数毎のアクセス回数を利用して、前記スケジュール方法の種類に応じて、前記ループ変数毎の処理がいずれのスレッドに割り当てられるかを特定する
請求項６に記載の情報処理装置。
【請求項８】
主記憶装置へのアクセスの情報、及びキャッシュメモリの構成情報に基づいて、
前記取得部は、前記主記憶装置へのアクセス要求に対応するキャッシュメモリのキャッシュセット番号を特定し、該キャッシュセット番号が示すキャッシュセットに、前記主記憶装置へのアクセス要求に対応するデータが存在するか否かを模擬して、キャッシュメモリへのアクセスの成否に関連する情報を取得する
請求項１〜請求項７のいずれか１項に記載の情報処理装置。
【請求項９】
前記取得部は、前記キャッシュメモリが複数のキャッシュセットに分割されている場合、前記キャッシュセット毎に前記キャッシュメモリへのアクセスの成否に関連する情報を取得する請求項１〜請求項８のいずれか１項に記載の情報処理装置。
【請求項１０】
前記取得部は、前記キャッシュセット毎の前記キャッシュメモリへのアクセスの成否に関連する情報を取得する処理を、前記キャッシュセット毎に並列に実行する請求項９に記載の情報処理装置。
【請求項１１】
複数のスレッドが並列処理を実行するプログラムの実行時における、各スレッドから主記憶装置へのアクセス要求に対応するキャッシュメモリへのアクセスを表す行列を、前記並列処理についての複数の異なる実行方法毎に生成し、
前記実行方法の各々について、生成した行列の要素が示す前記キャッシュメモリへのアクセスの成否に関連する情報を取得する
ことを含む処理をコンピュータが実行する情報処理方法。
【請求項１２】
複数のスレッドが並列処理を実行するプログラムの実行時における、各スレッドから主記憶装置へのアクセス要求に対応するキャッシュメモリへのアクセスを表す行列を、前記並列処理についての複数の異なる実行方法毎に生成し、
前記実行方法の各々について、生成した行列の要素が示す前記キャッシュメモリへのアクセスの成否に関連する情報を取得する
ことを含む処理をコンピュータに実行させる情報処理プログラム。
【発明の詳細な説明】
【技術分野】
【０００１】
開示の技術は、情報処理装置、情報処理方法、及び情報処理プログラムに関する。
【背景技術】
【０００２】
従来、プログラム実行時のキャッシュメモリへのアクセスに関するプロファイル情報を取得する技術が存在する。
【０００３】
例えば、判定対象データに対応するキャッシュセットが、予め選択されたキャッシュセットであるか否かを判定し、選択されたキャッシュセットに対応するメモリ領域のアドレス情報を記憶するシステムが提案されている。このシステムは、キャッシュセットが予め選択されたキャッシュセットであると判定された場合、キャッシュメモリへのヒット又はミスの何れが生じたかを判断する。そして、ミスが生じたと判断された場合に、ミスの回数を示すヒット変数を更新しかつキャッシュメモリのアドレス情報を記憶し、ヒットが生じたと判断された場合に、ヒットの回数を示すヒット変数を更新する。
【０００４】
また、現在のプロセッサは複数のコアを持ち、複数のコアが共有して使用するキャッシュメモリが存在する。例えば、High Performance Computing（ＨＰＣ）アプリケーションプログラムなどのように、複数のコアを使用して並列処理を実行するマルチスレッドプログラムでは、キャッシュメモリを有効利用することがプログラムを高速に実行するために必要である。
【０００５】
また、特に、ＨＰＣアプリケーションプログラムのようなマルチスレッドプログラムは、一般に一つのループを並列化することが多い。各ループのイタレーションを並列に実行する方法は、使用するスレッド数、ループのイタレーションをグループ化する場合のサイズであるチャンクサイズ、及びスレッドをスケジュールする方法の種類（例えば、ｓｔａｔｉｃ、ｄｙｎａｍｉｃなど）の３つのパラメータで決まる。すなわち、パラメータとして、より良いスレッド数、チャンクサイズ、及びスケジュール方法の種類を探すことが性能向上に重要となる。これらのパラメータを変更することで、マルチスレッドプログラムを実行した場合に、マルチスレッドが共有するキャッシュメモリ上で発生するキャッシュミスの回数は変化する。キャッシュミスは、ＨＰＣアプリケーション分野のプログラムでは大きな性能低下の要因であるため、キャッシュミスを低減するようにパラメータの値を求めることは重要なチューニング方針である。
【先行技術文献】
【特許文献】
【０００６】
【特許文献１】特開２００９−１３９５０６号公報
【発明の概要】
【発明が解決しようとする課題】
【０００７】
しかし、大規模ＨＰＣアプリケーションプログラムの実行時間は一般に長時間であるため、キャッシュメモリの利用状況のプロファイル情報を取得するためには長時間実機を利用する必要がある。
【０００８】
また、現在利用されているキャッシュの利用状況の調査方法は、ＣＰＵに内蔵のレジスタを利用するもので、キャッシュミスの回数のカウントなどの単純なデータを取得することは可能である。しかし、ＣＰＵの内蔵レジスタを利用する手法では、上述したようなループの並列実行方法のパラメータを考慮したプロファイル情報などのように、マルチスレッドプログラムにおけるキャッシュメモリの利用状況のプロファイル情報は取得することはできない。また、ＣＰＵのシミュレータや専用のツールを使って詳細なプロファイル情報を取得する手法を使う場合、普通にプログラムを実行するより、はるかに長い実行時間を要するという問題がある。
【０００９】
さらに、大規模ＨＰＣアプリケーションプログラムの開発では、プログラムを開発する計算機と実際に動作させる計算機とが異なるという状況が有り得る。この場合、開発に利用する計算機と実際に動作させる計算機とでキャッシュメモリの構成が異なる可能性がある。その場合、開発に利用する計算機上で、ＣＰＵに内蔵のレジスタを利用してプロファイル情報を取得する方法では、実際の計算機におけるキャッシュの正確な利用状況を調査することはできない。
【００１０】
開示の技術は、一つの側面として、マルチスレッドプログラムにおいて、並列処理の実行方法毎に、キャッシュメモリへのアクセスに関するプロファイル情報を高速で取得することを目的とする。
【課題を解決するための手段】
【００１１】
一つの態様として、生成部が、複数のスレッドが並列処理を実行するプログラムの実行時における、各スレッドから主記憶装置へのアクセス要求に対応するキャッシュメモリへのアクセスを表す行列を、並列処理についての複数の異なる実行方法毎に生成する。そして、取得部が、前記実行方法の各々について、前記生成部で生成された行列の要素が示す前記キャッシュメモリへのアクセスの成否に関連する情報を生成する。
【発明の効果】
【００１２】
一つの側面として、マルチスレッドプログラムにおいて、並列処理の実行方法毎に、キャッシュメモリへのアクセスに関するプロファイル情報を高速で取得することができる。
【図面の簡単な説明】
【００１３】
【図１】本実施形態に係る情報処理装置の機能ブロック図である。
【図２】本実施形態に係る情報処理装置として機能するコンピュータの概略構成を示すブロック図である。
【図３】マルチスレッドにおける共有キャッシュメモリを説明するための図である。
【図４】本実施形態における情報処理の一例を示すフローチャートである。
【図５】プログラム情報の一例を示す図である。
【図６】イベントカウント情報生成プログラムの一例を示す図である。
【図７】プログラムデータ情報の一例を示す図である。
【図８】配列データ情報の一例を示す図である。
【図９】変数データ情報の一例を示す図である。
【図１０】イベントカウント情報の一例を示す図である。
【図１１】イベント行列情報生成プログラムの一例を示す図である。
【図１２】並列実行方法試行情報の一例を示す図である。
【図１３】並列実行方法情報の一例を示す図である。
【図１４】イベントカウント情報の他の例を示す図である。
【図１５】ｓｔａｔｉｃによるスレッドへのループの割り当てを説明するための図である。
【図１６】ｄｙｎａｍｉｃによるスレッドへのループの割り当てを説明するための図である。
【図１７】ｄｙｎａｍｉｃによるスレッドへのループの割り当てを説明するための図である。
【図１８】ｇｕｉｄｅｄによるスレッドへのループの割り当てを説明するための図である。
【図１９】ｇｕｉｄｅｄによるスレッドへのループの割り当てを説明するための図である。
【図２０】キャッシュ構成情報の一例を示す図である。
【図２１】イベント行列情報の一例を示す図である。
【図２２】キャッシュプロファイル情報生成処理の一例を示すフローチャートである。
【図２３】キャッシュプロファイル情報生成処理をプログラムとして記述した一例を示す図である。
【図２４】キャッシュプロファイル情報生成処理をプログラムとして記述した他の例を示す図である。
【図２５】第１変換処理の一例を示すフローチャートである。
【図２６】プログラム情報を構成要素に分解した一例を示す図である。
【図２７】第２変換処理の一例を示すフローチャートである。
【発明を実施するための形態】
【００１４】
以下、図面を参照して開示の技術に係る実施形態の一例を詳細に説明する。
【００１５】
図１に示すように、本実施形態に係る情報処理装置１０には、プロファイルの対象である対象プログラムに関する入力情報が入力される。入力情報には、対象プログラムを示すプログラム情報（ソースファイル）、プログラムデータ情報、配列データ情報、変数データ情報、並列実行方法試行情報、及びキャッシュ構成情報が含まれる。なお、本実施形態における対象プログラムは、複数のスレッドが並列に実行されるマルチスレッドプログラムである。特に、回転数ＮＩ回のループ本体におけるループ変数ｉのループ（以下、「ループｉ」ともいう）の各々が複数のスレッドのいずれかに割り当てられて、ループ本体が並列に実行されるプログラムを対象プログラムとする。以下、この場合におけるループ本体を「並列化ループ」ともいう。
【００１６】
また、情報処理装置１０は、対象プログラムを実行した場合のキャッシュメモリへのアクセスをシミュレーションし、キャッシュメモリへのアクセスに関するプロファイル情報を取得して出力する。プロファイル情報には、キャッシュミスの回数を示すキャッシュプロファイル情報と、キャッシュミスを最小化する並列実行方法の情報とが含まれる。なお、キャッシュミスとは、プログラムがアクセスするメモリ（主記憶装置）のメモリ領域に記憶されているデータがキャッシュメモリに存在しない場合である。また、並列実行方法とは、詳細は後述するが、並列化ループを実行するスレッド数、各スレッドに割り当てるループのチャンクサイズ、及びスレッドのスケジュール方法の種類の３つのパラメータの値で決まる実行方法である。
【００１７】
情報処理装置１０へ入出力される各情報の詳細については後述する。
【００１８】
情報処理装置１０は、図１に示すように、機能的には、第１変換部１１と、計測部１２と、第２変換部１３と、生成部１４と、取得部１５とを含む。なお、第１変換部１１及び計測部１２は、開示の技術の計測部の一例であり、第２変換部１３及び生成部１４は、開示の技術の生成部の一例であり、取得部１５は、開示の技術の取得部の一例である。
【００１９】
第１変換部１１は、入力情報に含まれる対象プログラムのプログラム情報を、イベントカウント情報生成プログラムのソースファイルに変換する。イベントカウント情報生成プログラムは、並列化ループの実行時に発生するイベント数を、ループｉ毎にカウントしたイベントカウント情報を生成するためのプログラムである。なお、本実施形態において「イベント」とは、プログラムからキャッシュメモリへのアクセスを意味する。
【００２０】
計測部１２は、入力情報に含まれるプログラムデータ情報、配列データ情報、及び変数データ情報を用いて、第１変換部１１により変換されたイベントカウント情報生成プログラムを実行することにより、イベントカウント情報（詳細は後述）を生成する。
【００２１】
第２変換部１３は、入力情報に含まれる対象プログラムのプログラム情報を、イベント行列情報生成プログラムのソースファイルに変換する。イベント行列情報生成プログラムは、対象プログラムを実行した際に各スレッドで発生するイベントを、スレッドの識別情報とイベントの発生タイミングとに対応させた行列形式で表現したイベント行列情報を生成するためのプログラムである。なお、本実施形態では、スレッドの識別情報としてスレッド番号を用い、イベントの発生タイミングとしてクロック番号を用い、スレッド番号を列、クロック番号を行とする行列を生成する場合について説明する。
【００２２】
生成部１４は、入力情報に含まれる並列実行方法試行情報から作成される並列実行方法毎に、配列データ情報、変数データ情報、及びイベントカウント情報を用いて、第２変換部１３により変換されたイベント行列情報生成プログラムを実行する。生成部１４は、イベント行列情報生成プログラムの実行により、並列実行方法毎に、イベント行列情報（詳細は後述）を生成する。
【００２３】
取得部１５は、生成部１４により生成されたイベント行列情報、及び入力情報に含まれるキャッシュ構成情報を用いて、プロファイル情報を生成し、出力する。
【００２４】
情報処理装置１０は、例えば図２に示すコンピュータ２０で実現することができる。コンピュータ２０は、Central Processing Unit（ＣＰＵ）２１と、一時記憶領域としてのメモリ２２と、不揮発性の記憶部２３とを備える。また、コンピュータ２０は、表示部及び入力部を含む入出力装置２４と、記憶媒体２９に対するデータの読み込み及び書き込みを制御するRead/Write（Ｒ／Ｗ）部２５とを備える。また、コンピュータ２０は、インターネット等のネットワークに接続される通信インターフェース（Ｉ／Ｆ）２６を備える。ＣＰＵ２１、メモリ２２、記憶部２３、入出力装置２４、Ｒ／Ｗ部２５、及び通信Ｉ／Ｆ２６は、バス２７を介して互いに接続される。なお、ＣＰＵ２１はハードウェアである。
【００２５】
ここで、情報処理装置１０によるプロファイルの対象となる計算機（対象プログラムが実行される実機）は、図３に示すようなＣＰＵ５１を備える。ＣＰＵ５１は、複数のコア５１１Ａ、５１１Ｂ、５１１Ｃ・・・と、各コア５１１Ａ、５１１Ｂ、５１１Ｃ・・・により実行される複数のスレッド４０Ａ、４０Ｂ、４０Ｃ・・・で共有して使用されるキャッシュメモリ５１２とを備える。キャッシュメモリ５１２は、所定サイズ毎に複数のブロックに分割されている。この各ブロックをキャッシュセット５１３といい、各キャッシュセット５１３には、各キャッシュセット５１３の識別情報であるキャッシュセット番号が付されている。なお、情報処理装置１０では、キャッシュをシミュレーションしてプロファイル情報を取得するため、情報処理装置１０のＣＰＵ２１は、図３に示すＣＰＵ５１と同様の構成とする必要はない。
【００２６】
記憶部２３は、Hard Disk Drive（ＨＤＤ）、Solid State Drive（ＳＳＤ）、フラッシュメモリ等によって実現できる。記憶媒体としての記憶部２３には、コンピュータ２０を情報処理装置１０として機能させるための情報処理プログラム３０が記憶される。情報処理プログラム３０は、第１変換プロセス３１と、計測プロセス３２と、第２変換プロセス３３と、生成プロセス３４と、取得プロセス３５とを有する。
【００２７】
ＣＰＵ２１は、情報処理プログラム３０を記憶部２３から読み出してメモリ２２に展開し、情報処理プログラム３０が有するプロセスを順次実行する。ＣＰＵ２１は、第１変換プロセス３１を実行することで、図１に示す第１変換部１１として動作する。また、ＣＰＵ２１は、計測プロセス３２を実行することで、図１に示す計測部１２として動作する。また、ＣＰＵ２１は、第２変換プロセス３３を実行することで、図１に示す第２変換部１３として動作する。また、ＣＰＵ２１は、生成プロセス３４を実行することで、図１に示す生成部１４として動作する。また、ＣＰＵ２１は、取得プロセス３５を実行することで、図１に示す取得部１５として動作する。これにより、情報処理プログラム３０を実行したコンピュータ２０が、情報処理装置１０として機能する。
【００２８】
なお、情報処理プログラム３０により実現される機能は、例えば半導体集積回路、より詳しくはApplication Specific Integrated Circuit（ＡＳＩＣ）等で実現することも可能である。
【００２９】
次に、本実施形態に係る情報処理装置１０の作用について説明する。対象プログラムの入力情報が情報処理装置１０に入力され、プロファイルの開始が指示されると、情報処理装置１０が、図４に示す情報処理を実行する。
【００３０】
ここで、例えば、High Performance Computing（ＨＰＣ）アプリケーションプログラムでは、プログラムのホットスポットが限られる傾向がある。したがって、プログラムの特徴を捉えるためにプロファイル情報を取得する場合でも、いくつかのループ本体のみを調査すればよい場合が多い。そこで、本実施形態では、対象プログラム全体のうち、並列化ループを含む一部分に関する入力情報を情報処理装置１０に入力する場合について説明する。図５に、情報処理装置１０に入力される対象プログラムのプログラム情報の一例を示す。また、ここでは、図５に示すプログラム情報のトップレベルのループ本体（ループ変数ｉのループ本体）を並列化ループとして実行する場合を考える。
【００３１】
ステップＳ１０で、詳細を後述する第１変換処理が実行されて、対象プログラムのプログラム情報が、例えば、図６に示すようなイベントカウント情報生成プログラムのソースファイルに変換される。
【００３２】
次に、ステップＳ３０で、計測部１２が、例えば、図７に示すプログラムデータ情報、図８に示す配列データ情報、及び図９に示す変数データ情報を用いて、第１変換部１１により変換されたイベントカウント情報生成プログラムを実行する。図７に示すプログラムデータ情報には、対象プログラムで参照する各配列の開始アドレス、配列の要素当たりのバイト数、及び次元情報が含まれる。図８に示す配列データ情報は、図５に示す対象プログラムで参照される配列ＮＪの各要素の値（データ）をインデックスと対応付けた情報である。図９に示す変数データ情報は、対象プログラムにおける並列化ループの回転数を示す変数ＮＩの値（データ）を示す情報である。
【００３３】
計測部１２は、図６に示すイベントカウント情報プログラムを実行することで、並列化ループのループｉ毎に、イベントの発生回数、すなわち、プログラムからキャッシュメモリ５１２にアクセスする回数をカウントする。そして、計測部１２は、例えば、図１０に示すように、ループ変数ｉに、ループｉでのイベントの発生回数（イベント数）を対応付けたイベントカウント情報を生成する。
【００３４】
次に、ステップＳ４０で、詳細を後述する第２変換処理が実行されて、対象プログラムのプログラム情報が、例えば、図１１に示すようなイベント行列情報生成プログラムのソースファイルに変換される。
【００３５】
次に、ステップＳ６１で、生成部１４が、キャッシュミス回数の最小値を表す作業用変数ＭをＭ＝∞に初期化し、キャッシュミス回数を最小化する並列実行方法情報を表す作業用変数ＲＥＳＵＬＴを空に初期化する。
【００３６】
次に、ステップＳ６２で、生成部１４が、入力情報に含まれる並列実行方法試行情報から作成される並列実行方法情報のうち、以下のステップＳ６３〜Ｓ９２の処理が未試行の並列実行方法情報が存在するか否かを判定する。
【００３７】
図１２に、入力情報に含まれる並列実行方法試行情報の一例を示す。図１２に示す並列実行方法試行情報では、パラメータ変数であるスレッド数Ｔ、チャンクサイズＣ、及びスケジュール方法の種類Ｋに対して試行する範囲を定義している。図１２の例では、スレッド数Ｔについては４つの値を、チャンクサイズＣについては３つの値を、スケジュール方法の種類Ｋついては３種類を定義している。並列実行方法試行情報は、これら３つのパラメータの全ての組み合わせについて作成される。したがって、図１２に示す並列実行方法試行情報から作成される並列実行方法情報の総数は３６個となる。
【００３８】
なお、スケジュール方法の種類の定義としては、参考文献「OpenMP Architecture Review Board, OpenMP Application Program Interface（version 4.0）, OpenMP Architecture Review Board，2013.」を利用することができる。
【００３９】
未試行の並列実行方法情報が存在する場合には、処理はステップＳ６３へ移行し、生成部１４が、未試行の並列実行方法情報Ｘを一つ作成する。例えば、生成部１４は、図１３に示すような並列実行方法情報Ｘ＝（Ｔ；Ｃ；Ｋ）＝（４；１；ｄｙｎａｍｉｃ）を作成する。
【００４０】
次に、ステップＳ６４で、生成部１４が、プログラムデータ情報、配列データ情報、変数データ情報、キャッシュ構成情報、及び並列実行方法情報Ｘを入力データとして、上記ステップＳ４０で生成したイベント行列情報生成プログラムを実行する。
【００４１】
ここで、図１１に示すイベント行列情報生成プログラム内のライブラリ関数ｉｎｉｔｉａｌｉｚｅ＿ＷＯＲＫ（ｓｉｚｅ）は、引数ｓｉｚｅに並列化ループの回転数の値を受け取り、イベント行列情報のデータ領域を初期化する機能を実現する。引数ｓｉｚｅには、変数データ情報が示す変数ＮＩの値が渡される。イベント行列情報のデータ構造は、本ステップで本関数を実行するときに参照する、並列実行方法情報Ｘの中のスレッド数Ｔの値によって、その列のサイズが決まる。また、イベント行列情報の行のサイズは、本ステップでイベント行列情報生成プログラムを実行する過程で、必要なだけ拡張される。
【００４２】
また、図１１に示すイベント行列情報生成プログラム内の「ｇｅｔ＿ｔｈｒｅａｄ＿ｎｕｍｂｅｒ（ｉ）」は、ループｉを実行するスレッドのスレッド番号を求める機能を実現する。ここでは、スレッド番号を求める処理は、上述の参考文献のスケジュール方法の種類の定義に準拠するものとする。スレッド番号を求める処理には、一般に、ループ変数の値（ここではｉ）、並列化ループの回転数の値（ここではＮＩ）、スレッド数Ｔ、チャンクサイズＣ、スケジュール方法の種類Ｋ、ループｉを実行する直前の状態等の情報が必要となる。なお、ループｉを実行する直前の状態は、上記ステップＳ３０で求めたイベントカウント情報と、本ステップでイベント行列情報生成プログラムを実行する過程で、更新するイベント行列情報とから判定することができる。
【００４３】
より具体的に、上記ステップＳ３０において、図１４に示すイベントカウント情報が生成されている場合における「ｇｅｔ＿ｔｈｒｅａｄ＿ｎｕｍｂｅｒ（ｉ）」の実現例について説明する。図１４に示すイベントカウント情報から、ループ変数ｉの値の範囲は０以上１０以下で、その総数Ｎは１１個であることがわかる。以下では、スレッドの数Ｔ＝４と仮定して説明する。
【００４４】
まず、スケジュール方法の種類Ｋ＝ｓｔａｔｉｃ、チャンクサイズＣ＝２の場合、すなわち、（Ｔ；Ｃ；Ｋ）＝（４；２；ｓｔａｔｉｃ）の場合の「ｇｅｔ＿ｔｈｒｅａｄ＿ｎｕｍｂｅｒ（ｉ）」の実現例を以下に示す。
【００４５】
ｓｔａｔｉｃは、ループｉ（ここでは、ｉ＝０，１，・・・，１０）をＣ個ずつ均等に各スレッドに順番に割り当てるスケジュール方法である。したがって、ループ本体のスレッドへの割り当て結果は図１５に示すようになる。なお、図１５に示す割り当て結果では、各スレッドに割り当てられたループｉを、そのスレッドのスレッド番号にループ変数ｉを対応付けて表している。以下、図１６〜図１９も同様である。この割り当て結果に基づいて、ループ変数ｉに対応するスレッド番号を特定することで、「ｇｅｔ＿ｔｈｒｅａｄ＿ｎｕｍｂｅｒ（ｉ）」を実現することができる。例えば、図１５に示す割り当て結果の場合、ｉ＝１０ならば、「ｇｅｔ＿ｔｈｒｅａｄ＿ｎｕｍｂｅｒ（ｉ）」により、スレッド番号Ｔ１が取得される。
【００４６】
次に、Ｋ＝ｄｙｎａｍｉｃ、チャンクサイズＣ＝２の場合、すなわち、（Ｔ；Ｃ；Ｋ）＝（４；２；ｄｙｎａｍｉｃ）の場合の「ｇｅｔ＿ｔｈｒｅａｄ＿ｎｕｍｂｅｒ（ｉ）」の実現例を以下に示す。ｄｙｎａｍｉｃは、各スレッドのイベント数に応じて、ループｉの各々を各スレッドに動的に割り当てるスケジュール方法である。したがって、まず、１回目の割り当てで、図１６に示すように、ループｉをＣ個ずつ均等に各スレッドに順番に割り当てる。このとき、各スレッドのイベント数は、図１４に示すイベントカウント情報に基づいて、それぞれ「イベント総数」の行に示した数となる。２回目の割り当てでは、図１７に示すように、イベント総数の少ないスレッドから順にループｉをＣ個ずつ割り当てる。例えば、図１７に示す割り当て結果が得られた場合、ｉ＝１０ならば、「ｇｅｔ＿ｔｈｒｅａｄ＿ｎｕｍｂｅｒ（ｉ）」により、スレッド番号Ｔ２が取得される。
【００４７】
最後に、Ｋ＝ｇｕｉｄｅｄ、チャンクサイズＣ＝１の場合、すなわち、（Ｔ；Ｃ；Ｋ）＝（４；１；ｇｕｉｄｅｄ）の場合の「ｇｅｔ＿ｔｈｒｅａｄ＿ｎｕｍｂｅｒ（ｉ）」の実現例を以下に示す。なお、Ｋ＝ｇｕｉｄｅｄの場合、Ｃの値はチャンクサイズの最小値を意味する。ｇｕｉｄｅｄは、チャンク数を変更しながら、各スレッドのイベント数に応じて、ループｉを各スレッドに動的に割り当てるスケジュール方法である。
【００４８】
まず、１回目の割り当てのチャンクサイズＣ１は、ループの総数ＮをＴで割った値である
Ｃ１＝Ｎ／Ｔ＝１１／４＝２  （小数点以下切捨て）
の値になる。したがって、図１８に示すように、まずループｉを２個ずつ各スレッドに割り当てる。この場合、ループ８、ループ９、及びループ１０が残る。Ｋ＝ｇｕｉｄｅｄの場合、チャンクサイズは指数関数的に減少するので、ここでは一例として２回目の割り当てのチャンクサイズＣ２はＣ２＝Ｃ１／２＝１であると仮定する。この結果として、図１９に示すように、残りの３個のループｉ（ループ８、ループ９、及びループ１０）を一つずつ、「イベント総数」が少ないスレッドから順に動的に割り当てる。そして、例えば、図１９に示す割り当て結果が得られた場合、ｉ＝１０ならば、「ｇｅｔ＿ｔｈｒｅａｄ＿ｎｕｍｂｅｒ（ｉ）」により、スレッド番号Ｔ１が取得される。
【００４９】
このように、上記ステップＳ３０で作成したイベントカウント情報を用いて、各スケジュール方法の種類に応じて、各スレッドへのループｉの割り当てをシミュレーションして、ループｉが割り当てられるスレッドのスレッド番号を求めることができる。
【００５０】
上述のように、図１４に示すイベントカウント情報が得られている場合において、同じスレッド数Ｔ＝４であっても、スケジュール方法の種類によって、各スレッドが処理するイベント総数が変わることが、図１５、図１７、及び図１９から確認できる。また、イベント総数だけでなく、各スレッドで実行されるループｉも、スケジュール方法の種類によって異なる。これは、並列実行方法が異なる場合には、各スレッドからキャッシュメモリ５１２へのアクセスの状況も異なることを表している。
【００５１】
なお、プログラムの実行時間は、並列実行するスレッドの中で最も遅いスレッド（すなわち最もイベント総数が多いスレッド）によって決まる。イベント総数の最大値は、図１５では３６０、図１７では２４０、図１９では２００である。すなわち、Ｋ＝ｇｕｉｄｅｄ、Ｋ＝ｄｙｎａｍｉｃ、Ｋ＝ｓｔａｔｉｃの順に効率良くイベントを各スレッドに分配できていることが確認できる。
【００５２】
また、図１１に示すイベント行列情報生成プログラム内のライブラリ関数「ＷＯＲＫ（ａｄｄｒｅｓｓ，ｔｈｒｅａｄ）」は、プログラムがアクセス要求した配列要素のメモリアドレス、及びアクセス要求したスレッドのスレッド番号を取得する機能を実現する。さらに、取得したアドレスａｄｄｒｅｓｓ及びスレッド番号ｔｈｒｅａｄを、イベント行列情報の該当する要素の値として保存する機能を実現する。
【００５３】
具体的には、ライブラリ関数「ＷＯＲＫ（ａｄｄｒｅｓｓ，ｔｈｒｅａｄ）」により、プログラムがアクセス要求した配列要素が記憶されているメモリアドレスが特定される。例えば、ＮＪ［ｉ］のアドレスは、図７に示すプログラムデータ情報を参照して、配列ＮＪの開始アドレス４０００、配列要当たりのバイト数４、及び変数ｉから、４０００＋ｉ×４と特定することができる。同様に、Ｚ［ｉ］［ｊ］のアドレスは、配列Ｚの開始アドレス１６００、配列要当たりのバイト数８、変数ｉ、ｊ、及び次元情報６×６から、１６００＋（６×ｉ＋ｊ）×８と特定することができる。そして、特定したアドレスを引数ａｄｄｒｅｓｓに渡す。
【００５４】
また、「ｇｅｔ＿ｔｈｒｅａｄ＿ｎｕｍｂｅｒ（ｉ）」により取得されたスレッド番号を引数ｔｈｒｅａｄに渡す。そして、イベント行列情報のスレッド番号ｔｈｒｅａｄの列をクロック番号０の行から検査し、使用していないクロック番号ｃを検出する。さらに、アドレスａｄｄｒｅｓｓをイベント行列情報のｃ行、ｔｈｒｅａｄ列の要素の値として保存する。
【００５５】
上記のように、生成部１４がイベント行列情報生成プログラムを実行することにより、図２１に示すようなイベント行列情報が生成される。図２１に示すイベント行列情報では、列は４つのスレッドＴ０、Ｔ１、Ｔ２、Ｔ３を示し、行はイベントが発生したクロックを示している。図２１の行列の要素には、各スレッドが各クロックでアクセスするデータのアドレス値が入っている。アドレス値が「−１」の欄は、そのスレッドのそのクロックではキャッシュメモリ５１２へのアクセスが発生しないことを示す。
【００５６】
次に、ステップＳ７０で、取得部１５が、上記ステップＳ６４で生成されたイベント行列情報、及び入力情報に含まれるキャッシュ構成情報を用いて、キャッシュプロファイル情報生成処理を実行する。これにより、キャッシュアクセスがシミュレーションされ、キャッシュプロファイル情報が生成される。ここで、図２２を参照して、キャッシュプロファイル情報生成処理について詳述する。
【００５７】
ステップＳ７１で、取得部１５が、イベント行列情報の行番号（クロック番号）の最大値を取得し、変数ｒｍａｘに格納する。また、取得部１５が、イベント行列情報の列番号（スレッド番号）の最大値を取得し、変数ｃｍａｘに格納する。例えば、図２１に示すイベント行列情報の場合、ｒｍａｘ＝１９、ｃｍａｘ＝３である。また、取得部１５は、キャッシュミス回数をカウントするための作業用変数ｍを０にリセットする。
【００５８】
次に、ステップＳ７１で、取得部１５が、処理対象の行番号を示す作業用変数ｒに０を設定する。次に、ステップＳ７１で、取得部１５が、ｒがｒｍａｘより大きいか否かを判定する。ｒがｒｍａｘ以下の場合には、イベント行列情報において未処理の行が存在することを表している。この場合、処理はステップＳ７４へ移行する。
【００５９】
ステップＳ７４では、取得部１５が、処理対象の列番号を示す作業用変数ｃに０を設定する。次に、ステップＳ７５で、取得部１５が、ｃがｃｍａｘより大きいか否かを判定する。ｃがｃｍａｘ以下の場合には、イベント行列情報のｒ行において未処理の列が存在することを表している。この場合、処理はステップＳ７６へ移行する。
【００６０】
ステップＳ７６では、取得部１５が、イベント行列情報のｒ行ｃ列の要素ａを取り出す。次に、ステップＳ７７で、取得部１５が、上記ステップＳ７６で取り出した要素ａが−１か否かを判定する。ａ≠−１の場合には、処理はステップＳ７８へ移行する。ステップＳ７８では、取得部１５が、アドレスａに対応するキャッシュメモリ５１２のキャッシュセット５１３へのアクセスをシミュレーションし、キャッシュミスか否かを判定する。取得部１５は、キャッシュミスの場合には、ｍに１加算して、処理はステップＳ７９へ移行する。
【００６１】
一方、ａ＝−１の場合には、上記ステップＳ７８の処理はスキップして、ステップＳ７９へ移行する。ステップＳ７９では、取得部１５が、ｃを１インクリメントして、処理はステップＳ７５に戻る。
【００６２】
ステップＳ７５で、ｃがｃｍａｘより大きいと判定された場合には、イベント行列情報のｒ行において全ての列について処理が終了したことを表しているため、処理はステップＳ８０へ移行する。ステップＳ８０では、取得部１５が、ｒを１インクリメントして、処理はステップＳ７３に戻る。
【００６３】
ステップＳ７３で、ｒがｒｍａｘより大きいと判定された場合には、イベント行列情報の全ての要素について処理が終了したことを表しているため、処理はステップＳ８１へ移行する。ステップＳ８１では、取得部１５が、作業用変数ｍに格納されているキャッシュミスの回数を、キャッシュプロファイル情報として出力して、処理は図４に示す情報処理に戻る。
【００６４】
上記のキャッシュプロファイル情報生成処理により、イベント行列情報を利用して、並列に実行されている複数のスレッドが同時に共有キャッシュにアクセスする状態をシミュレーションすることができる。
【００６５】
図２３に、図２２に示すキャッシュプロファイル情報生成処理をプログラムとして記述した例を示す。図２３では、イベント行列情報を２次元配列データＭＡＴＲＩＸとして利用している。
【００６６】
また、上記ステップＳ７８の処理は、図２３に示すプログラムにおいて、ライブラリ関数ＡＣＣＥＳＳ（ａｄｄｒｅｓｓ）で実現される。具体的には、引数ａｄｄｒｅｓｓにａを与え、アドレスａに対応するキャッシュメモリ５１２上のキャッシュセット番号を特定する。例えば、図２０に示すような、キャッシュの連想数Ａ、ブロックサイズＢ、及びセット数Ｓの情報を含むキャッシュ構成情報を用い、アドレスａのデータが記憶されたキャッシュセット５１３のキャッシュセット番号ｓは以下のように特定される。
ｓ＝（ａ／Ｂ（小数点以下切捨て））ｍｏｄ Ｓ
【００６７】
そして、特定されたキャッシュセット番号ｓが示すキャッシュセット５１３に、プログラムがアクセス要求したデータが記憶されているか否かを判定する。該当のデータがキャッシュメモリ５１２に記憶されていない場合には、キャッシュミスであると判定し、ｍに１加算する。なお、ライブラリ関数ＡＣＣＥＳＳ（ａｄｄｒｅｓｓ）は、特開２０１４−２３２３６９号公報で開示されている技術を適用することができるため、ここでは、詳細な説明を省略する。
【００６８】
なお、図２３に示すプログラムは、キャッシュセット５１３毎に、キャッシュプロファイル情報生成処理を逐次実行する場合のプログラムの一例である。ここで、キャッシュアクセスのプロファイル情報はキャッシュセット５１３毎に独立してシミュレーションすることが可能である。この性質を利用して、全てのキャッシュセット５１３を同時にシミュレーションし、各キャッシュセット５１３に関するキャッシュプロファイル情報生成処理を並列に実行することができる。その処理をプログラムとして記述した例を図２４に示す。図２４に示すプログラム内の「ａｓ＝（ａｄｄｒｅｓｓ／Ｂ）％Ｓ」は、上述のキャッシュセット番号ｓを特定する式と同様である。そして、ａｓが該当のキャッシュセットの番号（ｓ）と一致する場合に、上述のライブラリ関数ＡＣＣＥＳＳ（ａｄｄｒｅｓｓ）が実行される。
【００６９】
図４の情報処理に戻って、次のステップＳ９１で、取得部１５が、上記ステップＳ７０で出力されたキャッシュプロファイル情報（キャッシュミスの回数）ｍが、作業用変数Ｍより小さいか否かを判定する。ｍ＜Ｍの場合には、処理はステップＳ９２へ移行し、取得部１５が、Ｍにｍの値を保存し、かつ作業用変数ＲＥＳＵＬＴに並列実行方法情報Ｘを保存し、処理はステップＳ６２に戻る。一方、ｍ≧Ｍの場合には、ステップＳ９２の処理はスキップして、ステップＳ６２に戻る。
【００７０】
ステップＳ６２で、全ての並列実行方法情報について、キャッシュプロファイル情報を生成する処理が終了したと判定された場合には、処理はステップＳ９３へ移行する。ステップＳ９３では、取得部１５が、Ｍに保存されているキャッシュプロファイル情報、及びＲＥＳＵＬＴに保存されている並列実行方法情報Ｘを、対象プログラムのプロファイル情報として出力し、情報処理は終了する。
【００７１】
ここで、図２５を参照して、図４に示す情報処理のステップＳ１０で実行される第１変換処理について説明する。
【００７２】
まず、ステップＳ１１で、第１変換部１１が、入力された対象プログラムのプログラム情報を構成要素に分解する。
【００７３】
次に、ステップＳ１２で、第１変換部１１が、イベントカウント情報を示す配列を初期化するコードを出力する。なお、コードを出力するとは、生成するプログラムのソースファイルに該当のコードを記述することを意味する。
【００７４】
次に、ステップＳ１３で、第１変換部１１が、プログラム情報を分解した構成要素のうち、以下のステップＳ１４〜Ｓ２３の処理が未処理の構成要素が存在するか否かを判定する。未処理の構成要素が存在する場合には、第１変換部１１が、未処理の構成要素から、対象プログラムにおける出現順に１つの構成要素Ｓを選択し、処理はステップＳ１４へ移行する。
【００７５】
ステップＳ１４では、第１変換部１１が、構成要素Ｓがループ変数ｉで処理を繰り返す並列化ループか否かを判定する。肯定判定の場合には、処理はステップＳ１５へ移行し、否定判定の場合には、処理はステップＳ１６へ移行する。
【００７６】
ステップＳ１５では、第１変換部１１が、構成要素Ｓを出力し、構成要素Ｓの直後にイベントをカウントする対象のループを特定するループ変数ｉを初期値に設定するコードを出力する。そして、処理はステップＳ１３に戻る。
【００７７】
ステップＳ１６では、第１変換部１１が、構成要素Ｓが並列化ループ以外のループか否かを判定する。肯定判定の場合には、処理はステップＳ１７へ移行し、第１変換部１１が、構成要素Ｓを出力し、処理はステップＳ１３に戻る。一方、否定判定の場合には、処理はステップＳ１８へ移行する。
【００７８】
ステップＳ１８では、第１変換部１１が、構成要素Ｓが並列化ループの回転数に影響を与えない代入文か否かを判定する。肯定判定の場合には、処理はステップＳ１９へ移行し、否定判定の場合には、処理はステップＳ２０へ移行する。
【００７９】
ステップＳ１９では、第１変換部１１が、構成要素Ｓを削除する。そして、第１変換部１１が、構成要素Ｓの代入文に出現する、配列の要素を参照する項の数ｃを計算し、構成要素Ｓの代わりに、イベントカウント情報を示す配列のループ変数ｉに対応する要素にｃを加算するコードを出力する。そして、処理はステップＳ１３に戻る。
【００８０】
ステップＳ２０では、第１変換部１１が、構成要素Ｓが並列化ループの回転数に影響を与える代入文か否かを判定する。肯定判定の場合には、処理はステップＳ２１へ移行し、否定判定の場合には、処理はステップＳ２２へ移行する。
【００８１】
ステップＳ２１では、第１変換部１１が、構成要素Ｓを出力する。そして、第１変換部１１が、構成要素Ｓの代入文に出現する、配列の要素を参照する項の数ｃを計算し、構成要素Ｓの直後に、イベントカウント情報を示す配列のループ変数ｉに対応する要素にｃを加算するコードを出力する。そして、処理はステップＳ１３に戻る。
【００８２】
ステップＳ２２では、第１変換部１１が、構成要素Ｓがループを閉じる括弧か否かを判定する。肯定判定の場合には、処理はステップＳ２３へ移行し、第１変換部１１が、構成要素Ｓを出力し、処理はステップＳ１３に戻る。否定判定の場合には、そのままステップＳ１３に戻る。
【００８３】
ステップＳ１３で、第１変換部１１が、対象プログラムのプログラム情報を分解した構成要素の全てについて、ステップＳ１３〜Ｓ２３の処理が終了したと判定した場合には、処理はステップＳ２４へ移行する。ステップＳ２４では、第１変換部１１が、結果のイベントカウント情報を、プログラムの実行結果として出力するためのコードを出力して、第１変換処理は終了する。
【００８４】
第１変換処理の一例として、図５に示す対象プログラムのプログラム情報をイベントカウント情報生成プログラムに変換する場合について説明する。
【００８５】
まず、第１変換部１１は、プログラム情報を、図２６に示すように、各構成要素に分解する（ステップＳ１１）。図２６の例では、プログラム情報において各構成要素が出現する順に、各構成要素に番号Ｅｊ（ｊ＝１、２、・・・、６）を付与している。以下では、番号Ｅｊの構成要素を「構成要素Ｅｊ」と表記する。
【００８６】
次に、第１変換部１１は、イベントカウント情報を示す配列を初期化するコードとして、例えば、以下のコードを出力する（ステップＳ１２）。
【００８７】
ｉｎｉｔｉａｌｉｚｅ（ＥＶＥＮＴＣＯＵＮＴ，ＮＩ）；
【００８８】
イベントカウント情報を示す配列ＥＶＥＮＴＣＯＵＮＴの要素数は、並列化ループの回転数に等しいため、変数ＮＩを参照している。
【００８９】
次に、第１変換部１１は、構成要素Ｅ１を処理対象として選択する。構成要素Ｅ１はループ変数ｉで繰り返す並列化ループである。したがって、第１変換部１１は、構成要素Ｅ１を出力した後に、例えば以下に示すように、イベントカウント情報を示す配列ＥＶＥＮＴＣＯＵＮＴにおける変数ｉに初期値０を設定するコードを出力する（ステップＳ１５）。
【００９０】
ＥＶＥＮＴＣＯＵＮＴ［ｉ］＝０；
【００９１】
次に、第１変換部１１は、構成要素Ｅ２を処理対象として選択する。構成要素Ｅ２はループの回転数に影響を与える代入文である。したがって、第１変換部１１は、構成要素Ｅ２を出力した後に、例えば以下に示すように、並列化ループのループ変数ｉのイベントのカウントを１増やすコードを出力する（ステップＳ２１）。
【００９２】
ＥＶＥＮＴＣＯＵＮＴ［ｉ］＋＋；
【００９３】
ここで、増やす値が１であるのは、構成要素Ｅ２の代入文では、配列の要素を参照する項が右辺のＮＪ［ｉ］の一つだけであるためである。
【００９４】
次に、第１変換部１１は、構成要素Ｅ３を処理対象として選択する。構成要素Ｅ３は並列化ループ以外のループである。したがって、第１変換部１１は、構成要素Ｅ３だけを出力する（ステップＳ１７）。
【００９５】
次に、第１変換部１１は、構成要素Ｅ４を処理対象として選択する。構成要素Ｅ４はループの回転数に影響を与えない代入文である。したがって、第１変換部１１は、構成要素Ｅ４の代わりに、以下に示すように、構成要素Ｅ４の代入文が参照する配列の要素毎に、並列化ループのループ変数ｉのイベントのカウントを３増やすコードを出力する（ステップＳ１９）。
【００９６】
ＥＶＥＮＴＣＯＵＮＴ［ｉ］＋＝３；
【００９７】
ここで、増やす値が３であるのは、構成要素Ｅ４の代入文が参照する配列の要素は、右辺のＸ［ｉ］［ｊ］、Ｙ［ｉ］［ｊ］、及び左辺のＺ［ｉ］［ｊ］の３つであるためである。
【００９８】
次に、第１変換部１１は、構成要素Ｅ５を処理対象として選択する。構成要素Ｅ５はループを閉じる括弧であるため、第１変換部１１は、単に構成要素Ｅ５を出力する（ステップＳ２３）。構成要素Ｅ６もループを閉じる括弧であるため、構成要素Ｅ５と同様に処理される。
【００９９】
以上のように、全ての構成要素の処理が終了すると、第１変換部１１は、以下に示すように、結果のイベントカウント情報を、プログラムの実行結果として出力するためのコードを出力する（ステップＳ２４）。
【０１００】
ｐｒｉｎｔ＿ｏｕｔ（ＥＶＥＮＴＣＯＵＮＴ）；
【０１０１】
これにより、図５に示すプログラム情報が、図６に示すようなイベントカウント情報生成プログラムに変換される。
【０１０２】
次に、図２７を参照して、図４に示す情報処理のステップＳ４０で実行される第２変換処理について説明する。なお、第２変換処理において、上述の第１変換処理（図２５）と同様の処理については、同一のステップ番号を付して詳細な説明を省略する。
【０１０３】
まず、ステップＳ１１で、第２変換部１３が、入力された対象プログラムのプログラム情報を構成要素に分解する。なお、上述の第１変換処理（図２５）のステップＳ１１におけるプログラム情報の分解結果（例えば、図２６）を取得してもよい。
【０１０４】
次に、ステップＳ４２で、第２変換部１３が、イベント行列情報を生成する処理のための初期化コードを出力する。
【０１０５】
次に、ステップＳ４３で、第２変換部１３が、未処理の構成要素が存在するか否かを判定する。未処理の構成要素が存在する場合には、第２変換部１３が、未処理の構成要素から、対象プログラムにおける出現順に１つの構成要素Ｓを選択し、処理はステップＳ１４へ移行する。
【０１０６】
ステップＳ１４では、第２変換部１３が、構成要素Ｓがループ変数ｉで処理を繰り返す並列化ループか否かを判定する。肯定判定の場合には、処理はステップＳ４５へ移行し、否定判定の場合には、処理はステップＳ１６へ移行する。
【０１０７】
ステップＳ４５では、第２変換部１３が、構成要素Ｓを出力し、構成要素Ｓの直後にループｉを実行するスレッドのスレッド番号を取得するコードを出力する。そして、処理はステップＳ１３に戻る。
【０１０８】
ステップＳ１６では、第２変換部１３が、構成要素Ｓが並列化ループ以外のループか否かを判定する。肯定判定の場合には、処理はステップＳ１７へ移行し、第２変換部１３が、構成要素Ｓを出力し、処理はステップＳ１３に戻る。一方、否定判定の場合には、処理はステップＳ１８へ移行する。
【０１０９】
ステップＳ１８では、第２変換部１３が、構成要素Ｓが並列化ループの回転数に影響を与えない代入文か否かを判定する。肯定判定の場合には、処理はステップＳ４９へ移行し、否定判定の場合には、処理はステップＳ２０へ移行する。
【０１１０】
ステップＳ４９では、第２変換部１３が、構成要素Ｓを削除する。そして、第２変換部１３が、構成要素Ｓの代入文に出現する、配列の要素を参照する各項ｔについて、ライブラリ関数ＷＯＲＫを実行するコードを出力する。そして、処理はステップＳ１３に戻る。
【０１１１】
ステップＳ２０では、第２変換部１３が、構成要素Ｓが並列化ループの回転数に影響を与える代入文か否かを判定する。肯定判定の場合には、処理はステップＳ５１へ移行し、否定判定の場合には、処理はステップＳ２２へ移行する。
【０１１２】
ステップＳ５１では、第２変換部１３が、構成要素Ｓを出力する。そして、第２変換部１３が、構成要素Ｓの代入文に出現する、配列の要素を参照する各項ｔについて、ライブラリ関数ＷＯＲＫを実行するコードを出力する。そして、処理はステップＳ１３に戻る。
【０１１３】
ステップＳ２２では、第２変換部１３が、構成要素Ｓがループを閉じる括弧か否かを判定する。肯定判定の場合には、処理はステップＳ２３へ移行し、第２変換部１３が、構成要素Ｓを出力し、処理はステップＳ１３に戻る。否定判定の場合には、そのままステップＳ１３に戻る。
【０１１４】
ステップＳ１３で、第２変換部１３が、対象プログラムのプログラム情報を分解した構成要素の全てについて、ステップＳ１３〜Ｓ２３の処理が終了したと判定した場合には、処理はステップＳ５４へ移行する。ステップＳ５４では、第２変換部１３が、結果のイベント行列情報を、プログラムの実行結果として出力するためのコードを出力して、第２変換処理は終了する。
【０１１５】
第２変換処理の一例として、図５に示す対象プログラムのプログラム情報をイベント行列情報生成プログラムに変換する場合について説明する。
【０１１６】
まず、第２変換部１３は、第１変換処理と同様に、プログラム情報を、図２６に示すように、各構成要素に分解する（ステップＳ１１）。
【０１１７】
次に、第２変換部１３は、例えば、以下のように、イベント行列情報を生成する処理のための初期化コードを出力する（ステップＳ４２）。
【０１１８】
ｉｎｉｔｉａｌｉｚｅ＿ＷＯＲＫ（ＮＩ）；
【０１１９】
イベント行列情報を生成するためには並列化ループの回転数が必要であるため、上記の例では、変数ＮＩを初期化処理への引数として渡している。
【０１２０】
次に、第２変換部１３は、構成要素Ｅ１を処理対象として選択する。構成要素Ｅ１はループ変数ｉで繰り返す並列化ループである。したがって、第２変換部１３は、構成要素Ｅ１を出力した後に、例えば以下に示すように、ループ変数ｉでループ本体を実行するスレッドのスレッド番号を取得するコードを出力する（ステップＳ４５）。
【０１２１】
ｔｈｒｅａｄ＝ｇｅｔ＿ｔｈｒｅａｄ＿ｎｕｍｂｅｒ（ｉ）；
【０１２２】
次に、第２変換部１３は、構成要素Ｅ２を処理対象として選択する。構成要素Ｅ２はループの回転数に影響を与える代入文である。したがって、第２変換部１３は、構成要素Ｅ２を出力した後に、例えば以下に示すように、配列要素ＮＪ［ｉ］のアドレス情報をスレッド番号ｔｈｒｅａｄのスレッドで実行する処理として、イベント行列情報に保存するためのコードを出力する（ステップＳ５１）。
【０１２３】
ＷＯＲＫ（ａｄｄｒｅｓｓ（ＮＪ［ｉ］），ｔｈｒｅａｄ）；
【０１２４】
次に、第２変換部１３は、構成要素Ｅ３を処理対象として選択する。構成要素Ｅ３は並列化ループ以外のループである。したがって、第２変換部１３は、構成要素Ｅ３だけを出力する（ステップＳ１７）。
【０１２５】
次に、第２変換部１３は、構成要素Ｅ４を処理対象として選択する。構成要素Ｅ４はループの回転数に影響を与えない代入文である。したがって、第２変換部１３は、構成要素Ｅ４の代わりに、例えば以下に示すように、各配列要素のアドレス情報をスレッド番号ｔｈｒｅａｄのスレッドで実行する処理として、イベント行列情報に保存するためのコードを出力する（ステップＳ４９）。
【０１２６】
ＷＯＲＫ（ａｄｄｒｅｓｓ（Ｘ［ｉ］［ｊ］），ｔｈｒｅａｄ）；
ＷＯＲＫ（ａｄｄｒｅｓｓ（Ｙ［ｉ］［ｊ］），ｔｈｒｅａｄ）；
ＷＯＲＫ（ａｄｄｒｅｓｓ（Ｚ［ｉ］［ｊ］），ｔｈｒｅａｄ）；
【０１２７】
次に、第２変換部１３は、ループを閉じる括弧である構成要素Ｅ５及びＥ６の各々について、構成要素Ｅ５及びＥ６を出力する（ステップＳ２３）。
【０１２８】
以上のように、全ての構成要素の処理が終了すると、第２変換部１３は、以下に示すように、結果のイベント行列情報を、プログラムの実行結果として出力するためのコードを出力する（ステップＳ５４）。
【０１２９】
ｐｒｉｎｔ＿ｏｕｔ＿ＥＶＥＮＴ＿ＭＡＴＲＩＸ（）；
【０１３０】
これにより、図５に示すプログラム情報が、図１１に示すようなイベント行列情報生成プログラムに変換される。
【０１３１】
以上説明したように、本実施形態における情報処理装置によれば、マルチスレッドプログラムで並列化ループを実行する際の各スレッドで発生するイベント（キャッシュメモリへのアクセス）を、並列実行方法毎にイベント行列情報で表す。イベント行列情報は、スレッドとイベント発生タイミングとを対応させた行列であり、行列の要素は、その要素の列に対応するスレッドが、その要素の行に対応するタイミングで要求したアクセス先のメモリアドレスである。また、並列実行方法の各々について、イベント行列情報に沿って、メモリアドレスに対応するキャッシュメモリのキャッシュセットへのアクセスをシミュレーションして、キャッシュミス回数をカウントする。そして、キャッシュミス回数、及びキャッシュミス回数が最小となる並列実行方法をプロファイル情報として出力する。これにより、マルチスレッドプログラムにおいて、並列処理の実行方法毎に、キャッシュメモリへのアクセスに関するプロファイル情報を取得することができる。
【０１３２】
また、対象プログラムが行う計算を省略して、メモリへのアクセスだけを考慮したシミュレーションを行うことにより、プロファイル情報を高速に取得することができる。
【０１３３】
また、並列化ループのループ変数毎のイベント回数をカウントしておき、この情報を利用して、各並列実行方法において、各ループがいずれのスレッドで実行されるかを高速に決定することができる。これにより、イベント行列情報を効率よく生成することができる。このことも、プロファイル情報取得の高速化に寄与する。
【０１３４】
例えば、ＨＰＣアプリケーションプログラムは一般に、複数の巨大な配列にアクセスするため、プログラムの総実行時間における、メモリアクセスに要する時間が占める割合が多く、かつ個々の命令の実行時間が長い浮動小数点演算を大量に含む。本実施形態では、浮動小数点演算もメモリアクセスもほとんど必要としないため、処理を高速化することができる。
【０１３５】
また、キャッシュアクセスをシミュレーションするため、対象プログラムが稼動する実機を使用することなく、対象プログラムのキャッシュアクセスのプロファイル情報を取得することができる。
【０１３６】
また、対象プログラムの開発環境と実際の稼働環境との相違により、開発時と実際の稼動時とでキャッシュ構成が異なる場合がある。ＣＰＵの内蔵レジスタを使用してプロファイル情報を取得する場合は、そのＣＰＵのキャッシュ構成に基づくプロファイル情報しか取得することができない。本実施形態では、実際の稼動時のキャッシュ構成を示すキャッシュ構成情報を与えてシミュレーションすることで、適切なプロファイル情報を取得することができる。
【０１３７】
また、キャッシュメモリへのアクセスのシミュレーションを、キャッシュセット毎に並列に行うことができる。このことも、プロファイル情報取得の高速化に寄与する。例えば、キャッシュセット数はＣＰＵによって異なるが、一般に１００個以上から数千個である。したがって、キャッシュセット毎に逐次プロファイル情報を取得する場合と比較して、１００倍から数千倍以上の高速化を図ることができる。
【０１３８】
なお、上記実施形態では、キャッシュミスが最小となる並列実行方法情報と、そのときのキャッシュミス回数とをプロファイル情報として出力する場合について説明したが、これに限定されない。全ての並列実行方法の各々に、その並列実行方法におけるキャッシュミス回数を対応付けてリスト化するなどして出力してもよい。また、キャッシュミス回数が少ない順に所定個の並列実行方法情報を出力するようにしてもよい。
【０１３９】
また、上記では、情報処理プログラム３０が記憶部２３に予め記憶（インストール）されている態様を説明したが、これに限定されない。プログラムは、ＣＤ−ＲＯＭ、ＤＶＤ−ＲＯＭ、ＵＳＢメモリ等の記憶媒体に記憶された形態で提供することも可能である。
【０１４０】
以上の実施形態に関し、更に以下の付記を開示する。
【０１４１】
（付記１）
複数のスレッドが並列処理を実行するプログラムの実行時における、各スレッドから主記憶装置へのアクセス要求に対応するキャッシュメモリへのアクセスを表す行列を、前記並列処理についての複数の異なる実行方法毎に生成する生成部と、
前記実行方法の各々について、前記生成部で生成された行列の要素が示す前記キャッシュメモリへのアクセスの成否に関連する情報を取得する取得部と、
を含む情報処理装置。
【０１４２】
（付記２）
前記取得部は、前記キャッシュメモリへのアクセスの成否に関する情報として、キャッシュミスの回数を取得し、前記キャッシュミスの回数と前記実行方法とを対応付けて出力する付記１に記載の情報処理装置。
【０１４３】
（付記３）
前記取得部は、前記キャッシュミスの回数が最も少ない場合に対応する前記実行方法を出力する付記２に記載の情報処理装置。
【０１４４】
（付記４）
前記生成部は、前記アクセスを要求したスレッドと、該アクセスが要求されたタイミングとを対応させた行列であって、各スレッドからアクセスされる前記キャッシュメモリにアクセスするデータのアドレスを要素とする行列を生成する付記１〜付記３のいずれか１項記載の情報処理装置。
【０１４５】
（付記５）
前記並列処理は、ループ変数毎の処理を複数のスレッドの各々に割り当ててループを実行する処理である付記１〜付記４のいずれか１項に記載の情報処理装置。
【０１４６】
（付記６）
前記実行方法は、並列処理を実行するスレッド数、各スレッドに割り当てるループのチャンクサイズ、及びスレッドのスケジュール方法の種類に基づいて決定される付記５に記載の情報処理装置。
【０１４７】
（付記７）
前記ループの実行時における前記キャッシュメモリへのアクセス回数をループ変数毎に計測する計測部を含み、
前記生成部は、前記計測部により計測されたループ変数毎のアクセス回数を利用して、前記スケジュール方法の種類に応じて、前記ループ変数毎の処理がいずれのスレッドに割り当てられるかを特定する
付記６に記載の情報処理装置。
【０１４８】
（付記８）
主記憶装置へのアクセスの情報、及びキャッシュメモリの構成情報に基づいて、
前記取得部は、前記主記憶装置へのアクセス要求に対応するキャッシュメモリのキャッシュセット番号を特定し、該キャッシュセット番号が示すキャッシュセットに、前記主記憶装置へのアクセス要求に対応するデータが存在するか否かを模擬して、キャッシュメモリへのアクセスの成否に関連する情報を取得する
付記１〜付記７のいずれか１項に記載の情報処理装置。
【０１４９】
（付記９）
前記取得部は、前記キャッシュメモリが複数のキャッシュセットに分割されている場合、前記キャッシュセット毎に前記キャッシュメモリへのアクセスの成否に関連する情報を取得する付記１〜付記８のいずれか１項に記載の情報処理装置。
【０１５０】
（付記１０）
前記取得部は、前記キャッシュセット毎の前記キャッシュメモリへのアクセスの成否に関連する情報を取得する処理を、前記キャッシュセット毎に並列に実行する付記９に記載の情報処理装置。
【０１５１】
（付記１１）
複数のスレッドが並列処理を実行するプログラムの実行時における、各スレッドから主記憶装置へのアクセス要求に対応するキャッシュメモリへのアクセスを表す行列を、前記並列処理についての複数の異なる実行方法毎に生成し、
前記実行方法の各々について、生成した行列の要素が示す前記キャッシュメモリへのアクセスの成否に関連する情報を取得する
ことを含む処理をコンピュータが実行する情報処理方法。
【０１５２】
（付記１２）
前記キャッシュメモリへのアクセスの成否に関する情報として、キャッシュミスの回数を取得し、前記キャッシュミスの回数と前記実行方法とを対応付けて出力する付記１１に記載の情報処理方法。
【０１５３】
（付記１３）
前記キャッシュミスの回数が最も少ない場合に対応する前記実行方法を出力する付記１２に記載の情報処理方法。
【０１５４】
（付記１４）
前記アクセスを要求したスレッドと、該アクセスが要求されたタイミングとを対応させた行列であって、各スレッドからアクセスされる前記キャッシュメモリにアクセスするデータのアドレスを要素とする行列を生成する付記１１〜付記１３のいずれか１項記載の情報処理方法。
【０１５５】
（付記１５）
前記並列処理は、ループ変数毎の処理を複数のスレッドの各々に割り当ててループを実行する処理である付記１１〜付記１４のいずれか１項に記載の情報処理方法。
【０１５６】
（付記１６）
前記実行方法は、並列処理を実行するスレッド数、各スレッドに割り当てるループのチャンクサイズ、及びスレッドのスケジュール方法の種類に基づいて決定される付記１５に記載の情報処理方法。
【０１５７】
（付記１７）
前記ループの実行時における前記キャッシュメモリへのアクセス回数をループ変数毎に計測することをさらに含む処理を前記コンピュータが実行し、
計測したループ変数毎のアクセス回数を利用して、前記スケジュール方法の種類に応じて、前記ループ変数毎の処理がいずれのスレッドに割り当てられるかを特定する
付記１６に記載の情報処理方法。
【０１５８】
（付記１８）
主記憶装置へのアクセスの情報、及びキャッシュメモリの構成情報に基づいて、
前記主記憶装置へのアクセス要求に対応するキャッシュメモリのキャッシュセット番号を特定し、
該キャッシュセット番号が示す前記キャッシュセットに、前記主記憶装置へのアクセス要求に対応するデータが存在するか否かを模擬して、キャッシュメモリへのアクセスの成否に関連する情報を取得する
付記１１〜付記１７のいずれか１項に記載の情報処理方法。
【０１５９】
（付記１９）
前記キャッシュメモリが複数のキャッシュセットに分割されている場合、前記キャッシュセット毎に前記キャッシュメモリへのアクセスに関連する情報を取得する付記１１〜付記１８のいずれか１項に記載の情報処理方法。
【０１６０】
（付記２０）
複数のスレッドが並列処理を実行するプログラムの実行時における、各スレッドから主記憶装置へのアクセス要求に対応するキャッシュメモリへのアクセスを表す行列を、前記並列処理についての複数の異なる実行方法毎に生成し、
前記実行方法の各々について、生成した行列の要素が示す前記キャッシュメモリへのアクセスの成否に関連する情報を取得する
ことを含む処理をコンピュータに実行させる情報処理プログラム。
【符号の説明】
【０１６１】
１０   情報処理装置
１１   第１変換部
１２   計測部
１３   第２変換部
１４   生成部
１５   取得部
２０   コンピュータ
２１   ＣＰＵ
２２   メモリ
２３   記憶部
２９   記憶媒体
３０   情報処理プログラム
４０   スレッド
５１   ＣＰＵ
５１１ コア
５１２ キャッシュメモリ
５１３ キャッシュセット
【図１】
2018124892.tif 000003
【図２】
2018124892.tif 000004
【図３】
2018124892.tif 000005
【図４】
2018124892.tif 000006
【図５】
2018124892.tif 000007
【図６】
2018124892.tif 000008
【図７】
2018124892.tif 000009
【図８】
2018124892.tif 000010
【図９】
2018124892.tif 000011
【図１０】
2018124892.tif 000012
【図１１】
2018124892.tif 000013
【図１２】
2018124892.tif 000014
【図１３】
2018124892.tif 000015
【図１４】
2018124892.tif 000016
【図１５】
2018124892.tif 000017
【図１６】
2018124892.tif 000018
【図１７】
2018124892.tif 000019
【図１８】
2018124892.tif 000020
【図１９】
2018124892.tif 000021
【図２０】
2018124892.tif 000022
【図２１】
2018124892.tif 000023
【図２２】
2018124892.tif 000024
【図２３】
2018124892.tif 000025
【図２４】
2018124892.tif 000026
【図２５】
2018124892.tif 000027
【図２６】
2018124892.tif 000028
【図２７】
2018124892.tif 000029