以下、図面にしたがって本発明の実施の形態について説明する。ただし、本発明の技術的範囲はこれらの実施の形態に限定されず、特許請求の範囲に記載された事項とその均等物まで及ぶものである。
[ソースコードの最適化]
ソースコードの最適化処理は、例えば、実行ファイルを効率化し、実行時間やメモリ使用量などを最小化するために、ソースコードを修正する処理を示す。ソースコードの最適化によって、プログラムの実行時間の減少や、使用するメモリ量の減少が実現する。最適化処理は、例えば、外部メモリへのアクセス回数の削減や、ループ処理内の判定処理の削減、除算の削減等の処理を含む。コンパイルプログラムは、最適化後ソースファイルを入力として、オブジェクトコードを生成する。
初めに、本実施の形態におけるソースコードの一例を説明する。
[ソースコード]
図1は、最適化対象となるソースファイルcaに記述されたソースコードの一例を示す図である。図1に示すソースコードは、ループ処理を含み、ループ処理内で構造体が有するメンバにアクセスする処理を含む。
図1に示すコードcd1は、多次元構造体「members」を定義するコードである。多次元構造体「members」は、メンバとして、構造体「subject」型の構造体を40個有する構造体配列(members[40])と、リザーブ領域(reserve[2])とを有する。多次元構造体「members」は、例えば、生徒40人分の、各科目の得点に関する情報を有する構造体である。
構造体配列(members[40])の各構造体「members」は、subject型の構造体である。コードcd2によると、subject型の構造体は、メンバとして、char型の変数「math」と、char型の変数「eng」と、リザーブ領域「reserve[7]」とを有する。変数「math」は、例えば、数学の得点を格納する変数であって、変数「eng」は、例えば、英語の得点を格納する変数である。このように、構造体配列(members[40])は、例えば、生徒40人分の、数学及び英語の得点の情報を有する。
また、図1に示すコードcd3は、8個の多次元構造体「members」を2セット分、メモリ上の領域に確保することを指示するコードである。変数「Class[2][8]」は、メモリ上に確保した、8個の多次元構造体「members」の2セット分の領域を示す。
また、図1に示すソースコードは、処理として3つのループ処理lp1〜lp3を有する。第1のループ処理lp1は、カウンタ変数「i」がループ毎にインクリメントされ、値「0」から値「1」に達するまで、括弧({})内の処理を繰り返すループ処理である。即ち、第1のループ処理lp1は、括弧({})内の処理を、2回繰り返す。
第2のループ処理lp2は、カウンタ変数「c」がインクリメントされ、値「0」から値「7」に達するまで、括弧({})内の処理を8回、繰り返すループ処理である。ただし、第2のループ処理lp2は、第1のループ処理lp1に含まれる。したがって、プログラムの実行時、CPUは、第2のループ処理lp2を、計16(=2×8)回、実行する。
第3のループ処理lp3は、カウンタ変数「m」がループ毎にインクリメントされ、値「0」から値「40」に達するまで、括弧({})内の処理を40回、繰り返すループ処理である。ただし、第3のループ処理lp3は、第1、第2のループ処理lp1、lp2に含まれる。したがって、プログラムの実行時、CPUは、第3のループ処理lp3を、計「640(=16×40)」回、実行する。
また、第3のループ処理lp3は、変数「Class[i][c].members[m]」のメンバmath及びメンバengに、値「0」をセットするコードcd4、cd5を含む。具体的に、コード「Class[i][c].members[m].math = 0;」cd4は、iセット目、c個目の多次元構造体「members」が有する構造体配列members[40]のうち、m番目の構造体「members」のメンバmathに、値「0」をセットする処理を示す。コードcd5についても同様にして、iセット目、c個目の多次元構造体「members」が有する構造体配列members[40]のうち、m番目の構造体「members」のメンバengに、値「0」をセットする処理を示す。
[多次元構造体]
図2は、図1のソースコードに示す、変数「Class[2][8]」の構成を示す図である。図1で前述したとおり、変数「Class[2][8]」は、2セット分の、8個の多次元構造体「members」を示す。したがって、図2は、1セット目の8個の多次元構造体「members」を示す構造体「Class[0][0]〜Class[0][7]」、及び、2セット目の8個の多次元構造体「members」を示す、構造体「Class[1][0]〜Class[1][7]」を表わす。
また、図2に示すように、図1で前述したとおり、構造体「Class[0][0]〜Class[1][7]」のそれぞれは、メンバ(構造体配列members[40])を有する。メンバ(構造体配列members[40])は、40個分のsubject型の構造体「members」を有する。
図2に示す矢印p0は、変数「Class[2][8]」の先頭アドレスを示す。また、矢印p1は、構造体「Class[0][0]」のアドレスを示し、矢印p0が示すアドレスと同様である。また、矢印p2は、構造体「Class[0][1]」のアドレスを示す。同様にして、矢印p3は構造体「Class[0][2]」のアドレスを示し、矢印p4は構造体「Class[0][7]」のアドレスを示す。
また、図2に示す矢印p11は、構造体「Class[1][0]」のアドレスを示し、矢印p12は、構造体「Class[1][1]」のアドレスを示す。同様にして、矢印p13は構造体「Class[1][2]」のアドレスを示し、矢印p14は構造体「Class[1][7]」のアドレスを示す。
矢印p21は、構造体「Class[0][0]」が有する構造体配列「members[40]」の、1個目の構造体「members[0]」のアドレスを示し、矢印p0、p1と同様のアドレスを示す。矢印p22は、構造体「Class[0][0]」が有する構造体配列「members[40]」の、2個目の構造体「members[1]」のアドレスを示す。
同様にして、矢印p23は構造体「Class[0][0]」が有する構造体配列「members[40]」の、3個目の構造体「members[2]」のアドレスを示し、矢印p24は40個目の構造体「members[39]」のアドレスを示す。
コードcd4に示す、変数「Class[i][c].members[m]」のメンバmathに値「0」をセットする処理は、図2に示すアドレスp21〜p24が指す各構造体「members」のメンバmathに、値「0」をセットする処理を示す。
コードcd4に示す処理は、変数「Class[i][c].members[m].math」のアドレスの算出工程を含む。当該算出工程は、変数「Class[i][c]」のアドレスp1〜p14の算出工程と、アドレスp1〜p14からmembers[m]のメンバmathのアドレスp21〜p24までの差分アドレスを算出する工程と、アドレスp1〜p14に差分アドレスを加算する工程を含む。
なお、アドレスp1〜p14の算出工程は、変数「Class[0][0]」のアドレスp0の取得工程と、アドレスp0から変数「Class[i][c]」のアドレスp1〜p14までの差分アドレスを算出する工程と、アドレスp0に差分アドレスを加算する工程とを含む。例えば、CPU(Central Processing Unit:CPU)は、メモリ管理ユニット等を介して、変数「Class[0][0]」のアドレスを取得する。
このように、構造体が有するメンバ(図1の例では、math、eng)にアクセスする場合、構造体のアドレスの算出工程が生じる。即ち、CPUは、図1に示すソースファイルcaに対応するプログラムを実行する際に、コードcd4の処理を行う毎に、アドレスp1〜p14の算出工程を行う。図1のコードcd15に示す処理も同様である。また、図1に図示していないが、配列が有するメンバにアクセスする場合についても、同様である。
また、図1で前述したとおり、プログラムを実行する際、CPUは、第3のループ処理lp3を、合計「640(=2×8×40)回」、実行する。したがって、ループ回数の多いループ処理内で、構造体または配列が有するメンバにアクセスする処理を行う場合、多量のアドレス算出工程が生じる。これにより、プログラムの実行にかかるサイクル数が増加し、プログラムの性能(実行時間)が、所定値を満たせない場合がある。
[本実施の形態の概要]
したがって、本実施の形態における情報処理装置(プログラムの最適化装置)は、ソースコードから、ループ処理内でアクセス対象となるメンバを有する構造体または配列を検出する。また、情報処理装置は、ポインタ変数を宣言する第1のコード、及び、構造体または配列のアドレスを、ポインタ変数にセットする第2のコードを、ソースコードのループ処理の前に挿入する。また、情報処理装置は、ループ処理内の、メンバにアクセスするコードを、ポインタ変数に基づいてメンバにアクセスする第3のコードに置換する。
なお、ソースコードにおけるコードの記述順と、ソースコードに対応するプログラムの実行時の、コードの実行順とは異なる場合がある。具体的に、ソースコード上で、所定コードの後に記述されているコードであっても、プログラムの実行時には、所定コードの前に実行される場合がある。第2のコードをループ処理の前に挿入することは、ループ処理の実行前に第2のコードを実行することを示す。
図3は、本実施の形態における情報処理装置が、図1に示すソースコードを最適化した後の、最適化後のソースコードの一例を示す。
図1の例によると、情報処理装置は、図1に示すソースコードから、ループ処理lp3内でアクセス対象となるメンバ「math、eng」を有する構造体または配列として、構造体「Class[i][c]」を検出する。
そして、情報処理装置は、ポインタ変数「members_p」を宣言するコードcd11、及び、構造体「Class[i][c]」のアドレスp1〜p14(図2)をポインタ変数にセットするコードcd12を、ループ処理lp3の前に挿入する。また、情報処理装置は、ループ処理lp3内の、メンバにアクセスするコードcd4、cd5を、ポインタ変数に基づいてメンバにアクセスするコードcd13、cd14に置換する。
図3に示すコードcd11は、ポインタ変数「members_p」を宣言するコードを示す。ポインタ変数は、アドレスを保持する変数を示す。なお、コードcd11における、値「restrict」は、コンパイラプログラムの最適化処理のための値を示し、エイリアスが存在しないと仮定した最適化を許可する旨を示す。図3の例では、値「restrict」を付加しているが、値「restrict」は、付加されていなくてもよい。
コードcd12は、ポインタ変数「members_p」に、変数「Class[i][c]」のアドレス「&Class[i][c]」p1〜p14をセットするコードを示す。コードcd13、cd14は、ポインタ変数「members_p」に基づいて、変数「Class[i][c].members[m]」の各メンバにアクセスし、値「0」をセットする処理を示す。
コードcd13、cd14は、アドレスp1〜p14を有するポインタ変数「members_p」に基づいてメンバにアクセスするコードを示す。これにより、コードcd13、cd14の実行時に、変数「Class[i][c]」のアドレスp1〜p14の算出工程が生じない。つまり、ポインタ変数に基づくアクセス処理に置換することによって、構造体(または配列)のアドレス算出工程を省略可能になる。
つまり、コードcd13、cd14の実行時に、図2に示すアドレスp0を取得する工程、アドレスp0からアドレスp1〜p14までの差分アドレスを算出する工程、アドレスp0と差分アドレスとを加算する工程が生じない。また、図3のソースコードによると、第2のループ処理lp2は、新たに、アドレスp1〜p14の算出工程を行うコードcd12を有する。
ただし、第2のループ処理lp2の総ループ回数「16(=2×8)」は、第3のループ処理lp3の総ループ回数「640(=16×40)」に対して大幅に少ない。したがって、アドレスp1〜p14の算出工程が、第3のループ処理lp3の外に移動することによって、アドレスp1〜p14の算出工程の回数を大幅に削減可能になる。
このように、本実施の形態における情報処理装置は、ループ処理内でアクセス対象となるメンバを有する構造体のアドレスの算出工程を、当該ループ処理の外に移動することによって、ループ処理内の構造体のアドレスの演算処理(算出工程)を抑制する。これにより、情報処理装置は、値「アドレス計算処理×総ループ回数」のサイクル数の削減を実現できる。
このように、繰り返し行うループ処理内の、アドレスの演算処理の回数を抑制することにより、プログラム実行時の処理量が大幅に減少し、プログラムの実行にかかるサイクル数を大幅に削減可能になる。これにより、プログラムの実行時間の高速化が実現可能になる。
また、情報処理装置は、ループのネストが深く、アクセス処理を含むループ処理のループ回数が多い程、アドレスの演算処理の抑制度合いを向上できる。また、情報処理装置は、ループ処理内のアクセス処理のコード(図1のコードcd4、cd5)の数が多い程、アドレスの演算処理の抑制度合いを向上できる。また、情報処理装置は、アドレスの演算処理を移動する対象の構造体や配列の階層が深い程、アドレスの演算処理の抑制度合いを向上できる。
また、本実施の形態における最適化処理によると、アクセス処理におけるアドレス算出工程が抑制されるため、使用するアドレスレジスタの数を抑制することが可能になる。これにより、アドレスレジスタの不足によってスタックポインタにメモリ転送による退避を行う頻度が減少するため、処理のレイテンシを抑制可能になる。
また、本実施の形態における情報処理装置は、選任の技術者に最適化処理を依頼することなく、簡易に、ソースコードの最適化処理を実現することができる。これにより、最適化処理にかかるコストや工数を抑制可能になる。また、情報処理装置は、最適化処理にしたがってソースコードを複雑化しない。したがって、情報処理装置は、ソースコードの可読性を低下せずに、プログラムの保守性を維持できる。
図4は、本実施の形態における情報処理装置の、ソースコードの最適化処理を説明するフローチャート図である。
S11:情報処理装置は、ソースファイルcaからソースコードを読み出し、ループ処理内でアクセス対象となるメンバを有する構造体または配列を検出する。図1のソースコードによると、情報処理装置は、第3のループ処理内のコードcd14、cd15に基づいて、構造体「Class[i][c].members[m]」を検出する。
S12:情報処理装置は、ポインタ変数を宣言する第1のコード、及び、構造体または配列のアドレスを、ポインタ変数にセットする第2のコードをループ処理の前に挿入する。図3の例によると、情報処理装置は、ポインタ変数「members_p」を宣言する第1のコードcd11、ポインタ変数「members_p」に構造体「Class[i][c]」のアドレスをセットする第2のコードcd12を、第3のループ処理lp3の前に挿入する。
S13:情報処理装置は、ループ処理内の、メンバにアクセスするコードを、ポインタ変数に基づいてメンバにアクセスするコードに置換する。
図3の例によると、情報処理装置は、図1のソースコードに示すコード「Class[i][c].members[m].math=0;」cd4を、ポインタ変数「members_p」に基づくコード「members_p->members[m].math=0」cd13に置換する。同様にして、情報処理装置は、図1のソースコードに示すコード「Class[i][c].members[m].eng=0;」cd5を、ポインタ変数「members_p」に基づくコード「members_p->members[m].eng=0」cd14に置換する。
図5は、図1のソースファイルcaに対応するプログラムの命令と、図3の最適化後ソースファイルcbに対応するプログラムの命令とを表す図である。図5の左図は、図1のソースファイルcaに対応するプログラムの命令を示し、図5の右図は、図3の最適化後ソースファイルcbに対応するプログラムの命令を示す。
初めに、図1のソースファイルcaに対応するプログラムの命令を説明する。図5の左図の、17行〜37行の命令は第3のループ処理lp3を示す。また、14行〜38行の命令は第2のループ処理lp2を示し、11行〜39行の命令は第1のループ処理lp1を示す。
第3のループ処理lp3に対応する17行〜37行のうち、20行〜27行は変数「Class[i][c].members[m].math」に値「0」をセットする処理(cd4)を示す。また、28行〜36行は、変数「Class[i][c].members[m].eng」に値「0」をセットする処理(cd5)を示す。
また、コードcd4に対応する20行〜27行のうち、23行〜25行は、構造体「Class[i][c]」のアドレスp1〜p14の算出工程を示す。具体的に、23行は構造体「Class[0][0]」のアドレスp0の取得処理を、24行は、アドレスp0から構造体「Class[i][c]」のアドレスp1〜p14までの差分アドレスの算出処理を示す。また、25行は、アドレスp0と差分アドレスとの加算処理を示す。
同様にして、コードcd5に対応する28行〜36行のうち、31行〜33行は、構造体「Class[i][c]」のアドレスp1〜p14の算出工程を示す。31行〜33行の処理の詳細は、23行〜25行と同様である。
次に、図3の最適化後ソースファイルcb(図3)に対応するプログラムの命令を説明する。図5の右図の、20行〜34行の命令は第3のループ処理lp3を示す。また、14行〜32行の命令は第2のループ処理lp2を示し、11行〜33行の命令は第1のループ処理lp1を示す。
図3の例によると、第2のループ処理lp2は、ポインタ変数「members_p」に、変数「Class[i][c]」のアドレスをセットする処理(cd12)を有する。第2のループ処理lp2に対応する14行〜32行のうち、15行〜17行はコードcd12の処理を示す。なお、15行〜17行の各処理は、図5の左図に示す、23行〜25行、及び、31行〜33行の処理と同様である。
また、第3のループ処理lp3に対応する20行〜34行のうち、23行〜27行は、変数「members_p->members[m].math」に値「0」をセットする処理(コードcd13)を示す。また、28行〜33行は、変数「members_p->members[m].eng」に値「0」をセットする処理(コードcd14)を示す。図5の左図によると、第3のループ処理lp3は、変数「Class[i][c]」のアドレスの算出工程(15行〜17行)を有しない。このように、コードcd13、cd14の実行の度に、15行〜17行に示す3つの命令を省略可能になるため、処理サイクルを削減可能になる。
(サイクル数)
図6は、図1のソースファイルcaに対応するプログラムの実行にかかるサイクル数と、図3の最適化後ソースファイルcbに対応するプログラムの実行にかかるサイクル数を表す図である。
初めに、図1のソースファイルcaに対応するプログラムの実行にかかるサイクル数を説明する。図1のソースファイルcaに対応するプログラムによると、例えば、第3のループ処理lp3の実行にかかるサイクル数は、18サイクルである。また、第1のループ処理lp1のループ回数は2回、第2のループ処理lp2のループ回数は8回、第3のループ処理lp3のループ回数は40回である。
したがって、図1のソースファイルcaに対応するプログラムの実行にかかるサイクル数は、例えば、式「13+2*{4+{8*(4+(40*18))}}」にしたがって算出した値「11605Cycle」となる。
一方、図3のソースファイルcbに対応するプログラムによると、コードcd13、cd14毎に、3命令分、処理が減少する。したがって、第3のループ処理lp3毎に、6命令文の処理が減少する。したがって、第3のループ処理lp3の実行にかかるサイクル数は、例えば、12サイクルとなる。一方、第2のループ処理lp2毎に、3命令文の処理が増加する。
したがって、最適後のソースファイルcaに対応するプログラムの実行にかかるサイクル数は、例えば、式「13+2*{4+{8*(3+(4+(40*12)))}}」にしたがって算出した値「7813Cycle」となる。このように、ソースコードの最適化処理によって、サイクル数は「0.673(≒7813/11605)」となり、サイクル数が約68%に減少する。
なお、図1、図3の例はメンバを有する構造体の例を示すが、本実施の形態における最適化処理は、メンバを有する配列に関しても有効である。配列に適用する例を、図27、図28にしたがって後述する。
次に、図7、図8にしたがって、本実施の形態における情報処理装置のハードウェア構成、及び、ソフトウェアブロック図を説明する。
[情報処理装置100のハードウェア構成]
図7は、本実施の形態における情報処理装置(プログラムの最適化装置)100のハードウェア構成図である。情報処理装置100は、例えば、CPU(Central Processing Unit:CPU)101、メインメモリ201や補助記憶装置111等を備えるメモリ102、通信インタフェース部103、外部インタフェース部104を有する。各部は、バス106を介して相互に接続する。
CPU101は、バス106を介してメモリ102等と接続するとともに、情報処理装置100全体の制御を行う。通信インタフェース部103は、インターネット等を介して、他の機器(図示せず)と接続し、ネットワークに対するアクセスを行う。RAM(Random Access Memory:RAM)等を示すメインメモリ201は、CPU101が処理を行うデータ等を記憶する。また、外部インタフェース部104は、ストレージ装置SD等と接続する。
補助記憶装置111は、CPU101が実行するオペレーションシステムのプログラムを格納する領域(図示せず)を備える。また、補助記憶装置111は、コンパイルプログラム格納領域120、テーブル群格納領域130を備える。また、補助記憶装置111は、ソースファイル格納領域ca、最適化後ソースファイル格納領域cb、オブジェクトファイル格納領域obを有する。補助記憶装置111は、HDD(Hard disk drive:HDD)、不揮発性半導体メモリ等を示す。
コンパイルプログラム格納領域120のコンパイルプログラム(以下、コンパイルプログラム120と称する)は、CPU101の実行によって、コンパイルプログラム(最適化プログラム)120の処理を実現する。テーブル群格納領域130のテーブル群(以下、テーブル群130と称する)は、コンパイルプログラム120が生成するテーブルである。テーブル群130が有する各テーブルは、図8にしたがって後述する。
ソースファイル格納領域caのソースファイル(以下、ソースファイルcaと称する)は、コンパイルプログラム120の入力となるファイルであって、最適化処理の対象となるソースファイルcaを示す。最適化後ソースファイル格納領域cbの最適化後ソースファイル(以下、最適化後ソースファイルcbと称する)は、コンパイルプログラム120が最適化処理を行って生成するファイルであって、コンパイル対象となるファイルを示す。
オブジェクトファイル格納領域obのオブジェクトファイル(以下、オブジェクトファイルobと称する)は、コンパイルプログラム120が、最適化後ソースファイルcbを入力としてコンパイル処理を行って生成するファイルを示す。
[情報処理装置100のソフトウェアブロック]
図8は、図7に示したコンパイルプログラム120のソフトウェアブロックの構成図である。コンパイルプログラム120は、最適化モジュール121と、コンパイルモジュール125とを有する。最適化モジュール121は、例えば、検出モジュール122、構造体解析モジュール123、コード修正モジュール124を有する。
最適化モジュール121は、ソースファイルcaを入力として、最適化後ソースファイルcbを生成する。また、最適化モジュール121は、テーブル群130(図7)を生成する。コンパイルモジュール125は、最適化後ソースファイルcbを入力としてコンパイル処理を行い、オブジェクトファイルobを生成する。
また、テーブル群130は、ループ文検知テーブル131、構造体検知テーブル132、最適化構造体テーブル133、変更最適化構造体テーブル134を有する。
ループ文検知テーブル131は、ソースファイルcaに記述されたソースコード内のループ処理の情報を保持するテーブルである。ループ文検知テーブル131の詳細は、図11にしたがって後述する。構造体検知テーブル132は、ループ処理内でアクセス対象となるメンバを有する構造体の構成に関する情報を有するテーブルである。構造体検知テーブル132の詳細は、図13にしたがって後述する。
最適化構造体テーブル133は、構造体検知テーブル132に記憶された構造体のアドレスの、ループ処理毎の値の変更の有無に関する情報を、構造体の階層毎に有するテーブルである。最適化構造体テーブル133の詳細は、図15にしたがって後述する。変更最適化構造体テーブル134は、構造体検知テーブル132に格納された構造体の、ポインタ変数に関する情報を有するテーブルである。変更最適化構造体テーブル134の詳細は、図18にしたがって後述する。
検出モジュール122は、ソースファイルcaを入力として、ソースファイルcaに記述されたコードのうちループ処理に対応するコードを検出し、ループ文検知テーブル131に記憶する。また、検出モジュール122は、ループ文検知テーブル131を参照し、構造体の構成を解析し、構造体の構成に関する情報を構造体検知テーブル132を生成する。構造体解析モジュール123は、構造体検知テーブル132を参照し、検出した構造体の、ループ処理内のアクセス処理を解析し、最適化構造体テーブル133を生成する。
コード修正モジュール124は、最適化構造体テーブル133を参照して、ポインタ変数にセットする構造体の型に基づいてポインタ変数の名前を生成し、変更最適化構造体テーブル134に記憶する。また、コード修正モジュール124は、ソースファイルcaを複写し最適化後ソースファイルcbを生成するとともに、変更最適化構造体テーブル134を参照し、最適化後ソースファイルcbのソースコードを修正する。
[コンパイルプログラム120の処理の流れ]
次に、図9のフローチャート図にしたがって、図8で説明したコンパイルプログラム120の処理の詳細を説明する。
図9は、図8で説明したコンパイルプログラム120の処理の詳細を説明するフローチャート図である。
S21:検出モジュール122は、ソースファイルcaを入力として、ループ文及び構造体の検知処理を行う。また、構造体解析モジュール123は、構造体検知テーブル132を参照し、構造体の構成の解析処理を行う。工程S21の処理の詳細は、図10〜図15にしたがって後述する。
具体的に、図8で前述したとおり、検出モジュール122は、ループ処理に対応するコードを検出し、ループ文検知テーブル131に記憶する。また、検出モジュール122は、ループ処理に対応するコードに、構造体のメンバへのアクセス処理が含まれている場合に、構造体検知テーブル132に記憶する。また、構造体解析モジュール123は、構造体検知テーブル132を参照して構造体の構成の解析処理を行い、最適化構造体テーブル133に記憶する。
S22:コード修正モジュール124は、構造体の解析結果に基づいて、ポインタ変数の型を決定し、最適化後ソースファイルcbに対するコードの修正処理を行う。工程S22の処理の詳細は、図16にしたがって後述する。
具体的に、コード修正モジュール124は、最適化構造体テーブル133を参照し、ループ処理の度にアドレスが変化しない構造体または配列のアドレスを、ポインタ変数にセットする。つまり、コード修正モジュール124は、メンバを有する構造体(配列)のアドレスが、ループ処理の外で一定である場合に、当該構造体のアドレスのセットをループ処理の外に移動する。これにより、コード修正モジュール124は、ループ処理の外でアドレスに変更が生じない構造体(配列)を適切に検出することができる。
また、コード修正モジュール124は、ポインタ変数の名前を決定し、決定したポインタ変数の名前を、変更最適化構造体テーブル134に記憶する。また、コード修正モジュール124は、ポインタ変数の名前に基づいて、最適化後ソースファイルcbに対し、コードの挿入、及び、コードの置換処理を行う。コード修正モジュール124は、コードの挿入、及び、置換にしたがって、検出した構造体(配列)のアドレスの演算処理をループ処理の外に移動する。
S23:コンパイルモジュール125は、最適化後ソースファイルcbを入力としてコンパイル処理を行い、オブジェクトファイルobを生成する。また、図示していないが、リンカモジュールは、1つまたは複数のオブジェクトファイルobを入力として、実行プログラムを生成する。
なお、本実施の形態における最適化処理の実行の可否を、ユーザに選択可能にしてもよい。これにより、デバッグ時に開発者の意図するデバッグ処理を可能にし、デバッグの完了後に、最適化処理を行うことで、開発効率を低下させずに性能を向上させることが可能になる。
(工程S21の処理)
図10は、図9で説明した工程S21の処理の詳細を説明する第1のフローチャート図である。
S31:検出モジュール122は、ソースファイルcaから、コードを1行読み出す。
S32:検出モジュール122は、ソースファイルcaの末尾(End Of File:EOF)を検知したか否かを判定する。ソースファイルcaの末尾を検知した場合(S32のYes)、検出モジュール122は、処理A1に遷移する。処理A1は、図12のフローチャート図で後述する。
S33:ソースファイルcaの末尾を検知しない場合(S32のNo)、検出モジュール122は、読み出したコードが、for文を含んでいるか否かを判定する。for文を含んでいない場合(S33のNo)、検出モジュール122は、工程S31の処理に遷移し、再び、ソースファイルcaから、コードを1行読み出す。
S34:一方、読み出したコードがfor文を含む場合(S33のYes)、検出モジュール122は、読み出したコードをループ文検知テーブル131に書き込む。ループ文検知テーブル131については、図11にしたがって後述する。
S35:検出モジュール122は、for文の検出に応答して、ループ階層(ネスト)を示すカウンタを、カウントアップする。
S36:検出モジュール122は、ソースファイルcaから、さらに、コードを1行読み出す。
S37:検出モジュール122は、読み出したコードがfor文を含むか否かを判定する。読み出したコードがfor文を含む場合(S37のYes)、検出モジュール122は、工程S34の処理に遷移し、読み出したコードを、ループ文検知テーブル131に書き込む。
S38:一方、読み出したコードがfor文を含んでいない場合(S37のNo)、検出モジュール122は、読み出したコードが文字”}”を含み、ループ階層の数に対応した文字”}”を検出したか否かを判定する。
S39:読み出したコードが文字”}”を含んでいない場合(S38のNo)、または、文字”}”を含むものの、ループ階層の数に対応した文字”}”を検出していない場合(S38のNo)、検出モジュール122は、読み出したコードをループ文検知テーブル131に書き込む。そして、検出モジュール122は、工程S36に遷移し、ソースファイルcaから、さらに、コードを1行読み出す。
一方、読み出したコードが文字”}”を含み、ループ階層の数に対応した文字”}”を検出した場合(S38のYes)、検出モジュール122は、処理A2に遷移する。処理A2は、図12のフローチャート図で後述する。
(ループ文検知テーブル131)
図11は、ループ文検知テーブル131の一例を示す図である。ループ文検知テーブル131は、例えば、項目「NO」、項目「ループ構成」、項目「ループ内変数」、項目「値」、項目「コードカウンタ」を有する。項目「NO」は、各コードの識別情報を示す。
項目「ループ構成」は、ソースファイルcaから読み出した、for文に対応するコードを示す。for文に対応するコードは、for文から文字”}”までのコードを示す。図11に示すように、for文が多階層のループ処理である場合、ループ文検知テーブル131は、多階層のループ処理に対応するコードを有する。
項目「ループ内変数」はfor文のカウンタ変数の名前を示し、項目「値」はカウンタ変数の条件継続式(例えば、「i < 2」)における最大値を有する。したがって、第1のループ処理lp1のカウンタ変数は、変数「i」であって値は「2」である。同様にして、第2のループ処理lp2のカウンタ変数は、変数「c」であって値は「8」であり、第3のループ処理lp3のカウンタ変数は、変数「m」であって値は「40」である。
また、項目「コードカウンタ」は、for文内の、構造体のメンバへのアクセス処理を行うコードの数を示す。図11の例によると、第3のループ処理lp3は、構造体のメンバへのアクセス処理を行うコードを2つ有する。したがって、第3のループ処理lp3に対応するコードカウンタは、値「2」となる。
図12は、図9で説明した工程S21の処理を説明する第2のフローチャート図である。
S41:検出モジュール122は、図10のフローチャート図の処理A2として、ループ文検知テーブル131(図11)を読み出す。
S42:検出モジュール122は、ループ文検知テーブル131の項目「ループ構成」から、文字”.”を検出したか否かを判定する。
S43:文字”.”を検知した場合(S42のYes)、ループ処理内に、構造体のメンバへのアクセス処理を行うコードが存在することを示す。したがって、検出モジュール122は、コードカウンタをインクリメントし、ループ文検知テーブル131に記憶する。具体的に、図11のループ文検知テーブル131によると、検出モジュール122は、文字”.”を含む、コード「Class[i][c].members[m].math=0;」及びコード「Class[i][c].members[m].eng=0;」を検出するため、コードカウンタを値「2」に設定する。
一方、文字”.”を検知しない場合(S42のNo)、ループ処理内に、構造体のメンバへのアクセス処理を行うコードが存在しないことを示す。したがって、検出モジュール122は、図10のフローチャート図の処理A3に遷移し、ソースファイルcaからコードを1行読み出す。これにより、検出モジュール122は、別のループ処理を検出し、ループ文検知テーブル131に記憶する。
S44:検出モジュール122は、検出したコードから文字”.”を抽出することによって、構造体を分解する。そして、検出モジュール122は、分解した構造体の構成を、構造体検知テーブル132に記憶する。構造体検知テーブル132の詳細は、図13にしたがって後述する。
図11のループ文検知テーブル131によると、検出モジュール122は、コード「Class[i][c].members[m].math=0;」に基づいて、構造体「Class[i][c]」、構造体「members[m]」と、メンバ「math」に分解し、構造体検知テーブル132に記憶する。同様にして、検出モジュール122は、コード「Class[i][c].members[m].eng=0;」に基づいて、構造体「Class[i][c]」、構造体「members[m]」と、メンバ「eng」に分解し、構造体検知テーブル132に記憶する。
構造体を分解すると、検出モジュール122は、図10のフローチャート図の処理A3に遷移してソースファイルcaからコードを1行読み出し、別のループ処理を検出する。
S45:また、検出モジュール122は、図10のフローチャート図の処理A1として、コードカウンタが値「1」以上のループ処理の、総ループ回数が閾値を超えるか否かを判定する。即ち、検出モジュール122は、ソースファイルcaの末尾を検知した場合(図10のS32のYes)、第3のループ処理lp3の総ループ回数が閾値を超えるか否かを判定する。閾値は、検証等にしたがって予め設定される値である。本実施の形態において、閾値は、例えば、値「10」である。
ループが多階層のループである場合、即ち、対象のループ処理lp3が別のループ処理lp2に含まれる場合、総ループ回数は、ループ処理lp3の第1のループ回数と、別のループ処理lp2の第2のループ回数との積を示す。例えば、図1の例によると、第3のループ処理lp3の総ループ回数は、値「640(=2×8×40)」である。
S46:総ループ回数が閾値を超える場合(S45のYes)、構造体解析モジュール123は、図14に後述する、構造体解析処理を行う。一方、総ループ回数が閾値を超えない場合(S45のNo)、構造体解析モジュール123は、構造体解析処理を行わない。即ち、構造体解析モジュール123は、総ループ回数が閾値を超えないループ処理に関しては、最適化処理の対象としない。
総ループ回数が閾値を超えない場合(S45のNo)、ループ処理が、構造体のメンバに対するアクセス処理を含んでいてもアクセス処理の回数は多くないため、アドレスの演算処理の回数も多くない。したがって、構造体のアドレスの演算処理を、ループ処理の外に遷移したとしても、サイクル数の削減率が大きくならない場合がある。
したがって、本実施の形態における検出モジュール122は、総ループ回数が所定値を超えるループ処理内でアクセス対象となる、メンバを有する構造体または配列を検出する。つまり、検出モジュール122は、総ループ回数が閾値を超えないループ処理に含まれるアクセス処理を、最適化対象外にすることにより、サイクル数を大幅に向上可能にする構造体または配列を検出できる。
(構造体検知テーブル132)
図13は、構造体検知テーブル132の一例を示す図である。構造体検知テーブル132は、例えば、項目「NO」、項目「ループ構成」、項目「多次元階層」を有する。項目「NO」は、図11のループ文検知テーブル131で説明したとおりである。
図13に示す構造体検知テーブル132における項目「ループ構成」は、さらに、構造体の階層を示す項目「S1」「S2」「S3」を有する。
図12のフローチャート図の工程S44で前述したとおり、構造体検知テーブル132は、コード「Class[i][c].members[m].math=0;」に基づいて、値「Class[i][c]」(S1)、値「members[m]」(S2)、値「math」(S3)を有する。同様にして、構造体検知テーブル132は、コード「Class[i][c].members[m].eng=0;」に基づいて、値「Class[i][c]」(S1)、値「members[m]」(S2)、値「eng」(S3)を有する。
また、項目「多次元階層」は、構造体の階層を示す。例えば、構造体「Class[i][c]」は、二次元構造体である。したがって、各コードに対応する項目「多次元階層」の値は、値「2」である。
(S46:構造体解析処理)
図14は、図12で説明した工程S46の構造体解析処理を説明するフローチャート図である。
S51:構造体解析モジュール123は、ループ文検知テーブル131が有する、対象のループ処理のコードカウンタ分、工程S52〜S59の処理を行う。つまり、構造体解析モジュール123は、図13の構造体検知テーブル132によると、NO「7」、NO「8」に関して、工程S52〜S59の処理を行う。
S52:構造体解析モジュール123は、構造体検知テーブル132が有する、多次元階層分、工程S53〜S58の処理を行う。つまり、構造体解析モジュール123は、図13の構造体検知テーブル132によると、各NOを対象として、工程S53〜S58の処理を2回ずつ行う。
S53:構造体解析モジュール123は、ループ文検知テーブル131を参照し、項目「ループ構成」の情報を読み出す。
S54:構造体解析モジュール123は、構造体検知テーブル132の項目「ループ構成」(S1〜S3)のうち、構造体の最下層の添え字を取得する。図13の構造体検知テーブル132によると、構造体解析モジュール123は、値「members[m]」の添え字「m」を取得する。
S55:構造体解析モジュール123は、添え字に文字”=”を付与し、ループ文検知テーブル131の項目「ループ構成」の対象のループ処理から、コード「添え字+”=”」を検索する。即ち、構造体解析モジュール123は、コード「m=」を検索する。なお、コード「m=」は、コード「m++」やコード「m--」を含む。
S56:構造体解析モジュール123は、文字列「添え字+”=”」を検出したか否かを判定する。
S57:検出しなかった場合(S56のNo)、対象のループ処理内で、変数「m」の値が変化しないことを示す。したがって、構造体解析モジュール123は、最適化構造体テーブル133のポインタフラグに値「0(Constant:一定)」を記憶する。そして、構造体解析モジュール123は、工程S53の遷移し、次の上位の階層の情報を読み出す。
S58:一方、文字列「添え字+”=”」を検出した場合(S56のYes)、対象のループ処理内で、変数「m」の値が変化することを示す。したがって、構造体解析モジュール123は、最適化構造体テーブル133のポインタフラグに値「1(Variable:変化)」を記憶する。
図11のループ文検知テーブル131の例によると、第3のループ処理lp3は、コード「m++」を含む。したがって、構造体解析モジュール123は、最適化構造体テーブル133の、値「members[m]」に対応する階層S2のポインタフラグに値「1」を記憶する。
S59:多次元階層分、ループ処理を行うと、構造体解析モジュール123は、工程S60に遷移する。
したがって、構造体解析モジュール123は、コード「c=」を検索する。第3のループ処理lp3は、コード「c++」を含まない。同様にして、構造体解析モジュール123は、コード「i=」を検索するが、第3のループ処理lp3はコード「i++」を含まない。したがって、構造体解析モジュール123は、最適化構造体テーブル133の、値「Class[i][c]」に対応する階層S1のポインタフラグに値「0」を記憶する。
S60:コードカウンタの値分、ループ処理を行うと、構造体解析モジュール123は、処理を終了する。図13の構造体検知テーブル132の例によると、構造体解析モジュール123は、構造体検知テーブル132のNO「8」に関しても同様の処理を行い、同様のポインタフラグをセットする。
(最適化構造体テーブル133)
図15は、最適化構造体テーブル133の一例を示す図である。最適化構造体テーブル133は、例えば、項目「NO」、項目「ポインタフラグ」を有する。項目「NO」は、図11のループ文検知テーブル131で説明したとおりである。
項目「ポインタフラグ」は、各階層(S1〜S3)の構造体のアドレスが、対象のループ処理毎に変化するか否かを示すフラグである。項目「ポインタフラグ」は、ポインタフラグが値「0(Constant)」である場合、ループ処理の度に、当該階層の構造体のアドレスが変化しないことを示す。一方、ポインタフラグが値「1(Variable)」である場合、ループ処理の度に、当該階層の構造体のアドレスが変化することを示す。
図14の工程S58で前述したとおり、値「Class[i][c]」は第3のループ処理lp3毎に変化しないため、項目「S1」は値「0(Constant)」を有する。また、値「members[m]」)は、第3のループ処理lp3毎に変化するため、項目「S2」は値「1(Variable)」を有する。
(工程S22)
図16は、図9で説明した工程S22の処理を説明するフローチャート図である。
S101:コード修正モジュール124は、最適化構造体テーブル133を参照して検出した構造体の型を検出し、ポインタ変数の名前を決定する。そして、コード修正モジュール124は決定したポインタ変数の名前を、変更最適化構造体テーブル134に記憶する。工程S101の処理の詳細は、図17のフローチャート図にしたがって後述する。
S102:コード修正モジュール124は、変更最適化構造体テーブル134を参照してポインタ変数の名前を取得し、ポインタ変数を宣言するコードを、最適化後ソースファイルcbに挿入する。工程S102の処理の詳細は、図19のフローチャート図にしたがって後述する。
S103:コード修正モジュール124は、ポインタ変数に、構造体のアドレスをセットするコードを、最適化後ソースファイルcbにおける対象のループ処理前に挿入する。工程S103の処理の詳細は、図20のフローチャート図にしたがって後述する。
S104:コード修正モジュール124は、最適化後ソースファイルcbにおける、対象のループ処理内の、メンバにアクセスするコードを、ポインタ変数に基づいてアクセスするコードに置換する。工程S104の処理の詳細は、図21のフローチャート図にしたがって後述する。
(工程S101の処理)
図17は、図16で説明した工程S101の処理の詳細を説明するフローチャート図である。
S61:コード修正モジュール124は、ソースファイルcaを複写して、最適化後ソースファイルcbを生成する。
S62:コード修正モジュール124は、ループ文検知テーブル131のコードカウンタ分、工程S63〜S67の処理を行う。つまり、コード修正モジュール124は、構造体検知テーブル132のNO「7」、NO「8」に関して、工程S63〜S67の処理を行う。
S63:コード修正モジュール124は、構造体検知テーブル132、及び、最適化構造体テーブル133を読み出す。
S64:コード修正モジュール124は、最適化構造体テーブル133を参照し、ポインタフラグが値「0(Constant)」の階層があるか否かを検索する。
S65:ポインタフラグが値「0」の階層を検出した場合(S64のYes)、コード修正モジュール124は、ポインタフラグが値「1(Variable)」の階層の上位の構造体であって、ポインタフラグが値「0」の階層の構造体(配列)を抽出する。
図15の最適化構造体テーブル133によると、階層「S1」のポインタフラグが値「0」であって、階層「S2」のポインタフラグが値「1」である。したがって、コード修正モジュール124は、構造体検知テーブル132を参照し、階層「S1」の構造体を示す値「Class[i][c]」を抽出する。
このように、コード修正モジュール124は、ポインタフラグが値「0(Constant)」の階層の、構造体(配列)のアドレスがあるか否かを判定する。これにより、コード修正モジュール124は、ループ処理lp3内でアドレスが変化しない、構造体(配列)のアドレス(この例では、値「Class[i][c]」のアドレス)を抽出する。つまり、コード修正モジュール124は、ループ処理lp3の度に、アドレスが変化しない構造体または配列のアドレスを、適切に検出できる。
S66:一方、ポインタフラグが値「0」の階層を検出しない場合(S64のNo)、ループ処理lp3内で、アドレスが変化しない、構造体(配列)のアドレスが存在しないことを示す。したがって、コード修正モジュール124は、対象のNOのコードを最適化の対象外とする。
S67:コード修正モジュール124は、検出した構造体の型をソースコードから検索する。コード修正モジュール124は、ソースコードから、検出した構造体の変数を宣言しているコードを検出することによって、構造体の型(タグ名)を取得する。そして、コード修正モジュール124は、取得したタグ名に、"_p"を付与したポインタ変数を生成し、変更最適化構造体テーブル134に記憶する。
図1のソースコードによると、値「Class[i][c]」の宣言を行うコードは、コード「struct members Class[2][8];」である。したがって、コード修正モジュール124は、値「Class[i][c]」の型がmembers型であることを検出し、検出した型の名前「members」に"_p"を付与したポインタ変数の名前を生成する。これにより、コード修正モジュール124は、ポインタ変数の名前「members_p」を生成し、変更最適化構造体テーブル134に更新する。
S68:コードカウンタの値分、ループ処理を行うと、工程S101の処理を終了する。
(変更最適化構造体テーブル134)
図18は、変更最適化構造体テーブル134の一例を示す図である。変更最適化構造体テーブル134は、構造体検知テーブル132(図13)と同様にして、例えば、項目「NO」、項目「ループ構成」、項目「多次元階層」を有する。
図18に示す変更最適化構造体テーブル134は、図13の構造体検知テーブル132に対して、ポインタ変数の名前を有する。図17のフローチャート図の工程S67で説明したとおり、変更最適化構造体テーブル134は、値「Class[i][c]」の代わりに、ポインタ変数の名前「members_p」を有する。
(工程S102の処理)
図19は、図16で説明した工程S102の処理の詳細を説明するフローチャート図である。
S71:コード修正モジュール124は、ループ文検知テーブル131のコードカウンタ分、工程S72〜S74の処理を行う。
S72:コード修正モジュール124は、変更最適化構造体テーブル134を読み出す。
S73:コード修正モジュール124は、変更最適化構造体テーブル134が保持するポインタ変数名を取得する。つまり、コード修正モジュール124は、ポインタ変数の名前「members_p」を取得する。
S74:コード修正モジュール124は、変換後構造体テーブルのポインタ変数と、構造体のタグ名に基づいて、ポインタ変数を宣言するコードcd11を生成し、最適化後ソースファイルcbに書き込む。
具体的に、コード修正モジュール124は、検出した型の名前「members」に"_t"を付与したタグ名を生成する。そして、コード修正モジュール124は、「”タグ名” *restrict “ポインタ変数”;」に基づくコード「members_t *restrict members_p;」cd11を生成し、最適化後ソースファイルcbに書き込む。
S75:コードカウンタの値分、ループ処理を行うと、工程S102の処理を終了する。
(工程S103の処理)
図20は、図16で説明した工程S103の処理の詳細を説明するフローチャート図である。
S81:コード修正モジュール124は、生成したポインタ変数に、構造体検知テーブル132の対応する構造体または配列のアドレスをセットするコードcd12を生成する。
図15の最適化構造体テーブル133によると、コード修正モジュール124は、階層「S2」の上位の階層「S1」の構造体の変数名「Class[i][c]」を抽出する。そして、コード修正モジュール124は、抽出した構造体「Class[i][c]」のアドレスを、ポインタ変数「members_p」にセットするコードcd12を生成する。
S82:コード修正モジュール124は、アクセス処理を有するループ処理がネストループに含まれるループ処理であるか否かを判定する。
S83:ネストループに含まれる場合(S82のYes)、コード修正モジュール124は、上位のループ処理内で、ポインタ変数にセットしたアドレスが変化するか否かを判定する。つまり、コード修正モジュール124は、第2のループ処理lp2内で、アドレス「& Class[i][c]」が変化するか否かを判定する。
S84:上位のループ処理でアドレスが変化する場合(S83のYes)、コード修正モジュール124は、アクセス処理を含むループ処理の前であって、上位のループ処理内に、コードcd12を挿入する。
図1のソースコードによると、アドレス「& Class[i][c]」は、第2のループ処理lp2内で変化する。したがって、コード修正モジュール124は、図3に示すように、コードcd12を、アクセス処理を含む第3のループ処理lp3の前であって、第2のループ処理lp2内に挿入する。
S85:一方、上位のループ処理でアドレスが変化しない場合(S83のNo)、アクセス処理を含むループ処理の前であって、上位のループ処理の前に、コードcd12を挿入する。
図25、図26にしたがって後述するが、例えば、アドレス「& Class[i][c]」が第2のループ処理lp2内で変化しない場合、コード修正モジュール124は、コードcd12を、第2、第3のループ処理lp2、lp3の前に挿入する。
第1のループ処理lp1のループ回数は、第2のループ処理lp2のループ回数に対して少ない。したがって、アドレスの演算処理を行うコードcd12を、さらに、第2のループ処理lp2の外に移動することにより、アドレスp1〜p14の演算処理の回数をさらに削減可能になる。
このように、コード修正モジュール124は、ループ処理が別のループ処理に含まれ、当該別のループ処理内で構造体または配列のアドレスが変化する場合に、第1、第2のコードcd11、cd12を、ループ処理の前であって別のループ処理内に挿入する。また、コード修正モジュール124は、別のループ処理内でアドレスが変化しない場合に、第1、第2のコードcd11、cd12を、ループ処理及び別のループ処理の前に挿入する。これにより、コード修正モジュール124は、最適化後のソースコードに対応するプログラムのサイクル数を、さらに、削減できる。
S86:一方、ネストループに含まれない場合(S82のNo)、コード修正モジュール124は、アクセス処理を含むループ処理の前に、生成したコードを挿入する。即ち、コード修正モジュール124は、コードcd12を、アクセス処理を含む第3のループ処理lp3の前に挿入する。
(工程S104の処理)
図21は、図16で説明した工程S104の処理の詳細を説明するフローチャート図である。
S91:コード修正モジュール124は、ループ文検知テーブル131のコードカウンタ分、工程S92〜S94の処理を行う。
S92:コード修正モジュール124は、最適化後のソースコードから、対象ループ処理内の、ポインタ変数にアドレスをセットした構造体または配列にアクセスするコードを検出する。即ち、コード修正モジュール124は、置換対象のアクセス処理のコードを検出する。具体的に、コード修正モジュール124は、NO「7」に関して、コード「Class[i][c].members[m].math=0;」を検出する。また、コード修正モジュール124は、NO「8」に関して、コード「Class[i][c].members[m].eng=0;」を検出する。
S93:コード修正モジュール124は、生成したポインタ変数に”->”を付加する。つまり、コード修正モジュール124は、コード「p_members->」を生成する。
S94:コード修正モジュール124は、最適化後ソースファイルcbの、工程S92で検出したコードに関して、文字列「”構造体または配列の値”+"."」を、コード「p_members->」に置換する。
S95:コード修正モジュール124は、コードカウンタの値分、ループ処理を行うと、コード修正モジュール124は、工程S96に遷移する。
S96:コード修正モジュール124は、修正した最適化後ソースファイルcbを補助記憶装置111等に記憶する。
[別のソースコードの例1]
図22は、別の最適化対象のソースコードを含むソースファイルca−1の例を示す図である。図1は、アクセス対象のメンバ「Class[i][c].members[m].math」、「Class[i][c].members[m].eng」のアドレスが、第3のループ処理lp3の毎に変化する場合を例示した。これに対し、図22のソースファイルca−1は、アクセス対象のメンバのアドレスが、第3のループ処理lp3の毎に変化しない例を示す。
図22は、図1のソースコードに対して、コードcd21〜cd23が異なる。コードcd21は、変数「temp」に値「0」をセットする処理を示す。図22の例において、変数「temp」の値は固定値「0」である。したがって、第3のループ処理lp3の度に、値「members[temp]」のアドレスが変化しない。コードcd23についても同様である。
図23は、本実施の形態における情報処理装置が、図22に示すソースファイルca−1を最適化した後の、ソースファイルcb−1の例を示す。情報処理装置100は、コードcd31、cd32をソースコードに挿入するともに、コードcd22、cd23(図22)を、コードcd33、cd34に置換する。コードcd31、cd32は、図3の例と同様である。
コードcd33、cd34は、ポインタ変数「members_p」に基づいて、メンバ「members[temp].math」「members[temp].eng」にアクセスするコードである。図3の例と同様にして、図23に示すソースコードによると、コードcd33、cd34は、変数「Class[i][c]」のアドレスp1〜p14の算出工程を有しない。したがって、第3のループ処理lp3における、アドレスp1〜p14の算出工程を省略可能になり、アドレスの演算処理が大幅に減少する。これにより、プログラムの実行にかかるサイクル数が、大幅に向上する。
なお、アクセス対象のメンバのアドレスが、第3のループ処理lp3の毎に変化しない場合、情報処理装置100は、メンバmathの上位のsubject構造体のアドレスp21〜p24の演算処理を、第3のループ処理lp3の外に移動してもよい。
この場合、情報処理装置100は、コードcd32として、コード「subject_p = (subject_t*)&Class[i][c].members[temp];」を挿入する。そして、情報処理装置100は、コードcd22(図22)をコード「subject_p->math = 0;」に置換し、コードcd23(図22)をコード「subject_p->eng = 0;」に置換する。
この場合についても同様にして、第3のループ処理lp3における、アドレスp21〜p24の算出工程を省略可能になり、アドレスの演算処理を大幅に抑制することが可能になる。
(サイクル数)
図24は、ソースファイルca−1(図22)に対応するプログラムの実行にかかるサイクル数と、最適化後ソースファイルcb−1(図23)に対応するプログラムの実行にかかるサイクル数を表す図である。
図24に示すように、図22に示すソースファイルcaに対応するプログラムの実行にかかるサイクル数は、例えば、式「13+2*{4+{8*(4+(40*13))}}」にしたがって算出した値「8405Cycle」となる。一方、図23に示す、最適後のソースファイルcaに対応するプログラムの実行にかかるサイクル数は、例えば、式「13+2*{4+{8*(3+(4+(40*7)))}}」にしたがって算出した値「4613Cycle」となる。
このように、図3と同様にして、アクセス処理を含むループ処理lp3内でメンバを有する構造体のアドレスが変化しない場合についても、サイクル数は大幅に減少する。
[別のソースコードの例2]
図25は、別の最適化対象のソースコードを含むソースファイルca−2の例を示す図である。図1は、図20のフローチャート図の工程S83において、値「Class[i][c]」のアドレス(&Class[i][c])が、第2のループ処理lp2毎に変化する場合を例示した。これに対し、図25は、アドレス「&Class[i][c]」が、第2のループ処理lp2の毎に変化しない場合を例示する。
図25のソースコードのコードcd41によると、第2のループ処理lp2のカウンタ変数は、変数「x」である。したがって、第2のループ処理lp2の度に、値「c」は変化しないため、アドレス「&Class[i][c]」も変化しない。
図26は、本実施の形態における情報処理装置100が、図25に示すソースファイルca−2を最適化した後の、ソースファイルcb−2の例を示す。情報処理装置100は、コードcd51、cd52をソースコードに挿入するともに、コードcd42、cd43(図25)を、コードcd53、cd54に置換する。コードcd51〜cd54は、図3に示すコードcd11〜cd14と同様である。
図26の例によると、情報処理装置100は、ポインタ変数にアドレス「&Class[i][c]」をセットするコードcd52を、第2、第3のループ処理lp2、lp3の前に挿入する。つまり、情報処理装置100は、アドレスp1〜p14の演算処理を、第3のループ処理lp3に加えて、第2のループ処理lp2の外に移動する。
第1のループ処理lp1のループ回数は、第2のループ処理lp2のループ回数に対して少ない。したがって、アドレスの演算処理を行うコードcd52を、さらに、第2のループ処理lp2の外に移動することにより、アドレスの演算処理の回数をさらに削減可能になる。これにより、これにより、コード修正モジュール124は、最適化後のソースコードに対応するプログラムのサイクル数を、さらに、削減することができる。
[別のソースコードの例3]
上記の実施の形態では、メンバを有する構造体のアドレス計算を省略する場合を例示した。本実施の形態における最適化処理は、複数のメンバを有する配列に対しても適用可能である。
図27は、別の最適化対象のソースコードを含むソースファイルca−3の例を示す図である。図1は、構造体のメンバにアクセスする処理を有するソースファイルcaを例示した。これに対し、図27は、配列のメンバにアクセスする処理を有するソースファイルca−3を例示する。
図27に示すコードcd61は、二次元配列「members[i][c]」のメンバに値「0」をセットする処理を示す。コードcd61の処理は、値「members[i][0]」のアドレスの算出工程を有する。
図28は、本実施の形態における情報処理装置が、図27に示すソースファイルca−3を最適化した後の、ソースファイルcb−3の例を示す。情報処理装置100は、コードcd71、cd72をソースコードに挿入するともに、コードcd61を、コードcd73に置換する。
コードcd71は、ポインタ変数「plist」を宣言する処理を示し、コードcd72は、ポインタ変数「plist」に、値「members[i][0]」のアドレスをセットする処理を示す。また、コードcd73は、ポインタ変数「plist」に基づいて、メンバ「members[i][c]」にアクセスするコードを示す。
図28に示すソースコードによると、コードcd73の実行の度に、値「members[i][0]」のアドレスの算出工程を省略可能になる。繰り返し行うループ処理内の、アドレスの演算処理の発生を抑制することにより、プログラム実行時の処理量が大幅に減少し、プログラムの実行にかかるサイクル数を大幅に削減可能になる。このように、本実施の形態における最適化処理は、メンバを有する配列に対しても適用可能である。
なお、本実施の形態では、ループ処理として、for文を例示している。ただし、この例に限定されるものではない。ループ処理は、while文やdo文等の別のループ処理を含んでいてもよい。本実施の形態における最適化処理は、for文以外のループ処理に対しても適用可能である。
以上の実施の形態をまとめると、次の付記のとおりである。
(付記1)
ソースコードから、ループ処理内でアクセス対象となるメンバを有する構造体または配列を検出する検出部と、
ポインタ変数を宣言する第1のコード、及び、前記構造体または前記配列のアドレスを前記ポインタ変数にセットする第2のコードを、前記ソースコードの前記ループ処理の前に挿入し、前記ループ処理内の、前記メンバにアクセスするコードを、前記ポインタ変数に基づいて前記メンバにアクセスする第3のコードに置換する編集部と、
を有するプログラムの最適化装置。
(付記2)
付記1において、
前記編集部は、前記ループ処理の度に前記アドレスが変化しない前記構造体または前記配列のアドレスを、前記ポインタ変数にセットする第2のコードを挿入する、
プログラムの最適化装置。
(付記3)
付記1または2において、
前記編集部は、前記ループ処理が別のループ処理に含まれ、当該別のループ処理内で前記構造体または前記配列の前記アドレスが変化する場合に、前記第1、第2のコードを、前記ループ処理の前であって前記別のループ処理内に挿入し、前記別のループ処理内で前記アドレスが変化しない場合に、前記第1、第2のコードを、前記ループ処理及び前記別のループ処理の前に挿入する、
プログラムの最適化装置。
(付記4)
付記1乃至3のいずれかにおいて、
前記検出部は、ループ回数が所定値を超える前記ループ処理内でアクセス対象となる、前記メンバを有する前記構造体または前記配列を検出する、
プログラムの最適化装置。
(付記5)
付記4において、
前記ループ回数は、前記ループ処理が別のループ処理に含まれる場合、前記ループ処理の第1のループ回数と、前記別のループ処理の第2のループ回数との積を示す、
プログラムの最適化装置。
(付記6)
付記1乃至5のいずれかにおいて、
前記構造体は、多次元構造体を含む、
プログラムの最適化装置。
(付記7)
付記1乃至5のいずれかにおいて、
前記配列は、二次配列を含む、
プログラムの最適化装置。
(付記8)
ソースコードから、ループ処理内でアクセス対象となるメンバを有する構造体または配列を検出し、
ポインタ変数を宣言する第1のコード、及び、前記構造体または前記配列のアドレスを前記ポインタ変数にセットする第2のコードを、前記ソースコードの前記ループ処理の前に挿入し、
前記ループ処理内の、前記メンバにアクセスするコードを、前記ポインタ変数に基づいて前記メンバにアクセスする第3のコードに置換する、
ことを実行させることを特徴とする最適化プログラム。
(付記9)
付記8において、
前記挿入は、前記ループ処理の度に前記アドレスが変化しない前記構造体または前記配列のアドレスを、前記ポインタ変数にセットする第2のコードを挿入する、
最適化プログラム。
(付記10)
付記8または9において、
前記挿入は、前記ループ処理が別のループ処理に含まれ、当該別のループ処理内で前記構造体または前記配列の前記アドレスが変化する場合に、前記第1、第2のコードを、前記ループ処理の前であって前記別のループ処理内に挿入し、前記別のループ処理内で前記アドレスが変化しない場合に、前記第1、第2のコードを、前記ループ処理及び前記別のループ処理の前に挿入する、
最適化プログラム。
(付記11)
付記8乃至10のいずれかにおいて、
前記検出は、ループ回数が所定値を超える前記ループ処理内でアクセス対象となる、前記メンバを有する前記構造体または前記配列を検出する、
最適化プログラム。
(付記12)
付記11において、
前記ループ回数は、前記ループ処理が別のループ処理に含まれる場合、前記ループ処理の第1のループ回数と、前記別のループ処理の第2のループ回数との積を示す、
最適化プログラム。
(付記13)
付記8乃至12のいずれかにおいて、
前記構造体は、多次元構造体を含む、
最適化プログラム。
(付記14)
付記8乃至12のいずれかにおいて、
前記配列は、二次配列を含む、
最適化プログラム。
(付記15)
処理部が、ソースコードから、ループ処理内でアクセス対象となるメンバを有する構造体または配列を検出し、
処理部が、ポインタ変数を宣言する第1のコード、及び、前記構造体または前記配列のアドレスを、前記ポインタ変数にセットする第2のコードを前記ソースコードの前記ループ処理の前に挿入し、前記ループ処理内の、前記メンバにアクセスするコードを、前記ポインタ変数に基づいて前記メンバにアクセスする第3のコードに置換し、
処理部が、前記挿入及び前記置換後のソースコードをコンパイルする、
最適化されたプログラムの製造方法。
(付記16)
付記15において、
前記挿入は、前記ループ処理の度に前記アドレスが変化しない前記構造体または前記配列のアドレスを、前記ポインタ変数にセットする第2のコードを挿入する、
最適化されたプログラムの製造方法。
(付記17)
付記15または16において、
前記挿入は、前記ループ処理が別のループ処理に含まれ、当該別のループ処理内で前記構造体または前記配列の前記アドレスが変化する場合に、前記第1、第2のコードを、前記ループ処理の前であって前記別のループ処理内に挿入し、前記別のループ処理内で前記アドレスが変化しない場合に、前記第1、第2のコードを、前記ループ処理及び前記別のループ処理の前に挿入する、
最適化されたプログラムの製造方法。
(付記18)
付記15乃至17のいずれかにおいて、
前記検出は、ループ回数が所定値を超える前記ループ処理内でアクセス対象となる、前記メンバを有する前記構造体または前記配列を検出する、
最適化されたプログラムの製造方法。
(付記19)
付記18において、
前記ループ回数は、前記ループ処理が別のループ処理に含まれる場合、前記ループ処理の第1のループ回数と、前記別のループ処理の第2のループ回数との積を示す、
最適化されたプログラムの製造方法。
(付記20)
付記15乃至19のいずれかにおいて、
前記構造体は、多次元構造体を含む、
最適化されたプログラムの製造方法。
(付記21)
付記15乃至19のいずれかにおいて、
前記配列は、二次配列を含む、
最適化されたプログラムの製造方法。