JPWO2009004709A1 - 間接分岐処理プログラムおよび間接分岐処理方法 - Google Patents

間接分岐処理プログラムおよび間接分岐処理方法 Download PDF

Info

Publication number
JPWO2009004709A1
JPWO2009004709A1 JP2009521463A JP2009521463A JPWO2009004709A1 JP WO2009004709 A1 JPWO2009004709 A1 JP WO2009004709A1 JP 2009521463 A JP2009521463 A JP 2009521463A JP 2009521463 A JP2009521463 A JP 2009521463A JP WO2009004709 A1 JPWO2009004709 A1 JP WO2009004709A1
Authority
JP
Japan
Prior art keywords
instruction
indirect branch
branch
processing
indirect
Prior art date
Legal status (The legal status is an assumption and is not a legal conclusion. Google has not performed a legal analysis and makes no representation as to the accuracy of the status listed.)
Pending
Application number
JP2009521463A
Other languages
English (en)
Inventor
隆志 豊島
隆志 豊島
青木 孝
孝 青木
Current Assignee (The listed assignees may be inaccurate. Google has not performed a legal analysis and makes no representation or warranty as to the accuracy of the list.)
Fujitsu Ltd
Original Assignee
Fujitsu Ltd
Priority date (The priority date is an assumption and is not a legal conclusion. Google has not performed a legal analysis and makes no representation as to the accuracy of the date listed.)
Filing date
Publication date
Application filed by Fujitsu Ltd filed Critical Fujitsu Ltd
Publication of JPWO2009004709A1 publication Critical patent/JPWO2009004709A1/ja
Pending legal-status Critical Current

Links

Images

Classifications

    • GPHYSICS
    • G06COMPUTING; CALCULATING OR COUNTING
    • G06FELECTRIC DIGITAL DATA PROCESSING
    • G06F9/00Arrangements for program control, e.g. control units
    • G06F9/06Arrangements for program control, e.g. control units using stored programs, i.e. using an internal store of processing equipment to receive or retain programs
    • G06F9/30Arrangements for executing machine instructions, e.g. instruction decode
    • G06F9/38Concurrent instruction execution, e.g. pipeline, look ahead
    • G06F9/3836Instruction issuing, e.g. dynamic instruction scheduling or out of order instruction execution
    • G06F9/3842Speculative instruction execution
    • G06F9/3844Speculative instruction execution using dynamic branch prediction, e.g. using branch history tables
    • GPHYSICS
    • G06COMPUTING; CALCULATING OR COUNTING
    • G06FELECTRIC DIGITAL DATA PROCESSING
    • G06F8/00Arrangements for software engineering
    • G06F8/40Transformation of program code
    • G06F8/41Compilation
    • G06F8/44Encoding
    • G06F8/443Optimisation
    • G06F8/4441Reducing the execution time required by the program code
    • G06F8/4442Reducing the number of cache misses; Data prefetching
    • GPHYSICS
    • G06COMPUTING; CALCULATING OR COUNTING
    • G06FELECTRIC DIGITAL DATA PROCESSING
    • G06F9/00Arrangements for program control, e.g. control units
    • G06F9/06Arrangements for program control, e.g. control units using stored programs, i.e. using an internal store of processing equipment to receive or retain programs
    • G06F9/30Arrangements for executing machine instructions, e.g. instruction decode
    • G06F9/30003Arrangements for executing specific machine instructions
    • G06F9/3005Arrangements for executing specific machine instructions to perform operations for flow control
    • G06F9/30061Multi-way branch instructions, e.g. CASE
    • GPHYSICS
    • G06COMPUTING; CALCULATING OR COUNTING
    • G06FELECTRIC DIGITAL DATA PROCESSING
    • G06F9/00Arrangements for program control, e.g. control units
    • G06F9/06Arrangements for program control, e.g. control units using stored programs, i.e. using an internal store of processing equipment to receive or retain programs
    • G06F9/30Arrangements for executing machine instructions, e.g. instruction decode
    • G06F9/32Address formation of the next instruction, e.g. by incrementing the instruction counter
    • G06F9/322Address formation of the next instruction, e.g. by incrementing the instruction counter for non-sequential address
    • GPHYSICS
    • G06COMPUTING; CALCULATING OR COUNTING
    • G06FELECTRIC DIGITAL DATA PROCESSING
    • G06F9/00Arrangements for program control, e.g. control units
    • G06F9/06Arrangements for program control, e.g. control units using stored programs, i.e. using an internal store of processing equipment to receive or retain programs
    • G06F9/30Arrangements for executing machine instructions, e.g. instruction decode
    • G06F9/38Concurrent instruction execution, e.g. pipeline, look ahead
    • G06F9/3802Instruction prefetching
    • G06F9/3804Instruction prefetching for branches, e.g. hedging, branch folding
    • G06F9/3806Instruction prefetching for branches, e.g. hedging, branch folding using address prediction, e.g. return stack, branch history buffer

Landscapes

  • Engineering & Computer Science (AREA)
  • Theoretical Computer Science (AREA)
  • Software Systems (AREA)
  • General Engineering & Computer Science (AREA)
  • Physics & Mathematics (AREA)
  • General Physics & Mathematics (AREA)
  • Advance Control (AREA)
  • Devices For Executing Special Programs (AREA)

Abstract

プロセッサ100は、インタプリタプログラム200aを読み出してインタプリタを起動し、インタプリタは、ソースプログラム200bを実行する場合に必要となる間接分岐命令の代わりに、間接分岐命令の分岐先のアドレスを逆順にリンクレジスタ120c(プロセッサ100の内部的には、リターン・アドレス・スタック130にも分岐先のアドレスが積まれる)に格納し、リターン・アドレス・スタック130からアドレスを順次読み出して分岐予測を行う。

Description

本発明は、間接分岐命令の代わりに擬似的な間接分岐命令をコンピュータに実行させる間接分岐処理プログラムおよび間接分岐処理方法に関するものである。
従来より、計算機(CPU(Central Processing Unit)等)は、コンパイル方式あるいはインタプリタ方式によって人間により記述されたソースプログラムを実行している。コンパイル方式は、ソースプログラムをコンパイラと呼ばれる変換プログラムにより計算機上で実行できるバイナリ形式に変換した後に、バイナリ形式に変換したコードを実行する方式であり、インタプリタ方式は、インタプリタと呼ばれる特別なバイナリコードを計算機上で実行し、インタプリタがソースプログラムを逐次解釈しながら内容に応じた処理を随時行う方式である。
ところで、近年では、計算機の処理を高速化するために、計算機をスーパースカラと呼ばれる方式に基づいて設計している。この方式では、パイプライン方式で処理を行うことを前提としている。パイプライン方式では、各命令処理が複数のステージに分割され、それぞれのステージが個別のユニットにより処理される。そのため、次に実行すべき命令が確定していれば、先行命令の第二ステージの実行と並行して、後続命令の第一ステージを実行することができ、分割したステージの数だけ並列動作による高速な実行が可能となる。
ここで、パイプライン処理が巧く機能する条件として、次に実行すべき命令が確定しているという条件が存在する。つまり、命令1の次に実行すべき命令2(命令が命令1、命令2、命令3・・・の順で実行される場合)が、命令1の第1ステージの実行が完了するまでに確定していない時、次の命令2の処理を並列して実行することができない(命令2に続く命令も同様である)。
このような状態が発生する代表的な例が、分岐命令である。分岐命令においては、直前の分岐条件判定命令(例えば、比較命令)の結果が判明するまで、次に処理するべき命令が確定せず、パイプライン処理を行うことができないため、計算機全体の処理速度が大幅に低下してしまう。
パイプライン処理の性能低下を防止するために、分岐予測と呼ばれる技術が考案され実用化されている。かかる分岐予測の原理としては、過去に実行したプログラムの分岐結果を履歴に残しておき、その延長線上で分岐結果を予測するというアイデアが基本となっている(例えば、非特許文献1参照)。
また、分岐命令には、通常の分岐命令だけではなく、レジスタに記憶されたアドレスを基にして分岐する間接分岐命令も存在する。間接分岐命令は、上述したインタプリタを実装する際などに頻繁に利用されている。しかし、間接分岐命令は、スーパースカラ方式の計算機においてコストの高い命令となっているため、間接分岐命令に焦点を当てた予測手法の研究も行われている(例えば、非特許文献2、非特許文献3参照)。
なお、特許文献1では、狭いアドレス空間のみを取り扱うプロセッサ用に書かれたコードを、間接コールを用いずに広いアドレス空間を取り扱うプロセッサに適用する技術が示されている。
John L. Hennessy, and David A. Patterson. "Computer Architecture-A Quantitative Approach 3rd Edition," MORGAN KAUFMANN PUBLISHERS, ISBN 1-55860-724-2. P.-Y. Chang, E. Hao, and Y. N. Patt. "Target Prediction for Indirect Jumps", In Proceedings of 24th International Symposium on Computer Architecture, pp. 274~283, 1997. K. Driesen and U. HAolzle. "Accurate Indirect Branch Prediction", In Proceedings of 25th International Symposium on Computer Architecture, pp. 167~178, 1998. 特開2000−284965号公報
しかしながら、上述した従来の技術では、プログラム中に記載されたある間接分岐命令の次にどの命令が実行されるかを履歴から予測しても、予測した命令と実際に次に実行される命令が一致する確率が低いという問題があった。
実行のたびに異なる分岐先を持つような間接分岐命令に対しては、非特許文献2および非特許文献3の技術を利用したとしても、精度のよい予測を行うことができず、間接分岐命令は、スーパースカラ方式によってプログラムを実行する計算機にとって依然、コストの高い命令となっている。
本発明は、上記に鑑みてなされたものであって、分岐予測を精度よく行うことができる間接分岐処理プログラムおよび間接分岐処理方法を提供することを目的とする。
上述した課題を解決し、目的を達成するために、コンピュータ上のインタプリタに、記憶装置に記憶されたソースプログラムを読み込む読込手順と、前記ソースプログラムを解釈し、内容にあったインタプリタ内の処理コードを選択する手順と、前記コード選択手順によって選択された処理コードを呼び出す手順を実行させるが、当該インタプリタは、前記処理コード選択、呼び出し手順において、選択したコードに分岐するために、間接分岐命令を利用する代わりに、選択したコードのアドレスを処理の順序とは逆順にコールスタックに格納し、疑似的な間接分岐命令によって呼び出し処理を行う。
また、本発明は、上記発明において、前記処理コード呼び出し手順の、汎用レジスタに記憶された分岐先のアドレスに処理を移行させる間接分岐命令を、前記コールスタックに分岐先のアドレスを格納し、そのアドレスに処理を移行させる命令で代用した擬似間接分岐コードで代用することを特徴とする。
また、本発明は、上記発明において、前記コンピュータに搭載された所定のスタック、またはリンクレジスタに間接分岐命令の分岐先のアドレスを格納することで、間接的に計算機内部の復帰アドレス予測テーブルを更新し、疑似的な間接分岐を処理する際に分岐予測を成功させることを特徴とする。
また、本発明は、上記発明において、前記ソースプログラムには、処理の分岐を伴う制御文が記述されており、前記インタプリタ内の擬似間接分岐コードは、前記制御文の条件判定部が記述されるまでの区間ごとに前記処理コードのアドレスを逆順にコールスタックに格納する命令を含んでいることを特徴とする。
本発明によれば、コンピュータに、記憶装置に記憶されたソースプログラムを読み込む読込手順と、ソースプログラムを解釈し、内容にあったインタプリタ内の処理コードを選択する手順と、コード選択手順によって選択された処理コードを呼び出す手順と、を実行させ、この処理により、間接的に計算機内部の復帰アドレス予測テーブルを更新し、処理コード呼び出し手順の際には、この予測テーブルを用いて分岐予測が行われるので、分岐予測を精度よく行うことができ、分岐によるペナルティなしに任意のアドレスへの分岐を完了することができる。結果、間接分岐命令に相当する処理を数倍〜数十倍高速に実行することができる。
また、本発明によれば、コンピュータに実行させるコードの呼び出し手順において、汎用レジスタに記憶された分岐先のアドレスに処理を移行させる間接分岐命令を、前記コールスタックに岐先のアドレスを格納し、そのアドレスに処理を移行させる命令で代用した擬似間接分岐コードで代用するので、ソースプログラムを実行するコンピュータの処理性能を向上させることができる。
また、本発明によれば、コンピュータに搭載された所定のスタック、またはリンクレジスタに間接分岐命令の分岐先のアドレスを逆順に格納することで、間接的に計算機内部の復帰アドレス予測テーブルを更新し、疑似的な間接分岐を処理する際に分岐予測を成功させるので、コンピュータの分岐予測の精度を向上させ、ソースプログラムを実行するコンピュータの処理性能を向上させることができる。
また、本発明によれば、ソースプログラムには、処理の分岐を行う制御文が記述されており、インタプリタ内の擬似間接分岐コードは、制御文の条件判定部が記載されるまでの区間ごとに前記間接分岐命令の分岐先のアドレスを逆順にコールスタックに格納する命令を含んでいるため、より効率よく高速に擬似間接分岐を実行することができる。
図1は、分岐処理を説明するための図である。 図2は、複数の分岐処理と間接分岐処理とを説明するための図である。 図3は、コンパイル方式とインタプリタ方式との違いを説明するための図である。 図4は、従来のインタプリタの処理を示すフローチャートである。 図5は、パイプライン処理を説明するための図である。 図6は、関数呼び出しの様子を説明するための図である。 図7は、間接分岐命令を用いるインタプリタの一例を示す図である。 図8は、擬似的な間接命令を用いるインタプリタの一例を示す図である。 図9は、本実施例1にかかるプロセッサの構成を示す機能ブロック図である。 図10は、複数の間接分岐命令を実行するインタプリタの一例を示す図である。 図11は、図10に示した「call %r6」と等価のプログラムを示す図である。 図12は、複数の擬似的な間接分岐命令を実行するインタプリタの一例を示す図である。 図13は、インタプリタの処理手順を示すフローチャート(1)である 図14は、インタプリタの処理手順を示すフローチャート(2)である。 図15は、本実施例3にかかるプロセッサの構成を示す機能ブロック図である。
符号の説明
100,300 プロセッサ
110,310 メモリアクセス制御部
120,320 レジスタ
120a,320a 汎用レジスタ群
120b,320b プログラムカウンタ
120c,320c リンクレジスタ
130,330 リターン・アドレス・スタック
140,340 分岐予測部
150,350 デコード・制御部
160,360 演算パイプライン部
200,400 メインメモリ
200a インタプリタプログラム
200b,400b ソースプログラム
400c 擬似間接分岐プログラム
200c,400d 退避データ
400a コンパイラプログラム
以下に、本発明にかかる間接分岐処理プログラムおよび間接分岐処理方法の実施例を図面に基づいて詳細に説明する。なお、この実施例によりこの発明が限定されるものではない。
まず、本願発明にかかる実施例の説明を行う前に、本願発明に関わる従来の技術(間接分岐命令、インタプリタ方式およびコンパイル方式、スーパースカラプロセッサとパイプライン処理、分岐予測、関数からの復帰処理、リターン・アドレス・スタック、ハードウェアによるインタプリタ支援、Just In Timeコンパイル方式)について順に説明する。
(間接分岐命令)
CPU(Central Processing Unit)等の計算機上で動作するプログラムについて、途中結果に応じて異なる処理を行うために分岐と呼ばれる命令が用いられる。計算機システムにおいて、プログラムはメモリ上に順に配置され、配置された順に従い、計算機により逐次実行される。図1は、分岐処理を説明するための図である。実行が分岐命令に差し掛かると、直前の条件判定結果において特定の条件を満たした場合に、次に処理すべき命令アドレスを指定されたメモリアドレスに変更する(図1では、条件に応じて、処理3あるいは処理5に移行することとなる)。この条件判定命令あるいは分岐命令においては、メモリアドレスや条件は、命令の一部として符号化された固定値である。
一方、条件に応じて複数の分岐先へ処理を移したい場合が存在する。図2は、複数の分岐処理と間接分岐処理とを説明するための図である。図2の左側に示すように、条件判定と分岐を必要な種類だけ並べて実現する事もできるが、多くの条件判定を伴う分岐は効率が悪い。そこで用いられるのが間接分岐命令と呼ばれる処理である。この処理では、次に実行すべきアドレスとしてレジスタの値が用いられる。即ち、過去の計算結果そのものを次の命令アドレスとして指定できる。これにより、プログラム自身で分岐先命令アドレスを計算し、その値により間接分岐を行う事が可能となり、任意の処理への分岐が実現できる(図2の右側参照)。
(インタプリタ方式およびコンパイル方式)
計算機上で動作するプログラムの実行方式には、大きく分けて2つの方式が存在する。1つがコンパイル方式であり、もう1つがこのインタプリタ方式である。コンパイル方式においては、ソースファイルに記述されたプログラムを、事前にコンパイラにより実行バイナリに変換する必要がある。このコンパイラにより変換された実行バイナリは、計算機上で直接実行される。
一方、インタプリタ方式において計算機上で直接実行されるのは、インタプリタと呼ばれるソフトウェアである。インタプリタは、ソースファイルを逐次解釈しながら、プログラム記述に沿った処理を行う。このため、コンパイル方式に比べ、プログラムの処理には時間がかかる。しかしその一方で、異なる設計の計算機システムにおいても、共通仕様のインタプリタが存在すれば、同一のプログラムをそのまま利用する事が可能というメリットも存在する。
図3は、コンパイル方式とインタプリタ方式との違いを説明するための図である。図3の左側に示すように、インタプリタ方式では、ハードウェア上で直接動作するのは基本ソフトとインタプリタであり、インタプリタは、基本ソフトの機能を利用しながら動作する。プログラムはこのインタプリタ上で解釈・実行される。一方、図3の右側に示すように、コンパイル方式ではプログラムはコンパイルされ、実行ファイルに変換される。実行ファイルは基本ソフトの機能を利用しながら、直接ハードウェアで実行される。
インタプリタは、それ自身1つのソフトウェアとして記述されている。インタプリタの基本動作は、プログラムを逐次解釈し、その内容に応じた処理を行う事の繰り返しである。図4は、従来のインタプリタの処理を示すフローチャートである。ここで注目したいのが、中央にある分岐処理「命令に応じた処理へ分岐」である。この分岐は、図4からもわかる通り複数の処理へ分岐する必要があり(例えば、処理A、処理B、・・・処理Y、処理Zのいずれかに分岐する必要があり)、この分岐としては間接分岐を用いる必要がある。よって、インタプリタの動作速度は、この間接分岐の処理効率に大きく左右される事になる。
(スーパースカラプロセッサとパイプライン処理)
現在の高性能計算機は、内部はスーパースカラと呼ばれる方式に基づいて設計されている。この方式ではパイプライン方式で処理を行う事を前提としており、パイプライン方式では各命令の処理は複数のステージに分割され、それぞれのステージが個別のユニットにより処理される。
図5は、パイプライン処理を説明するための図である。図5における横軸が時間の流れを示し、縦軸が命令の流れを示す。図5に示す例では、命令処理をIF、ID、EX、MEM、WBと5つのステージに分割している。最新のプロセッサでは、このステージ数が増加する傾向にあり、十数段のステージに分割されている事も稀ではない。
さて、IFを処理するユニット(IFユニット)について考える。このIFユニットでは、特定の命令のIFに該当する処理を行い、結果を次のIDユニットに引き渡す。よって、次のサイクルにおいてIDの処理が行われている際には、IFユニットが命令に対して行うべき処理はない。同様にして次のサイクルではEXユニットが処理を行い、IFユニット、IDユニットの行うべき処理はない。
これを利用して、次のサイクルではIFユニットは次の命令のIF処理を行うようにする。このようにして後続する命令の処理を平行して分割実行する事で、1つの命令の処理の完了まで5サイクルかかっていたとしても、長い時間で見ると、平均して1サイクル毎に1つの命令の処理が完了する事になる。このようにNサイクルかかる処理を分割・並列実行する事で見かけ上の処理時間を1サイクルにするような技術をパイプライン技術と呼ぶ。
ただし、このパイプライン処理が巧く機能する条件として、次に実行すべき命令が確定している、という条件が存在する。つまり、命令1の次に実行すべき命令が、命令1の実行が完了するまで確定していない時、次の命令の処理を並列して開始する事ができない。このような状態が発生する代表的な例が、分岐命令である。
分岐命令においては、直前の条件判定命令の結果が判明するまで、次に処理するべき命令が確定しない。このため、パイプライン処理を行う事ができずに、全体として性能が大きく低下してしまう。これを回避するための技術が分岐予測と呼ばれる技術である。分岐予測に関する詳しい説明は後述するが、簡単に説明すると、これは条件判定結果をあらかじめ予測し、分岐命令の時点で比較結果が確定していない時にも、この予測に基づき次に実行すべき命令を推測し、その推測に従って処理を進める方式である。
この方式を用いれば、予測の精度が十分に高い場合に、分岐による性能低下はなくなる。また、予測がはずれた場合には、それ以降の命令処理を破棄し、仮定に基づき実行した命令が処理される前の状態に巻き戻した上で、正しい命令列を改めて実行しなおす事で、実行結果に影響は与えない。スーパースカラプロセッサに関する詳細は文献[2](Mike Johnson. “Superscalar Microprocessor Design,” Prentice-Hallm Inc, ISBN 0138756341.)に記載されており、計算機全般に関する技術の詳細は文献[1](John L. Hennessy, and David A. Patterson. “Computer Architecture-A Quantitative Approach 3rd Edition,” MORGAN KAUFMANN PUBLISHERS, ISBN 1-55860-724-2.)に記載されている。
(分岐予測)
上記の「スーパースカラプロセッサとパイプライン処理」の節で述べた通り、精度の良い分岐予測を行うことは、スーパースカラ方式の計算機にとって重要な課題である。しかし、予測は条件判定結果に先立って、即座に行う事ができないと意味がなく、またハードウェアとして実装するため、大規模なデータベースを用いた予測なども行えない。よって、限られた資源でなるべく精度の高い予測が行えるよう工夫がなされている。
分岐予測の原理としては、過去の分岐結果を記憶しておき、その延長線上で分岐結果を予想するというアイデアが基本となっている。過去数回の分岐結果を命令毎に記憶しておき、過去の分岐傾向に従い予測するだけの単純な予測で、90%以上の精度で予測が当たるとされている。
ただし、実際には全ての分岐命令に対し個別の履歴を用意する事は難しく、分岐命令の命令アドレスの下位ビットをインデックスとして履歴を参照する方法が用いられる。この場合、運が悪い時には複数の分岐命令で同じ履歴を共有してしまい、正しく予測が行えない。
また、精度向上の工夫として、分岐間の相関を利用する方法がある。これは、特定の分岐結果は、その分岐命令に至るまでに通過した分岐命令の結果と相関関係がある事を利用している。これらは広域分岐予測と呼ばれ、95%前後の制度で予測する事が可能となる。さらには複数の予測機構を組み合わせて使うなど、様々な工夫により分岐予測精度の向上が図られている。予測機構については、文献[1]の3.4節以降に詳しく説明されている。また、ウィキペディア日本語版「分岐予測」の項[3]にも分岐予測の説明がなされている(“分岐予測”、ウィキペディア日本語版,http://ja.wikipedia.org/を参照)。
一方、これらの分岐予測手法は通常の分岐命令だけに焦点をあてた方法である。つまり複数の分岐先を持つような間接分岐命令に対しては、有効な予測手段を提供していない。間接分岐に焦点を当てた予測手法の研究は文献[4](P.-Y. Chang, E. Hao, and Y. N. Patt. “Target Prediction for Indirect Jumps”, In Proceedings of 24th International Symposium on Computer Architecture, pp. 274~283, 1997.)および文献[5](K. Driesen and U. HAolzle. “Accurate Indirect Branch Prediction”, In Proceedings of 25th International Symposium on Computer Architecture, pp. 167~178, 1998.)などが存在する。
また、商用プロセッサにおいてはIntel(R) Pentium(R) Mが間接分岐予測器を搭載したプロセッサとして存在する。この予測の仕組みについては例えば、文献[6](S. Gochman, R. Ronen, I. Anati, A. Berkovits, T. Kurts, A. Naveh, A. Saeed, Z. Sperber, and R. C. Valentine. “The Intel Pentium M Processor: Microarchitecture and Performance”, Intel Technology Journal, 7(2):21~36, 2003.)に記述されている。
また、分岐予測以外にもコンパイラと協調して分岐先アドレスをフォワーディングし、予測しなくてもペナルティが発生しない手法も研究されている(文献[7](豊島隆志、入江英嗣、五島正裕、and坂井修一.“レジスタ間接分岐ターゲット・フォワーディング”, SACSIS 2006))。しかしながら、間接分岐を考慮した予測機構を備えた商用プロセッサは少なく、また搭載されていたとしても、通常の分岐命令に比べ精度の良い予測を行うことはできていない。従って、間接分岐命令は、スーパースカラ方式のプロセッサにとって、コストの高い命令となっている。
(関数からの復帰処理)
特殊な形式の分岐を必要とする処理に「関数呼び出し」機能が挙げられる。図6は、関数呼び出しの様子を説明するための図である。同図に示す例では、メインの処理から関数Aが、関数Aから関数Bが呼び出される様子を示している。図6からもわかるように関数Aはメイン処理の複数の箇所から呼び出される。
一般に関数は、プログラム中のいずれの場所からも呼び出し可能であり、関数の実行が終了した際に移る次の処理というのは、呼び出し元箇所の次の命令となる。つまり、関数から戻る際には、複数の分岐先を持った分岐処理を行う必要がある。このために特殊な命令が用意されている事が多く、一般的には復帰命令(リターン命令)と呼ばれる命令が定義されている。
リターン命令は、それに対応するリンク処理が必要とされる。多くの計算機においては、関数を呼び出す際に、「Jump and Link」と呼ばれるリンク付き分岐命令を用いる。これは分岐と同時に現在実行中の命令アドレスを特定の場所に退避する命令である。復帰命令が呼ばれた際には、この時に退避された命令アドレスを用いて、呼び出し元のアドレスを特定し、呼び出し元に再分岐する。関数は入れ子状で呼び出されるため、この退避場所はスタック構造を持つ資源に格納される事が多い。あるいは特定の場所に一時退避し、次のリンク処理により上書きされる前に、一時退避済みのアドレスをソフトウェア的に再退避する事で入れ子状の呼び出しにも対応している。
(リターン・アドレス・スタック)
上記のリンク処理と復帰処理は特定の命令により実施される事が多く、プロセッサ内部で関数の呼び出し、復帰箇所を特定する事ができる。プロセッサ内部では、この復帰処理にかかる分岐のコストを最小限にするため、復帰処理に特化した分岐予測機構を備えている事が多い。現在利用されている商用プロセッサにおいては、例外なくこの予測機構は搭載されている。
この機構はリターン・アドレス・スタックと呼ばれ、リンク時に呼び出し元を内部のリターン・アドレス・スタックに積み、復帰時にはこのスタックから降ろしたアドレスを用いて分岐予測を行う。このリターン・アドレス・スタックとは、プログラムから見える外部仕様的な戻りアドレス退避場所とは異なり、プロセッサ内部で予測のためだけに用いられる特殊な記憶領域である。リターン・アドレス・スタックについては、文献[8](C.F.Webb. Subroutine.“call/return stack”,IBM Technical Disclosure Bulletin, 30(11):18~20,1988.)の技術解説、あるいは文献[9](D.R.Kaeli and P.G.Emma.“Branch History Table Prediction of Moving Target Branches Due to Subroutine Returns”,In Proceedings of 18th International Symposium of Computer Architecture,pages 34~42,1991.)、文献[10](K.Skadron,P.S.Ahuja,M.Martonosi, and D. W.Clark.“Improving Prediction for Procedure Return with Return-Address-Stack Repair Mechanisms”,In Proceedings of 31st International Symposium on Microarchitecture,pages 259~271,1998.)などの研究結果がある。
(ハードウェアによるインタプリタ支援)
インタプリタを高速に実行するための仕組みとして、計算機上にハードウェア的な支援機構を設ける場合もある。このような例の1つがMIPS社によるSmartMIPS(R)(文献[11](MIPS Technologies Inc.“MIPS32(R) Architecture for Programmers Volume IV-d: The SmartMIPS(R) Application-Specific Extension to the MIPS32(R) Architecture”,Document Number: MD00101 Revision 2.50,July 1,2005.))である。
これはMIPS32(R)アーキテクチャ向けの拡張仕様の1つで、組み込み分野をターゲットとした仕様になっている。この拡張は大きく分けて、暗号向け演算アクセラレータ、命令密度の最適化、インタプリタ支援、そしてリソース保護の4本柱になっている。このうちインタプリタ支援については文献[11]の3.4.3節で概要が触れられ、具体的な命令についての説明は5.1節に記述されている。
この拡張では、インタプリタの最内ループ処理を可能な限り少ない命令数で実現できるようにCISC的な命令が定義されている。CISCとは、スーパースカラ登場以前に主流だった計算機の方式で、現在主流のRISC(Reduced Instruction Set Computers)とは対照的に1つ1つの命令が高機能である(Complex Instruction Setである)事が特徴となっている。CISCとRISCについては文献[1]の2.16節内に「Reduced Instruction Set Computers」と題されて解説されている。
(Just In Timeコンパイル方式)
インタプリタを高速に実装するためのソフトウェア側の工夫としてJust In Timeコンパイル方式と呼ばれる技術が存在する。この方式ではまずインタプリタとしての動作でプログラムを解釈・実行し、それと同時にプログラムの動作について簡単な統計情報を作成する。この統計情報によりHot Spot(頻繁に実行される箇所)と判断されたプログラム部分に関しては、その時点でプログラムの解釈をまとめて行い、計算機上で直接実行可能な命令列に変換する。
以降、その命令に該当する箇所に実行がさしかかると、インタプリタによる動作をやめ、変換後の直接実行可能な命令列に制御を移す。この方式は、インタプリタ方式とコンパイラ方式の折衷方式と考えることができ、コンパイルにかかる時間的なコストと、直接実行される事による高速化の効果を比較し、効果の方が十分大きい場合に限って用いる事が可能な技術と言える。また、高速化の効果はコンパイル時にどれだけ複雑な最適化を行うかにも影響しており、多くの面でトレード・オフが存在する。また、計算機の性能や広大なメモリを要求するため、この方式は一般的に大規模なシステム上で利用される事が多い。
続いて、本実施例1の説明を行う。まず、本実施例1にかかるプロセッサの概要および特徴について説明する。本実施例1にかかるインタプリタは、ソースプログラムを逐次実行する場合に、間接分岐命令が必要な状況であっても、間接分岐命令の代わりに擬似的な間接分岐命令を実行するように実装されている。
このように、本実施例1にかかるインタプリタは、ソースプログラムを実行する場合に、間接分岐命令が必要な状況であっても、間接分岐命令の代わりに擬似的な間接分岐命令を実行するので、インタプリタを実行しているプロセッサは、分岐予測を精度よく行うことができ、分岐によるペナルティなしに任意のアドレスへの分岐を完了することができる。結果、間接分岐命令に相当する処理を数倍〜数十倍高速に実行することができる。
なお、本実施例1では、インタプリタを用いて説明するが、これに限定されるものではなく、その他のプログラムによって代用することができる。
次に、間接分岐命令と、間接分岐命令の代わりとなる擬似的な間接分岐命令とを比較して説明する。図7は、間接分岐命令を用いるインタプリタの一例を示す図であり、図8は、擬似的な間接命令を用いるインタプリタの一例を示す図である。
図7において、「call %r6」が間接分岐命令に対応する。具体的に、「call %r6」の処理内容は、プログラムカウンタに格納されたアドレスをリンクレジスタに格納した後に、プロセッサに搭載された汎用レジスタ「r6」に格納された分岐先のアドレスに処理を移行するという内容である。レジスタ「r6」に記憶されるアドレスに応じて分岐先がかわるため間接分岐命令となる。かかる間接分岐命令では、汎用レジスタに格納される分岐先のアドレスが多岐にわたるため、分岐命令の次に実行すべき命令を精度よく実行することができなかった。
一方、図8の「move %link_reg=%r6」および「ret」が擬似的な間接分岐命令に対応する。すなわち、本実施例1のインタプリタは、図7に示したような間接分岐命令「call %r6」を用いる必要がある場合であっても、かかる間接分岐命令を用いる代わりに、図8に示したような擬似的な間接分岐命令「move %link_reg=%r6」、「ret」を用いる。
図8に示す「move %link_reg=%r6」の処理内容は、プロセッサに搭載された、分岐元のアドレスを格納するレジスタ(以下、リンクレジスタ)に汎用レジスタ「r6」に格納された分岐先のアドレスを移動させるという内容である。つづく「ret」は、リンクレジスタに格納された分岐元に復帰するための命令であるが、本実施例においては、分岐先のアドレスが格納されているため、分岐先のアドレスに処理を移行する。
ここで、リンクレジスタにアドレスを格納するたびに、プロセッサに搭載されたリターン・アドレス・スタック(リターン・アドレス・スタックに関する説明は上記の内容を参照)にアドレスが順に積まれていく。プロセッサは、リンク付き分岐命令を実行した後の復帰時にリターン・アドレス・スタックに積まれた分岐先のアドレスを抽出する(新しく積まれた順にアドレスを抽出する)ことによって、精度よく復帰先のアドレスを予測することができる。
次に、本実施例1にかかるプロセッサの構成(構成の一例)について説明する。図9は、本実施例1にかかるプロセッサの構成を示す機能ブロック図である。同図に示すように、このプロセッサ100は、メモリアクセス制御部110と、レジスタ120と、リターン・アドレス・スタック130と、分岐予測部140と、デコード・制御部150と、演算パイプライン部160とを備えて構成される。
また、プロセッサ100は、各種のデータおよびプログラムを記憶するメインメモリ200に接続され、メインメモリ200に記憶された各種データ・プログラムを読み出して各種の処理を逐次実行する。
メインメモリ200は、各種のデータおよびプログラムを記憶する記憶装置であり、特に本発明に密接に関連するものとしては、インタプリタプログラム200a、ソースプログラム200b、退避データ200cを記憶している。
このうち、インタプリタプログラム200aは、ソースプログラム200bを逐次読み出して実行するためのプログラムである。プロセッサ100は、メインメモリ200に記憶されたインタプリタプログラム200aを読み出してインタプリタを起動することにより、ソースプログラム200bを逐次実行することとなる。また、インタプリタは、ソースプログラム200bを逐次実行する過程において、間接分岐を行う必要がある場合でも、間接分岐命令の代わりに、擬似的な間接分岐命令を用いるように実装されている。
例えば、プロセッサ100により起動されたインタプリタは、ソースプログラム200bを実行する場合に、間接分岐命令「call %rN(Nは0以上の整数)」(図7参照)が必要となった場合にでも、かかる間接分岐命令を用いず、擬似的な間接分岐命令「move %link_reg=%rN」、「ret」(図8参照)で代用するように実装されている。
続いて、プロセッサ100の構成の説明に移ると、メモリアクセス制御部110は、メインメモリ200との間で行われるデータの入出力を制御する処理部である。レジスタ120は、各種のデータを記憶する記憶装置であり、特に本発明に密接に関連するものとしては、汎用レジスタ群120a、プログラムカウンタ120b、リンクレジスタ120cを備える。
このうち、汎用レジスタ群120aは、各種プログラム(インタプリタプログラム200a等)を実行する場合に利用されるデータ、分岐先のアドレス等を格納するレジスタ群である。図9に示す例では、汎用レジスタ群は、汎用レジスタr0〜rN(Nは整数)を含んでいる。
プログラムカウンタ120bは、次に実行する命令が格納されたアドレスを格納するレジスタであり、リンクレジスタ120cは、分岐元のアドレスを格納するレジスタである。なお、リンクレジスタ120cは、メインメモリ200と協働して、擬似的なスタックを構成する事が可能である。例えば、リンクレジスタ120cにアドレスAが格納されている状態で、新たにアドレスBをリンクレジスタ120cに格納する場合には、アドレスAがメインメモリ200の退避データ200cに退避される。すなわち、リンクレジスタ120cは新たなアドレスを格納するたびに、退避データ200cにアドレスを退避させる。
また、リンクレジスタ120cにアドレスBが格納され、メインメモリ200の退避データ200cにアドレスAが退避されている状態で、リンクレジスタ120cのアドレスAが取り出された場合に、退避データ200cに退避していたアドレスBをリンクレジスタ120cに戻す処理を行う。すなわち、リンクレジスタ120cに格納されたアドレスが取り出されるたびに、退避されたアドレスがリンクレジスタ120cに戻される(新しく退避データに退避された順番で、アドレスがリンクレジスタ120cに戻される)。
リターン・アドレス・スタック130は、リンクレジスタ120cに分岐元となるアドレスが格納されるたびに、リンクレジスタ120cに格納されたアドレスと等しいアドレスを順番に格納するレジスタである。例えば、リンクレジスタ120cにアドレスA、アドレスB、アドレスC・・・の順番でアドレスが格納された場合には、リターン・アドレス・スタック130は、アドレスA、アドレスB、アドレスC・・・の順番で、アドレスを記憶する。ただし、メインメモリ200から読み出した値をリンクレジスタ120cに格納した場合には、リターン・アドレス・スタック130の更新は行わない。なぜなら、メインメモリ200からの読み出しは、退避していた分岐元アドレスをリンクレジスタ120cに戻す処理であり、ここでリターン・アドレス・スタック130を更新した場合は、格納と抽出の対応が取れなくなるためである。
リターン・スタック・アドレス130に記憶された各アドレスは、サブルーチン移行後の復帰命令時に、新しく格納したアドレスから順番に分岐予測部140に抽出され分岐予測が行われる。
分岐予測部140は、リターン・アドレス・スタック130に記憶された分岐先のアドレスを読み出して、復帰命令時による分岐予測を行う装置である。具体的に、分岐予測部140は、リターン・アドレス・スタック130に記憶された分岐先のアドレスを、新しく格納された順番で抽出し、抽出した分岐先のアドレスを復帰命令時の分岐先のアドレスとして判定する。
デコード・制御部150は、分岐予測部140から分岐予測結果を取得し、メインメモリ200に記憶された命令を、メモリアクセス制御部110、レジスタ120を経由して順次読み出し、実行すべき処理を判定し、判定結果となる制御命令を演算パイプライン部160に出力して各種演算を実行させる装置である。また、演算パイプライン部160は、デコード・制御部150から制御命令を取得し、スーパースカラ方式によって複数の処理を並列して実行する演算装置である。デコード・制御部150は、メインメモリ200から取得した命令が復帰命令の時に、リターン・アドレス・スタック130から戻りアドレスを降ろして分岐予測を行い、予測に従って次に実行すべき命令をメインメモリ200から読み出す。また、演算パイプライン部160へ復帰命令を処理する制御命令を送る。演算パイプライン部160は、デコード制御部150から制御命令を取得し、復帰命令、すなわちリンクレジスタ120cに格納されたアドレスを読み出し、そのアドレスが次に取得・解釈すべき命令のアドレスであると、デコード・制御部150に通達する。
図8に示した擬似的な間接分岐を構成する命令、move命令とret命令との間に十分多くの命令を挿入することができれば、リンクレジスタ120に書き込まれた値がリターン・アドレス・スタック130に積まれることになり、復帰命令を実施する際に復帰先を正しく予想することができる。
上述してきたように、本実施例1にかかるプロセッサ100は、メインメモリ200に記憶されたインタプリタプログラム200aを読み出してインタプリタを起動し、インタプリタプログラム200aがソースプログラム200bを実行する場合において、間接分岐命令が必要な状況であっても、間接分岐命令の代わりに擬似的な間接分岐命令を用いて分岐先のアドレスをリンクレジスタ120cに格納するようにインタプリタプログラム200aが実装されているので、分岐予測を精度よく行うことができ、分岐によるペナルティなしに任意のアドレスへの分岐を完了することができる。
上述した実施例1では、インタプリタが、単一の間接分岐命令の代わりに、擬似的な間接分岐命令を用いる場合を例にあげて説明したが、本実施例2では、複数の間接分岐命令が必要な場合に、かかる複数の間接分岐命令の代わりに擬似的な間接分岐命令を実行する場合について説明する。なお、実施例2にかかるプロセッサおよびメインメモリの構成は、実施例1に示したプロセッサ100およびメインメモリ200と同様であるので、適宜、図9を用いて実施例2の説明を行う。
まず、複数の間接分岐命令を実行するインタプリタを例示する。図10は、複数の間接分岐命令を実行するインタプリタの一例を示す図である。図10に示す各種命令を順に説明する。「move %r6=Func_a」によって、関数「Func_a」を開始するアドレスが汎用レジスタ「r6」に格納され、「move %r7=Func_b」によって、関数「Func_b」を開始するアドレスが汎用レジスタ「r7」に格納される。
そして、「call %r6」によって汎用レジスタ「r6」に格納されたアドレスに処理が移行して関数「Func_a」が実行され、「call %r7」によって汎用レジスタ「r7」に格納されたアドレスに処理が移行して関数「Func_b」が移行される。なお、図10に示す「Func_a:」〜「ret」は、関数「Func_a」のコードであり、「Func_b:」〜「ret」は、関数「Func_b」のコードである。
ここで、図10に示した「call %r6」と等価の処理を説明する。図11は、図10に示した「call %r6」と等価のプログラムを示す図である。同図に示すように、「call %r6」と等価のプログラムが「move %link_reg=%pc」、「jump %r6」となる。
ここで、「move %link_reg=%pc」は、プログラムカウンタ120bに格納されたアドレスをリンクレジスタ120cに格納する命令を示している(プログラムカウンタ120bおよびリンクレジスタ120cは図9を参照)。そして、「jump %r6」によって汎用レジスタ「r6」に格納されたアドレス(図10の場合では、関数「Funk_a」のアドレス)に移行する命令となる。すなわち、call命令は、リンク処理と間接分岐処理を同時に行う、リンク付き間接分岐命令である。
本実施例2のインタプリタは、図10、図11に示したような複数の間接分岐命令の代わりに擬似的な間接分岐命令を実行する。図12は、複数の擬似的な間接分岐命令を実行するインタプリタの一例を示す図である。
図12において、「move %r6=Func_a」によって、関数「Func_a」を開始するアドレスが汎用レジスタ「r6」に格納され、「move %r7=Func_b」によって、関数「Func_b」を開始するアドレスが汎用レジスタ「r7」に格納される。
そして、「move %link_reg=%r7」によって、汎用レジスタ「r7」に格納されたアドレスがリンクレジスタ120cに格納され、「store (%r1)=%link_reg」によって、リンクレジスタ120cに格納されたアドレスが、メインメモリ200の所定領域に退避される。
ここで、「move %link_reg=%r7」は、図10に示した間接分岐命令「call %r7」に代わる擬似的な間接分岐のための前処理となる。プロセッサ100は、「move %link_reg=%r7」を実行してリンクレジスタ120cに汎用レジスタ「r7」に格納されたアドレスを書き込むことによって、プロセッサ100内部では、復帰先アドレスとして汎用レジスタ「r7」で指定されたアドレスをリターン・アドレス・スタック130に記憶する。これは、プロセッサ100の内部で利用するための挙動で、外部には非公開の挙動である。
続いて、「move %link_reg=%r6」によって、汎用レジスタ「%r6」に格納されたアドレスがリンクレジスタ120cに格納される。なお、関数「Func_a」を実行するバイナリコードには、末尾に「load %link_reg=(%r1)」、「ret」が含まれ、「load %link_reg=(%r1)」によってメインメモリ200の所定領域に退避していたアドレスをリンクレジスタ120cに格納し、「ret」によって処理が元の関数に戻される。なお、「Func_b:」〜「ret」は、関数「Func_b」のコードであり、「Func_a:」〜「ret」と同様の各種コードが含まれる。
「store (%r1)=%link_reg」を実行することで、リンクレジスタ120cに書き込まれたアドレスを即座にメインメモリ200に退避し、「move %link_reg=%r6」を実行することで、汎用レジスタ「r6」で指定されたアドレスをリンクレジスタ120cに格納している。
上記命令をプロセッサが実行することによって、リンクレジスタ120cに格納されていたアドレスが上書きされてしまうことになるが、リターン・アドレス・スタック130は、その名の通り、スタックとしての構造を持っており、復帰先のアドレスが上書きされるわけではなく、直近の復帰先が汎用レジスタ「r6」に格納されていたアドレスとなり、その次の復帰先が汎用レジスタ「r7」に格納されていたアドレスとなる。
その後、復帰命令により現在のリンクレジスタ120cの値(汎用レジスタr6の値に対応)で指定された命令アドレスに処理を移す。これが復帰命令により擬似的に間接分岐を行っている部分である。続いて、その関数の最後において、退避したアドレスを再度リンクレジスタ120cに取り戻して復帰命令を実行している。
ここでリンクレジスタ120cに値を取り戻したのは、リターン・アドレス・スタック130に積まれたアドレスが、あくまでも分岐予測のための情報でしかないためである。仮にリンクレジスタ120cの値を元に戻さずに復帰してしまえば、再び現在のリンクレジスタ120cの値、つまり「Func_a」の先頭に処理は移動し、同時に分岐予測も外れる。2つ目の分岐アドレスがリンクレジスタ120cに格納されるのは呼び出し(=復帰)の直前なのだが、リターン・アドレス・スタック130への積載は「Func_a」呼び出し以前にまとめて行われているため、結果としてはリターン・アドレス・スタック130を用いた分岐予測はデコード・制御部150による命令の取得に間に合い、ヒットする事になる。
ところで、プロセッサ100は、インタプリタプログラム200aを読み出して、インタプリタを起動し、インタプリタがソースプログラム200bを実行する場合に、複数の間接分岐命令(図10、図11を参照)の代わりに、擬似的な間接分岐命令(図12を参照)を用いる。すなわち、プロセッサ100は、間接分岐を行うことなく各命令を実行することができる。
具体的に、プロセッサ100が、インタプリタを起動した場合には、本実施例のインタプリタは、ソースプログラム200bを実行する上で必要となる複数の間接分岐命令(例えば、call命令など)を逆順に抽出し(図10に示す例では、「call %r7」、「call %r6」の順番で抽出し)、抽出した間接分岐命令に対応する分岐先のアドレスを逆順に(図10に示す例では、「Func_bのアドレス」、「Func_aのアドレス」の順番)、リンクレジスタ120cに格納するような擬似的な間接分岐命令のための前処理を実行するように実装されている。
なお、間接分岐命令の置き替えに関して、事前処理をどこまでまとめて行えるかは、ソースプログラム中の分岐を伴う制御文(条件文、Switch文、仮想関数呼び出しなど)単位となる。
次に、本実施例2にかかるプロセッサ100が、メインメモリ200に記憶されたインタプリタプログラム200aを読み出して起動するインタプリタの処理手順について説明する。図13、図14は、インタプリタの処理手順を示すフローチャートである。
同図に示すように、インタプリタは、「プログラム読込開始位置」としてプログラム(ソースプログラム)の先頭位置を設定し(ステップS101)、「プログラム読込開始位置」に「プログラム読込現在位置」を設定し(ステップS102)、「プログラム読込現在位置」から1処理分のプログラムを読み込み、解釈する(ステップS103)。
そして、インタプリタは、「プログラム読込現在位置」を1処理分だけ先に進め(ステップS104)、解釈した命令が分岐処理であるか否かを判定する(ステップS105)。解釈した命令が分岐命令でない場合には(ステップS106,No)、ステップS103に移行する。
一方、解釈した命令が分岐命令である場合には(ステップS106,Yes)、「プログラム読込停止位置」に「プログラム読込現在位置」を設定し(ステップS107)、リンクレジスタ120cに格納されたアドレスをメインメモリ200上のスタックに退避し(ステップS108)、「プログラム読込現在位置」から1処理分のプログラムを読み込み、解釈する(ステップS109)。
続いて、解釈した命令に対応する処理を行うインタプリタ上の関数を調べ(ステップS110)、求めた関数のアドレスをリンクレジスタ120cに格納し(ステップS111)、「プログラム読込現在位置」を1処理分だけ後ろに戻す(ステップS112)。
そして、インタプリタは、「プログラム読込現在位置」と「プログラム読込開始位置」とが等しいか否かを判定し(ステップS113)、等しくない場合には(ステップS114,No)、ステップS108に移行する。
一方、「プログラム読込現在位置」と「プログラム読込開始位置」とが等しい場合には(ステップS114,Yes)、「ret」命令を実行し、リンクレジスタ120cに格納された関数へ分岐する(ステップS115)。
そして、インタプリタは、分岐先の関数で、プログラム中の1処理に対応した処理を行い(ステップS116)、分岐処理を行う関数か否かを判定し(ステップS117)、分岐処理を行なわない場合には(ステップS118,No)、分岐先の関数末尾で、メインメモリ200上のスタックに退避したリンクレジスタ120cの値を1つリンクレジスタに取り出し(ステップS119)、ステップS115に移行する。
一方、分岐処理を行う関数である場合には(ステップS118,Yes)、分岐処理に対応する関数を実行し(ステップS120)、「プログラム読込開始位置」として「プログラム実行停止位置」から1処理分だけ先に進めた位置を設定し(ステップS121)、ステップS102に移行する。
このように、インタプリタが、間接分岐命令の代わりに擬似的な間接分岐を実行するように実装されているので、インタプリタによって最も頻繁に実行されるループの高速化が期待され、間接分岐命令単体だけではなく、プログラム全体としても大きな性能向上を見込める。
上述してきたように、本実施例2にかかるプロセッサ100は、インタプリタプログラム200aを読み出してインタプリタを起動し、ソースプログラム200bを実行する上で必要となる間接分岐命令の代わりに、間接分岐命令の分岐先のアドレスを逆順にリンクレジスタ120cに格納し、復帰命令によって分岐するといった擬似的な間接分岐命令を利用する(プロセッサ100は、内部的に、リンクレジスタ120cに格納された値を、自動的にリターン・アドレス・スタック130に積む)ので、分岐予測を精度よく行うことができ、分岐によるペナルティなしに任意のアドレスへの分岐を完了することができる。結果、間接分岐命令に相当する処理を数倍〜数十倍高速に実行することができる。また、分岐先アドレスをまとめてリンクレジスタ120cに登録することで、実際の分岐処理に十分に先立って、分岐先アドレスをリンクレジスタ120cに登録しており、復帰命令により疑似的な間接分岐が実行される時までに、プロセッサ100によって、リンクレジスタ120cに登録されたデータをリターン・アドレス・スタック130に登録する作業が完了しており、分岐予測が間に合う(=予測がヒットする)。
なお、上述の実施例1および実施例2では、インタプリタが間接分岐命令を実行する代わりに擬似的な間接分岐命令を用いる場合を例にあげて説明したが、かかる実行方式を仮想マシンに適用することも可能である。すなわち、仮想マシン(Java(登録商標)等)がバイナリを実行する際に、間接分岐命令が必要となっても、かかる間接分岐命令の代わりに擬似的な間接分岐命令を実行して、プロセッサ100に分岐先となるアドレスをリターン・アドレス・スタック130に格納させ、分岐予測を成功させることができる。
上述した実施例1、2では、インタプリタがソースプログラムを逐次実行する場合において、間接分岐命令の代わりに擬似的な間接分岐命令を利用していたが、コンパイラによって、間接分岐命令の代わりに疑似的な間接分岐命令を利用するコードを生成することも可能である。
すなわち、コンパイラによってソースプログラムをコンパイルし、間接分岐命令の代わりに擬似的な間接分岐命令を含んだプログラム(以下、擬似間接分岐プログラムと表記する)を生成し、プロセッサが、かかる擬似間接分岐プログラムを実行することによって、間接分岐命令に相当する処理を高速化することができる。
次に、本実施例3にかかるプロセッサの構成について説明する。図15は、本実施例3にかかるプロセッサの構成を示す機能ブロック図である。同図に示すように、このプロセッサ300は、メインメモリ400に接続され、メモリアクセス制御部310と、レジスタ320と、リターン・アドレス・スタック330と、分岐予測部340と、デコード・制御部350と、演算パイプライン部360とを備えて構成される。
ここで、メモリアクセス制御部310、レジスタ320、リターン・アドレス・スタック330、分岐予測部340、デコード・制御部350、演算パイプライン部360は、図9において説明したメモリアクセス制御部110、レジスタ120、リターン・アドレス・スタック130、分岐予測部140、デコード・制御部150、演算パイプライン部160に対応するため、説明を省略する。
また、メインメモリ400は、各種のデータおよびプログラムを記憶する記憶装置であり、コンパイラプログラム400aと、ソースプログラム400bと、擬似間接分岐プログラム400cと、退避データ400dとを記憶する。
このうち、コンパイラプログラム400aは、プロセッサ300が実行可能な、コンパイルを行うためのプログラムである。プロセッサ300が、コンパイラを起動することによって、ソースプログラム400bをコンパイルし、擬似間接分岐プログラム400cを生成する。
コンパイラを起動したプロセッサ300は、ソースプログラム400bをコンパイルする過程において、ソースプログラム400bの命令を間接分岐命令(図7、図10参照)に変換する必要がある場合に、かかる間接分岐命令の代わりに擬似的な間接分岐命令に変換する(図8、図12参照)。すなわち、従来では、図7のようにソースプログラム400bをコンパイルしていたものを、図8のようにコンパイルする。あるいは、図10のようにソースプログラム400bをコンパイルしていたものを、図12のようにコンパイルする。
プロセッサ300は、コンパイラによって擬似間接分岐プログラム400cを生成した後に、擬似間接分岐プログラム400cを読み出して、擬似間接分岐プログラム400cに応じた処理を実行する。この擬似間接分岐プログラム400cには、間接分岐命令の代わりに擬似的な間接分岐命令が含まれているので、間接分岐命令に相当する処理を高速化することができる。
上述してきたように、本実施例3にかかるプロセッサ300は、コンパイラを起動してソースプログラム400bをコンパイルし、間接分岐命令の代わりに擬似的な間接分岐命令を含んだ擬似間接分岐プログラム400cを生成し、プロセッサ300が、かかる擬似間接分岐プログラム400cを実行するので、間接分岐命令に相当する処理を高速化することができる。
なお、本実施例3では、プロセッサ300がコンパイラを起動して、ソースプログラム400bから擬似間接分岐プログラム400cを作成していたが、これに限定されるものではなく、コンパイルを専用に実行するコンパイラ装置によって、ソースプログラム400bをコンパイルし、間接分岐命令の代わりに擬似間接分岐命令を含んだ擬似間接分岐プログラム400cを生成し、かかる擬似間接分岐プログラム400cをプロセッサ300、あるいはプロセッサ100が実行するようにしても構わない。
ところで、本実施例において説明した各処理のうち、自動的に行われるものとして説明した処理の全部または一部を手動的に行うこともでき、あるいは、手動的に行われるものとして説明した処理の全部あるいは一部を公知の方法で自動的に行うこともできる。この他、上記文書中や図面中で示した処理手順、制御手順、具体的名称、各種のデータやパラメータを含む情報については、特記する場合を除いて任意に変更することができる。
また、図9および図15に示したプロセッサ100,300の構成は機能概念的なものであり、必ずしも物理的に図示の如く構成されていることを要しない。すなわち、各装置の分散・統合の具体的形態は図示のものに限られず、その全部または一部を、各種の負荷や使用状況などに応じて、任意の単位で機能的または物理的に分散・統合して構成することができる。
また、図9および図15のメモリ200,400に記憶された各種プログラム(インタプリタプログラム200a、ソースプログラム200b,400b、コンパイラプログラム400a、擬似間接分岐プログラム400c)は、必ずしも最初からメインメモリ200,400に記憶させておく必要はない。たとえば、コンピュータに挿入されるフロッピー(登録商標)ディスク(FD)、CD−ROM、DVDディスク、光磁気ディスク、ICカードなどの「可搬用の物理媒体」、または、コンピュータの内外に備えられるハードディスクドライブ(HDD)などの「固定用の物理媒体」、さらには、公衆回線、インターネット、LAN、WANなどを介してコンピュータに接続される「他のコンピュータ(またはサーバ)」などに各種プログラムを記憶しておき、コンピュータ(プロセッサ)がこれらから各種プログラムを読み出して実行するようにしてもよい。
さて、これまで本発明の実施例について説明したが、本発明は上述した実施例以外にも、特許請求の範囲に記載した技術的思想の範囲内において種々の異なる実施例にて実施されてもよいものである。
上述したように、本発明は、現在広く利用されているインタプリタ等に対して、高速な実装方法を提供する物である。この手法は、現在利用されている計算機上で実現可能であり、また実装にかかるコストも大きくはない。また、産業上大きなインパクトを持つJava(商標登録)をはじめとする仮想マシンに対しても有効な最適化手法であるため、実用上の価値も高い。また、インタプリタを作り直すだけで、その上で動いていた全てのプログラムが高速に動作するようになる点も評価できる。
本発明は、間接分岐命令の代わりに擬似的な間接分岐命令をコンピュータに実行させる間接分岐処理プログラムおよび間接分岐処理方法に関するものである。
従来より、計算機(CPU(Central Processing Unit)等)は、コンパイル方式あるいはインタプリタ方式によって人間により記述されたソースプログラムを実行している。コンパイル方式は、ソースプログラムをコンパイラと呼ばれる変換プログラムにより計算機上で実行できるバイナリ形式に変換した後に、バイナリ形式に変換したコードを実行する方式であり、インタプリタ方式は、インタプリタと呼ばれる特別なバイナリコードを計算機上で実行し、インタプリタがソースプログラムを逐次解釈しながら内容に応じた処理を随時行う方式である。
ところで、近年では、計算機の処理を高速化するために、計算機をスーパースカラと呼ばれる方式に基づいて設計している。この方式では、パイプライン方式で処理を行うことを前提としている。パイプライン方式では、各命令処理が複数のステージに分割され、それぞれのステージが個別のユニットにより処理される。そのため、次に実行すべき命令が確定していれば、先行命令の第二ステージの実行と並行して、後続命令の第一ステージを実行することができ、分割したステージの数だけ並列動作による高速な実行が可能となる。
ここで、パイプライン処理が巧く機能する条件として、次に実行すべき命令が確定しているという条件が存在する。つまり、命令1の次に実行すべき命令2(命令が命令1、命令2、命令3・・・の順で実行される場合)が、命令1の第1ステージの実行が完了するまでに確定していない時、次の命令2の処理を並列して実行することができない(命令2に続く命令も同様である)。
このような状態が発生する代表的な例が、分岐命令である。分岐命令においては、直前の分岐条件判定命令(例えば、比較命令)の結果が判明するまで、次に処理するべき命令が確定せず、パイプライン処理を行うことができないため、計算機全体の処理速度が大幅に低下してしまう。
パイプライン処理の性能低下を防止するために、分岐予測と呼ばれる技術が考案され実用化されている。かかる分岐予測の原理としては、過去に実行したプログラムの分岐結果を履歴に残しておき、その延長線上で分岐結果を予測するというアイデアが基本となっている(例えば、非特許文献1参照)。
また、分岐命令には、通常の分岐命令だけではなく、レジスタに記憶されたアドレスを基にして分岐する間接分岐命令も存在する。間接分岐命令は、上述したインタプリタを実装する際などに頻繁に利用されている。しかし、間接分岐命令は、スーパースカラ方式の計算機においてコストの高い命令となっているため、間接分岐命令に焦点を当てた予測手法の研究も行われている(例えば、非特許文献2、非特許文献3参照)。
なお、特許文献1では、狭いアドレス空間のみを取り扱うプロセッサ用に書かれたコードを、間接コールを用いずに広いアドレス空間を取り扱うプロセッサに適用する技術が示されている。
John L. Hennessy, and David A. Patterson. "Computer Architecture-A Quantitative Approach 3rd Edition," MORGAN KAUFMANN PUBLISHERS, ISBN 1-55860-724-2. P.-Y. Chang, E. Hao, and Y. N. Patt. "Target Prediction for Indirect Jumps", In Proceedings of 24th International Symposium on Computer Architecture, pp. 274~283, 1997. K. Driesen and U. HAolzle. "Accurate Indirect Branch Prediction", In Proceedings of 25th International Symposium on Computer Architecture, pp. 167~178, 1998. 特開2000−284965号公報
しかしながら、上述した従来の技術では、プログラム中に記載されたある間接分岐命令の次にどの命令が実行されるかを履歴から予測しても、予測した命令と実際に次に実行される命令が一致する確率が低いという問題があった。
実行のたびに異なる分岐先を持つような間接分岐命令に対しては、非特許文献2および非特許文献3の技術を利用したとしても、精度のよい予測を行うことができず、間接分岐命令は、スーパースカラ方式によってプログラムを実行する計算機にとって依然、コストの高い命令となっている。
本発明は、上記に鑑みてなされたものであって、分岐予測を精度よく行うことができる間接分岐処理プログラムおよび間接分岐処理方法を提供することを目的とする。
上述した課題を解決し、目的を達成するために、コンピュータ上のインタプリタに、記憶装置に記憶されたソースプログラムを読み込む読込手順と、前記ソースプログラムを解釈し、内容にあったインタプリタ内の処理コードを選択する手順と、前記コード選択手順によって選択された処理コードを呼び出す手順を実行させるが、当該インタプリタは、前記処理コード選択、呼び出し手順において、選択したコードに分岐するために、間接分岐命令を利用する代わりに、選択したコードのアドレスを処理の順序とは逆順にコールスタックに格納し、疑似的な間接分岐命令によって呼び出し処理を行う。
また、本発明は、上記発明において、前記処理コード呼び出し手順の、汎用レジスタに記憶された分岐先のアドレスに処理を移行させる間接分岐命令を、前記コールスタックに分岐先のアドレスを格納し、そのアドレスに処理を移行させる命令で代用した擬似間接分岐コードで代用することを特徴とする。
また、本発明は、上記発明において、前記コンピュータに搭載された所定のスタック、またはリンクレジスタに間接分岐命令の分岐先のアドレスを格納することで、間接的に計算機内部の復帰アドレス予測テーブルを更新し、疑似的な間接分岐を処理する際に分岐予測を成功させることを特徴とする。
また、本発明は、上記発明において、前記ソースプログラムには、処理の分岐を伴う制御文が記述されており、前記インタプリタ内の擬似間接分岐コードは、前記制御文の条件判定部が記述されるまでの区間ごとに前記処理コードのアドレスを逆順にコールスタックに格納する命令を含んでいることを特徴とする。
本発明によれば、コンピュータに、記憶装置に記憶されたソースプログラムを読み込む読込手順と、ソースプログラムを解釈し、内容にあったインタプリタ内の処理コードを選択する手順と、コード選択手順によって選択された処理コードを呼び出す手順と、を実行させ、この処理により、間接的に計算機内部の復帰アドレス予測テーブルを更新し、処理コード呼び出し手順の際には、この予測テーブルを用いて分岐予測が行われるので、分岐予測を精度よく行うことができ、分岐によるペナルティなしに任意のアドレスへの分岐を完了することができる。結果、間接分岐命令に相当する処理を数倍〜数十倍高速に実行することができる。
また、本発明によれば、コンピュータに実行させるコードの呼び出し手順において、汎用レジスタに記憶された分岐先のアドレスに処理を移行させる間接分岐命令を、前記コールスタックに岐先のアドレスを格納し、そのアドレスに処理を移行させる命令で代用した擬似間接分岐コードで代用するので、ソースプログラムを実行するコンピュータの処理性能を向上させることができる。
また、本発明によれば、コンピュータに搭載された所定のスタック、またはリンクレジスタに間接分岐命令の分岐先のアドレスを逆順に格納することで、間接的に計算機内部の復帰アドレス予測テーブルを更新し、疑似的な間接分岐を処理する際に分岐予測を成功させるので、コンピュータの分岐予測の精度を向上させ、ソースプログラムを実行するコンピュータの処理性能を向上させることができる。
また、本発明によれば、ソースプログラムには、処理の分岐を行う制御文が記述されており、インタプリタ内の擬似間接分岐コードは、制御文の条件判定部が記載されるまでの区間ごとに前記間接分岐命令の分岐先のアドレスを逆順にコールスタックに格納する命令を含んでいるため、より効率よく高速に擬似間接分岐を実行することができる。
以下に、本発明にかかる間接分岐処理プログラムおよび間接分岐処理方法の実施例を図面に基づいて詳細に説明する。なお、この実施例によりこの発明が限定されるものではない。
まず、本願発明にかかる実施例の説明を行う前に、本願発明に関わる従来の技術(間接分岐命令、インタプリタ方式およびコンパイル方式、スーパースカラプロセッサとパイプライン処理、分岐予測、関数からの復帰処理、リターン・アドレス・スタック、ハードウェアによるインタプリタ支援、Just In Timeコンパイル方式)について順に説明する。
(間接分岐命令)
CPU(Central Processing Unit)等の計算機上で動作するプログラムについて、途中結果に応じて異なる処理を行うために分岐と呼ばれる命令が用いられる。計算機システムにおいて、プログラムはメモリ上に順に配置され、配置された順に従い、計算機により逐次実行される。図1は、分岐処理を説明するための図である。実行が分岐命令に差し掛かると、直前の条件判定結果において特定の条件を満たした場合に、次に処理すべき命令アドレスを指定されたメモリアドレスに変更する(図1では、条件に応じて、処理3あるいは処理5に移行することとなる)。この条件判定命令あるいは分岐命令においては、メモリアドレスや条件は、命令の一部として符号化された固定値である。
一方、条件に応じて複数の分岐先へ処理を移したい場合が存在する。図2は、複数の分岐処理と間接分岐処理とを説明するための図である。図2の左側に示すように、条件判定と分岐を必要な種類だけ並べて実現する事もできるが、多くの条件判定を伴う分岐は効率が悪い。そこで用いられるのが間接分岐命令と呼ばれる処理である。この処理では、次に実行すべきアドレスとしてレジスタの値が用いられる。即ち、過去の計算結果そのものを次の命令アドレスとして指定できる。これにより、プログラム自身で分岐先命令アドレスを計算し、その値により間接分岐を行う事が可能となり、任意の処理への分岐が実現できる(図2の右側参照)。
(インタプリタ方式およびコンパイル方式)
計算機上で動作するプログラムの実行方式には、大きく分けて2つの方式が存在する。1つがコンパイル方式であり、もう1つがこのインタプリタ方式である。コンパイル方式においては、ソースファイルに記述されたプログラムを、事前にコンパイラにより実行バイナリに変換する必要がある。このコンパイラにより変換された実行バイナリは、計算機上で直接実行される。
一方、インタプリタ方式において計算機上で直接実行されるのは、インタプリタと呼ばれるソフトウェアである。インタプリタは、ソースファイルを逐次解釈しながら、プログラム記述に沿った処理を行う。このため、コンパイル方式に比べ、プログラムの処理には時間がかかる。しかしその一方で、異なる設計の計算機システムにおいても、共通仕様のインタプリタが存在すれば、同一のプログラムをそのまま利用する事が可能というメリットも存在する。
図3は、コンパイル方式とインタプリタ方式との違いを説明するための図である。図3の左側に示すように、インタプリタ方式では、ハードウェア上で直接動作するのは基本ソフトとインタプリタであり、インタプリタは、基本ソフトの機能を利用しながら動作する。プログラムはこのインタプリタ上で解釈・実行される。一方、図3の右側に示すように、コンパイル方式ではプログラムはコンパイルされ、実行ファイルに変換される。実行ファイルは基本ソフトの機能を利用しながら、直接ハードウェアで実行される。
インタプリタは、それ自身1つのソフトウェアとして記述されている。インタプリタの基本動作は、プログラムを逐次解釈し、その内容に応じた処理を行う事の繰り返しである。図4は、従来のインタプリタの処理を示すフローチャートである。ここで注目したいのが、中央にある分岐処理「命令に応じた処理へ分岐」である。この分岐は、図4からもわかる通り複数の処理へ分岐する必要があり(例えば、処理A、処理B、・・・処理Y、処理Zのいずれかに分岐する必要があり)、この分岐としては間接分岐を用いる必要がある。よって、インタプリタの動作速度は、この間接分岐の処理効率に大きく左右される事になる。
(スーパースカラプロセッサとパイプライン処理)
現在の高性能計算機は、内部はスーパースカラと呼ばれる方式に基づいて設計されている。この方式ではパイプライン方式で処理を行う事を前提としており、パイプライン方式では各命令の処理は複数のステージに分割され、それぞれのステージが個別のユニットにより処理される。
図5は、パイプライン処理を説明するための図である。図5における横軸が時間の流れを示し、縦軸が命令の流れを示す。図5に示す例では、命令処理をIF、ID、EX、MEM、WBと5つのステージに分割している。最新のプロセッサでは、このステージ数が増加する傾向にあり、十数段のステージに分割されている事も稀ではない。
さて、IFを処理するユニット(IFユニット)について考える。このIFユニットでは、特定の命令のIFに該当する処理を行い、結果を次のIDユニットに引き渡す。よって、次のサイクルにおいてIDの処理が行われている際には、IFユニットが命令に対して行うべき処理はない。同様にして次のサイクルではEXユニットが処理を行い、IFユニット、IDユニットの行うべき処理はない。
これを利用して、次のサイクルではIFユニットは次の命令のIF処理を行うようにする。このようにして後続する命令の処理を平行して分割実行する事で、1つの命令の処理の完了まで5サイクルかかっていたとしても、長い時間で見ると、平均して1サイクル毎に1つの命令の処理が完了する事になる。このようにNサイクルかかる処理を分割・並列実行する事で見かけ上の処理時間を1サイクルにするような技術をパイプライン技術と呼ぶ。
ただし、このパイプライン処理が巧く機能する条件として、次に実行すべき命令が確定している、という条件が存在する。つまり、命令1の次に実行すべき命令が、命令1の実行が完了するまで確定していない時、次の命令の処理を並列して開始する事ができない。このような状態が発生する代表的な例が、分岐命令である。
分岐命令においては、直前の条件判定命令の結果が判明するまで、次に処理するべき命令が確定しない。このため、パイプライン処理を行う事ができずに、全体として性能が大きく低下してしまう。これを回避するための技術が分岐予測と呼ばれる技術である。分岐予測に関する詳しい説明は後述するが、簡単に説明すると、これは条件判定結果をあらかじめ予測し、分岐命令の時点で比較結果が確定していない時にも、この予測に基づき次に実行すべき命令を推測し、その推測に従って処理を進める方式である。
この方式を用いれば、予測の精度が十分に高い場合に、分岐による性能低下はなくなる。また、予測がはずれた場合には、それ以降の命令処理を破棄し、仮定に基づき実行した命令が処理される前の状態に巻き戻した上で、正しい命令列を改めて実行しなおす事で、実行結果に影響は与えない。スーパースカラプロセッサに関する詳細は文献[2](Mike Johnson. “Superscalar Microprocessor Design,” Prentice-Hallm Inc, ISBN 0138756341.)に記載されており、計算機全般に関する技術の詳細は文献[1](John L. Hennessy, and David A. Patterson. “Computer Architecture-A Quantitative Approach 3rd Edition,” MORGAN KAUFMANN PUBLISHERS, ISBN 1-55860-724-2.)に記載されている。
(分岐予測)
上記の「スーパースカラプロセッサとパイプライン処理」の節で述べた通り、精度の良い分岐予測を行うことは、スーパースカラ方式の計算機にとって重要な課題である。しかし、予測は条件判定結果に先立って、即座に行う事ができないと意味がなく、またハードウェアとして実装するため、大規模なデータベースを用いた予測なども行えない。よって、限られた資源でなるべく精度の高い予測が行えるよう工夫がなされている。
分岐予測の原理としては、過去の分岐結果を記憶しておき、その延長線上で分岐結果を予想するというアイデアが基本となっている。過去数回の分岐結果を命令毎に記憶しておき、過去の分岐傾向に従い予測するだけの単純な予測で、90%以上の精度で予測が当たるとされている。
ただし、実際には全ての分岐命令に対し個別の履歴を用意する事は難しく、分岐命令の命令アドレスの下位ビットをインデックスとして履歴を参照する方法が用いられる。この場合、運が悪い時には複数の分岐命令で同じ履歴を共有してしまい、正しく予測が行えない。
また、精度向上の工夫として、分岐間の相関を利用する方法がある。これは、特定の分岐結果は、その分岐命令に至るまでに通過した分岐命令の結果と相関関係がある事を利用している。これらは広域分岐予測と呼ばれ、95%前後の制度で予測する事が可能となる。さらには複数の予測機構を組み合わせて使うなど、様々な工夫により分岐予測精度の向上が図られている。予測機構については、文献[1]の3.4節以降に詳しく説明されている。また、ウィキペディア日本語版「分岐予測」の項[3]にも分岐予測の説明がなされている(“分岐予測”、ウィキペディア日本語版,http://ja.wikipedia.org/を参照)。
一方、これらの分岐予測手法は通常の分岐命令だけに焦点をあてた方法である。つまり複数の分岐先を持つような間接分岐命令に対しては、有効な予測手段を提供していない。間接分岐に焦点を当てた予測手法の研究は文献[4](P.-Y. Chang, E. Hao, and Y. N. Patt. “Target Prediction for Indirect Jumps”, In Proceedings of 24th International Symposium on Computer Architecture, pp. 274~283, 1997.)および文献[5](K. Driesen and U. HAolzle. “Accurate Indirect Branch Prediction”, In Proceedings of 25th International Symposium on Computer Architecture, pp. 167~178, 1998.)などが存在する。
また、商用プロセッサにおいてはIntel(R) Pentium(R) Mが間接分岐予測器を搭載したプロセッサとして存在する。この予測の仕組みについては例えば、文献[6](S. Gochman, R. Ronen, I. Anati, A. Berkovits, T. Kurts, A. Naveh, A. Saeed, Z. Sperber, and R. C. Valentine. “The Intel Pentium M Processor: Microarchitecture and Performance”, Intel Technology Journal, 7(2):21~36, 2003.)に記述されている。
また、分岐予測以外にもコンパイラと協調して分岐先アドレスをフォワーディングし、予測しなくてもペナルティが発生しない手法も研究されている(文献[7](豊島隆志、入江英嗣、五島正裕、and坂井修一.“レジスタ間接分岐ターゲット・フォワーディング”, SACSIS 2006))。しかしながら、間接分岐を考慮した予測機構を備えた商用プロセッサは少なく、また搭載されていたとしても、通常の分岐命令に比べ精度の良い予測を行うことはできていない。従って、間接分岐命令は、スーパースカラ方式のプロセッサにとって、コストの高い命令となっている。
(関数からの復帰処理)
特殊な形式の分岐を必要とする処理に「関数呼び出し」機能が挙げられる。図6は、関数呼び出しの様子を説明するための図である。同図に示す例では、メインの処理から関数Aが、関数Aから関数Bが呼び出される様子を示している。図6からもわかるように関数Aはメイン処理の複数の箇所から呼び出される。
一般に関数は、プログラム中のいずれの場所からも呼び出し可能であり、関数の実行が終了した際に移る次の処理というのは、呼び出し元箇所の次の命令となる。つまり、関数から戻る際には、複数の分岐先を持った分岐処理を行う必要がある。このために特殊な命令が用意されている事が多く、一般的には復帰命令(リターン命令)と呼ばれる命令が定義されている。
リターン命令は、それに対応するリンク処理が必要とされる。多くの計算機においては、関数を呼び出す際に、「Jump and Link」と呼ばれるリンク付き分岐命令を用いる。これは分岐と同時に現在実行中の命令アドレスを特定の場所に退避する命令である。復帰命令が呼ばれた際には、この時に退避された命令アドレスを用いて、呼び出し元のアドレスを特定し、呼び出し元に再分岐する。関数は入れ子状で呼び出されるため、この退避場所はスタック構造を持つ資源に格納される事が多い。あるいは特定の場所に一時退避し、次のリンク処理により上書きされる前に、一時退避済みのアドレスをソフトウェア的に再退避する事で入れ子状の呼び出しにも対応している。
(リターン・アドレス・スタック)
上記のリンク処理と復帰処理は特定の命令により実施される事が多く、プロセッサ内部で関数の呼び出し、復帰箇所を特定する事ができる。プロセッサ内部では、この復帰処理にかかる分岐のコストを最小限にするため、復帰処理に特化した分岐予測機構を備えている事が多い。現在利用されている商用プロセッサにおいては、例外なくこの予測機構は搭載されている。
この機構はリターン・アドレス・スタックと呼ばれ、リンク時に呼び出し元を内部のリターン・アドレス・スタックに積み、復帰時にはこのスタックから降ろしたアドレスを用いて分岐予測を行う。このリターン・アドレス・スタックとは、プログラムから見える外部仕様的な戻りアドレス退避場所とは異なり、プロセッサ内部で予測のためだけに用いられる特殊な記憶領域である。リターン・アドレス・スタックについては、文献[8](C.F.Webb. Subroutine.“call/return stack”,IBM Technical Disclosure Bulletin, 30(11):18~20,1988.)の技術解説、あるいは文献[9](D.R.Kaeli and P.G.Emma.“Branch History Table Prediction of Moving Target Branches Due to Subroutine Returns”,In Proceedings of 18th International Symposium of Computer Architecture,pages 34~42,1991.)、文献[10](K.Skadron,P.S.Ahuja,M.Martonosi, and D. W.Clark.“Improving Prediction for Procedure Return with Return-Address-Stack Repair Mechanisms”,In Proceedings of 31st International Symposium on Microarchitecture,pages 259~271,1998.)などの研究結果がある。
(ハードウェアによるインタプリタ支援)
インタプリタを高速に実行するための仕組みとして、計算機上にハードウェア的な支援機構を設ける場合もある。このような例の1つがMIPS社によるSmartMIPS(R)(文献[11](MIPS Technologies Inc.“MIPS32(R) Architecture for Programmers Volume IV-d: The SmartMIPS(R) Application-Specific Extension to the MIPS32(R) Architecture”,Document Number: MD00101 Revision 2.50,July 1,2005.))である。
これはMIPS32(R)アーキテクチャ向けの拡張仕様の1つで、組み込み分野をターゲットとした仕様になっている。この拡張は大きく分けて、暗号向け演算アクセラレータ、命令密度の最適化、インタプリタ支援、そしてリソース保護の4本柱になっている。このうちインタプリタ支援については文献[11]の3.4.3節で概要が触れられ、具体的な命令についての説明は5.1節に記述されている。
この拡張では、インタプリタの最内ループ処理を可能な限り少ない命令数で実現できるようにCISC的な命令が定義されている。CISCとは、スーパースカラ登場以前に主流だった計算機の方式で、現在主流のRISC(Reduced Instruction Set Computers)とは対照的に1つ1つの命令が高機能である(Complex Instruction Setである)事が特徴となっている。CISCとRISCについては文献[1]の2.16節内に「Reduced Instruction Set Computers」と題されて解説されている。
(Just In Timeコンパイル方式)
インタプリタを高速に実装するためのソフトウェア側の工夫としてJust In Timeコンパイル方式と呼ばれる技術が存在する。この方式ではまずインタプリタとしての動作でプログラムを解釈・実行し、それと同時にプログラムの動作について簡単な統計情報を作成する。この統計情報によりHot Spot(頻繁に実行される箇所)と判断されたプログラム部分に関しては、その時点でプログラムの解釈をまとめて行い、計算機上で直接実行可能な命令列に変換する。
以降、その命令に該当する箇所に実行がさしかかると、インタプリタによる動作をやめ、変換後の直接実行可能な命令列に制御を移す。この方式は、インタプリタ方式とコンパイラ方式の折衷方式と考えることができ、コンパイルにかかる時間的なコストと、直接実行される事による高速化の効果を比較し、効果の方が十分大きい場合に限って用いる事が可能な技術と言える。また、高速化の効果はコンパイル時にどれだけ複雑な最適化を行うかにも影響しており、多くの面でトレード・オフが存在する。また、計算機の性能や広大なメモリを要求するため、この方式は一般的に大規模なシステム上で利用される事が多い。
続いて、本実施例1の説明を行う。まず、本実施例1にかかるプロセッサの概要および特徴について説明する。本実施例1にかかるインタプリタは、ソースプログラムを逐次実行する場合に、間接分岐命令が必要な状況であっても、間接分岐命令の代わりに擬似的な間接分岐命令を実行するように実装されている。
このように、本実施例1にかかるインタプリタは、ソースプログラムを実行する場合に、間接分岐命令が必要な状況であっても、間接分岐命令の代わりに擬似的な間接分岐命令を実行するので、インタプリタを実行しているプロセッサは、分岐予測を精度よく行うことができ、分岐によるペナルティなしに任意のアドレスへの分岐を完了することができる。結果、間接分岐命令に相当する処理を数倍〜数十倍高速に実行することができる。
なお、本実施例1では、インタプリタを用いて説明するが、これに限定されるものではなく、その他のプログラムによって代用することができる。
次に、間接分岐命令と、間接分岐命令の代わりとなる擬似的な間接分岐命令とを比較して説明する。図7は、間接分岐命令を用いるインタプリタの一例を示す図であり、図8は、擬似的な間接命令を用いるインタプリタの一例を示す図である。
図7において、「call %r6」が間接分岐命令に対応する。具体的に、「call %r6」の処理内容は、プログラムカウンタに格納されたアドレスをリンクレジスタに格納した後に、プロセッサに搭載された汎用レジスタ「r6」に格納された分岐先のアドレスに処理を移行するという内容である。レジスタ「r6」に記憶されるアドレスに応じて分岐先がかわるため間接分岐命令となる。かかる間接分岐命令では、汎用レジスタに格納される分岐先のアドレスが多岐にわたるため、分岐命令の次に実行すべき命令を精度よく実行することができなかった。
一方、図8の「move %link_reg=%r6」および「ret」が擬似的な間接分岐命令に対応する。すなわち、本実施例1のインタプリタは、図7に示したような間接分岐命令「call %r6」を用いる必要がある場合であっても、かかる間接分岐命令を用いる代わりに、図8に示したような擬似的な間接分岐命令「move %link_reg=%r6」、「ret」を用いる。
図8に示す「move %link_reg=%r6」の処理内容は、プロセッサに搭載された、分岐元のアドレスを格納するレジスタ(以下、リンクレジスタ)に汎用レジスタ「r6」に格納された分岐先のアドレスを移動させるという内容である。つづく「ret」は、リンクレジスタに格納された分岐元に復帰するための命令であるが、本実施例においては、分岐先のアドレスが格納されているため、分岐先のアドレスに処理を移行する。
ここで、リンクレジスタにアドレスを格納するたびに、プロセッサに搭載されたリターン・アドレス・スタック(リターン・アドレス・スタックに関する説明は上記の内容を参照)にアドレスが順に積まれていく。プロセッサは、リンク付き分岐命令を実行した後の復帰時にリターン・アドレス・スタックに積まれた分岐先のアドレスを抽出する(新しく積まれた順にアドレスを抽出する)ことによって、精度よく復帰先のアドレスを予測することができる。
次に、本実施例1にかかるプロセッサの構成(構成の一例)について説明する。図9は、本実施例1にかかるプロセッサの構成を示す機能ブロック図である。同図に示すように、このプロセッサ100は、メモリアクセス制御部110と、レジスタ120と、リターン・アドレス・スタック130と、分岐予測部140と、デコード・制御部150と、演算パイプライン部160とを備えて構成される。
また、プロセッサ100は、各種のデータおよびプログラムを記憶するメインメモリ200に接続され、メインメモリ200に記憶された各種データ・プログラムを読み出して各種の処理を逐次実行する。
メインメモリ200は、各種のデータおよびプログラムを記憶する記憶装置であり、特に本発明に密接に関連するものとしては、インタプリタプログラム200a、ソースプログラム200b、退避データ200cを記憶している。
このうち、インタプリタプログラム200aは、ソースプログラム200bを逐次読み出して実行するためのプログラムである。プロセッサ100は、メインメモリ200に記憶されたインタプリタプログラム200aを読み出してインタプリタを起動することにより、ソースプログラム200bを逐次実行することとなる。また、インタプリタは、ソースプログラム200bを逐次実行する過程において、間接分岐を行う必要がある場合でも、間接分岐命令の代わりに、擬似的な間接分岐命令を用いるように実装されている。
例えば、プロセッサ100により起動されたインタプリタは、ソースプログラム200bを実行する場合に、間接分岐命令「call %rN(Nは0以上の整数)」(図7参照)が必要となった場合にでも、かかる間接分岐命令を用いず、擬似的な間接分岐命令「move %link_reg=%rN」、「ret」(図8参照)で代用するように実装されている。
続いて、プロセッサ100の構成の説明に移ると、メモリアクセス制御部110は、メインメモリ200との間で行われるデータの入出力を制御する処理部である。レジスタ120は、各種のデータを記憶する記憶装置であり、特に本発明に密接に関連するものとしては、汎用レジスタ群120a、プログラムカウンタ120b、リンクレジスタ120cを備える。
このうち、汎用レジスタ群120aは、各種プログラム(インタプリタプログラム200a等)を実行する場合に利用されるデータ、分岐先のアドレス等を格納するレジスタ群である。図9に示す例では、汎用レジスタ群は、汎用レジスタr0〜rN(Nは整数)を含んでいる。
プログラムカウンタ120bは、次に実行する命令が格納されたアドレスを格納するレジスタであり、リンクレジスタ120cは、分岐元のアドレスを格納するレジスタである。なお、リンクレジスタ120cは、メインメモリ200と協働して、擬似的なスタックを構成する事が可能である。例えば、リンクレジスタ120cにアドレスAが格納されている状態で、新たにアドレスBをリンクレジスタ120cに格納する場合には、アドレスAがメインメモリ200の退避データ200cに退避される。すなわち、リンクレジスタ120cは新たなアドレスを格納するたびに、退避データ200cにアドレスを退避させる。
また、リンクレジスタ120cにアドレスBが格納され、メインメモリ200の退避データ200cにアドレスAが退避されている状態で、リンクレジスタ120cのアドレスAが取り出された場合に、退避データ200cに退避していたアドレスBをリンクレジスタ120cに戻す処理を行う。すなわち、リンクレジスタ120cに格納されたアドレスが取り出されるたびに、退避されたアドレスがリンクレジスタ120cに戻される(新しく退避データに退避された順番で、アドレスがリンクレジスタ120cに戻される)。
リターン・アドレス・スタック130は、リンクレジスタ120cに分岐元となるアドレスが格納されるたびに、リンクレジスタ120cに格納されたアドレスと等しいアドレスを順番に格納するレジスタである。例えば、リンクレジスタ120cにアドレスA、アドレスB、アドレスC・・・の順番でアドレスが格納された場合には、リターン・アドレス・スタック130は、アドレスA、アドレスB、アドレスC・・・の順番で、アドレスを記憶する。ただし、メインメモリ200から読み出した値をリンクレジスタ120cに格納した場合には、リターン・アドレス・スタック130の更新は行わない。なぜなら、メインメモリ200からの読み出しは、退避していた分岐元アドレスをリンクレジスタ120cに戻す処理であり、ここでリターン・アドレス・スタック130を更新した場合は、格納と抽出の対応が取れなくなるためである。
リターン・スタック・アドレス130に記憶された各アドレスは、サブルーチン移行後の復帰命令時に、新しく格納したアドレスから順番に分岐予測部140に抽出され分岐予測が行われる。
分岐予測部140は、リターン・アドレス・スタック130に記憶された分岐先のアドレスを読み出して、復帰命令時による分岐予測を行う装置である。具体的に、分岐予測部140は、リターン・アドレス・スタック130に記憶された分岐先のアドレスを、新しく格納された順番で抽出し、抽出した分岐先のアドレスを復帰命令時の分岐先のアドレスとして判定する。
デコード・制御部150は、分岐予測部140から分岐予測結果を取得し、メインメモリ200に記憶された命令を、メモリアクセス制御部110、レジスタ120を経由して順次読み出し、実行すべき処理を判定し、判定結果となる制御命令を演算パイプライン部160に出力して各種演算を実行させる装置である。また、演算パイプライン部160は、デコード・制御部150から制御命令を取得し、スーパースカラ方式によって複数の処理を並列して実行する演算装置である。デコード・制御部150は、メインメモリ200から取得した命令が復帰命令の時に、リターン・アドレス・スタック130から戻りアドレスを降ろして分岐予測を行い、予測に従って次に実行すべき命令をメインメモリ200から読み出す。また、演算パイプライン部160へ復帰命令を処理する制御命令を送る。演算パイプライン部160は、デコード制御部150から制御命令を取得し、復帰命令、すなわちリンクレジスタ120cに格納されたアドレスを読み出し、そのアドレスが次に取得・解釈すべき命令のアドレスであると、デコード・制御部150に通達する。
図8に示した擬似的な間接分岐を構成する命令、move命令とret命令との間に十分多くの命令を挿入することができれば、リンクレジスタ120に書き込まれた値がリターン・アドレス・スタック130に積まれることになり、復帰命令を実施する際に復帰先を正しく予想することができる。
上述してきたように、本実施例1にかかるプロセッサ100は、メインメモリ200に記憶されたインタプリタプログラム200aを読み出してインタプリタを起動し、インタプリタプログラム200aがソースプログラム200bを実行する場合において、間接分岐命令が必要な状況であっても、間接分岐命令の代わりに擬似的な間接分岐命令を用いて分岐先のアドレスをリンクレジスタ120cに格納するようにインタプリタプログラム200aが実装されているので、分岐予測を精度よく行うことができ、分岐によるペナルティなしに任意のアドレスへの分岐を完了することができる。
上述した実施例1では、インタプリタが、単一の間接分岐命令の代わりに、擬似的な間接分岐命令を用いる場合を例にあげて説明したが、本実施例2では、複数の間接分岐命令が必要な場合に、かかる複数の間接分岐命令の代わりに擬似的な間接分岐命令を実行する場合について説明する。なお、実施例2にかかるプロセッサおよびメインメモリの構成は、実施例1に示したプロセッサ100およびメインメモリ200と同様であるので、適宜、図9を用いて実施例2の説明を行う。
まず、複数の間接分岐命令を実行するインタプリタを例示する。図10は、複数の間接分岐命令を実行するインタプリタの一例を示す図である。図10に示す各種命令を順に説明する。「move %r6=Func_a」によって、関数「Func_a」を開始するアドレスが汎用レジスタ「r6」に格納され、「move %r7=Func_b」によって、関数「Func_b」を開始するアドレスが汎用レジスタ「r7」に格納される。
そして、「call %r6」によって汎用レジスタ「r6」に格納されたアドレスに処理が移行して関数「Func_a」が実行され、「call %r7」によって汎用レジスタ「r7」に格納されたアドレスに処理が移行して関数「Func_b」が移行される。なお、図10に示す「Func_a:」〜「ret」は、関数「Func_a」のコードであり、「Func_b:」〜「ret」は、関数「Func_b」のコードである。
ここで、図10に示した「call %r6」と等価の処理を説明する。図11は、図10に示した「call %r6」と等価のプログラムを示す図である。同図に示すように、「call %r6」と等価のプログラムが「move %link_reg=%pc」、「jump %r6」となる。
ここで、「move %link_reg=%pc」は、プログラムカウンタ120bに格納されたアドレスをリンクレジスタ120cに格納する命令を示している(プログラムカウンタ120bおよびリンクレジスタ120cは図9を参照)。そして、「jump %r6」によって汎用レジスタ「r6」に格納されたアドレス(図10の場合では、関数「Funk_a」のアドレス)に移行する命令となる。すなわち、call命令は、リンク処理と間接分岐処理を同時に行う、リンク付き間接分岐命令である。
本実施例2のインタプリタは、図10、図11に示したような複数の間接分岐命令の代わりに擬似的な間接分岐命令を実行する。図12は、複数の擬似的な間接分岐命令を実行するインタプリタの一例を示す図である。
図12において、「move %r6=Func_a」によって、関数「Func_a」を開始するアドレスが汎用レジスタ「r6」に格納され、「move %r7=Func_b」によって、関数「Func_b」を開始するアドレスが汎用レジスタ「r7」に格納される。
そして、「move %link_reg=%r7」によって、汎用レジスタ「r7」に格納されたアドレスがリンクレジスタ120cに格納され、「store (%r1)=%link_reg」によって、リンクレジスタ120cに格納されたアドレスが、メインメモリ200の所定領域に退避される。
ここで、「move %link_reg=%r7」は、図10に示した間接分岐命令「call %r7」に代わる擬似的な間接分岐のための前処理となる。プロセッサ100は、「move %link_reg=%r7」を実行してリンクレジスタ120cに汎用レジスタ「r7」に格納されたアドレスを書き込むことによって、プロセッサ100内部では、復帰先アドレスとして汎用レジスタ「r7」で指定されたアドレスをリターン・アドレス・スタック130に記憶する。これは、プロセッサ100の内部で利用するための挙動で、外部には非公開の挙動である。
続いて、「move %link_reg=%r6」によって、汎用レジスタ「%r6」に格納されたアドレスがリンクレジスタ120cに格納される。なお、関数「Func_a」を実行するバイナリコードには、末尾に「load %link_reg=(%r1)」、「ret」が含まれ、「load %link_reg=(%r1)」によってメインメモリ200の所定領域に退避していたアドレスをリンクレジスタ120cに格納し、「ret」によって処理が元の関数に戻される。なお、「Func_b:」〜「ret」は、関数「Func_b」のコードであり、「Func_a:」〜「ret」と同様の各種コードが含まれる。
「store (%r1)=%link_reg」を実行することで、リンクレジスタ120cに書き込まれたアドレスを即座にメインメモリ200に退避し、「move %link_reg=%r6」を実行することで、汎用レジスタ「r6」で指定されたアドレスをリンクレジスタ120cに格納している。
上記命令をプロセッサが実行することによって、リンクレジスタ120cに格納されていたアドレスが上書きされてしまうことになるが、リターン・アドレス・スタック130は、その名の通り、スタックとしての構造を持っており、復帰先のアドレスが上書きされるわけではなく、直近の復帰先が汎用レジスタ「r6」に格納されていたアドレスとなり、その次の復帰先が汎用レジスタ「r7」に格納されていたアドレスとなる。
その後、復帰命令により現在のリンクレジスタ120cの値(汎用レジスタr6の値に対応)で指定された命令アドレスに処理を移す。これが復帰命令により擬似的に間接分岐を行っている部分である。続いて、その関数の最後において、退避したアドレスを再度リンクレジスタ120cに取り戻して復帰命令を実行している。
ここでリンクレジスタ120cに値を取り戻したのは、リターン・アドレス・スタック130に積まれたアドレスが、あくまでも分岐予測のための情報でしかないためである。仮にリンクレジスタ120cの値を元に戻さずに復帰してしまえば、再び現在のリンクレジスタ120cの値、つまり「Func_a」の先頭に処理は移動し、同時に分岐予測も外れる。2つ目の分岐アドレスがリンクレジスタ120cに格納されるのは呼び出し(=復帰)の直前なのだが、リターン・アドレス・スタック130への積載は「Func_a」呼び出し以前にまとめて行われているため、結果としてはリターン・アドレス・スタック130を用いた分岐予測はデコード・制御部150による命令の取得に間に合い、ヒットする事になる。
ところで、プロセッサ100は、インタプリタプログラム200aを読み出して、インタプリタを起動し、インタプリタがソースプログラム200bを実行する場合に、複数の間接分岐命令(図10、図11を参照)の代わりに、擬似的な間接分岐命令(図12を参照)を用いる。すなわち、プロセッサ100は、間接分岐を行うことなく各命令を実行することができる。
具体的に、プロセッサ100が、インタプリタを起動した場合には、本実施例のインタプリタは、ソースプログラム200bを実行する上で必要となる複数の間接分岐命令(例えば、call命令など)を逆順に抽出し(図10に示す例では、「call %r7」、「call %r6」の順番で抽出し)、抽出した間接分岐命令に対応する分岐先のアドレスを逆順に(図10に示す例では、「Func_bのアドレス」、「Func_aのアドレス」の順番)、リンクレジスタ120cに格納するような擬似的な間接分岐命令のための前処理を実行するように実装されている。
なお、間接分岐命令の置き替えに関して、事前処理をどこまでまとめて行えるかは、ソースプログラム中の分岐を伴う制御文(条件文、Switch文、仮想関数呼び出しなど)単位となる。
次に、本実施例2にかかるプロセッサ100が、メインメモリ200に記憶されたインタプリタプログラム200aを読み出して起動するインタプリタの処理手順について説明する。図13、図14は、インタプリタの処理手順を示すフローチャートである。
同図に示すように、インタプリタは、「プログラム読込開始位置」としてプログラム(ソースプログラム)の先頭位置を設定し(ステップS101)、「プログラム読込開始位置」に「プログラム読込現在位置」を設定し(ステップS102)、「プログラム読込現在位置」から1処理分のプログラムを読み込み、解釈する(ステップS103)。
そして、インタプリタは、「プログラム読込現在位置」を1処理分だけ先に進め(ステップS104)、解釈した命令が分岐処理であるか否かを判定する(ステップS105)。解釈した命令が分岐命令でない場合には(ステップS106,No)、ステップS103に移行する。
一方、解釈した命令が分岐命令である場合には(ステップS106,Yes)、「プログラム読込停止位置」に「プログラム読込現在位置」を設定し(ステップS107)、リンクレジスタ120cに格納されたアドレスをメインメモリ200上のスタックに退避し(ステップS108)、「プログラム読込現在位置」から1処理分のプログラムを読み込み、解釈する(ステップS109)。
続いて、解釈した命令に対応する処理を行うインタプリタ上の関数を調べ(ステップS110)、求めた関数のアドレスをリンクレジスタ120cに格納し(ステップS111)、「プログラム読込現在位置」を1処理分だけ後ろに戻す(ステップS112)。
そして、インタプリタは、「プログラム読込現在位置」と「プログラム読込開始位置」とが等しいか否かを判定し(ステップS113)、等しくない場合には(ステップS114,No)、ステップS108に移行する。
一方、「プログラム読込現在位置」と「プログラム読込開始位置」とが等しい場合には(ステップS114,Yes)、「ret」命令を実行し、リンクレジスタ120cに格納された関数へ分岐する(ステップS115)。
そして、インタプリタは、分岐先の関数で、プログラム中の1処理に対応した処理を行い(ステップS116)、分岐処理を行う関数か否かを判定し(ステップS117)、分岐処理を行なわない場合には(ステップS118,No)、分岐先の関数末尾で、メインメモリ200上のスタックに退避したリンクレジスタ120cの値を1つリンクレジスタに取り出し(ステップS119)、ステップS115に移行する。
一方、分岐処理を行う関数である場合には(ステップS118,Yes)、分岐処理に対応する関数を実行し(ステップS120)、「プログラム読込開始位置」として「プログラム実行停止位置」から1処理分だけ先に進めた位置を設定し(ステップS121)、ステップS102に移行する。
このように、インタプリタが、間接分岐命令の代わりに擬似的な間接分岐を実行するように実装されているので、インタプリタによって最も頻繁に実行されるループの高速化が期待され、間接分岐命令単体だけではなく、プログラム全体としても大きな性能向上を見込める。
上述してきたように、本実施例2にかかるプロセッサ100は、インタプリタプログラム200aを読み出してインタプリタを起動し、ソースプログラム200bを実行する上で必要となる間接分岐命令の代わりに、間接分岐命令の分岐先のアドレスを逆順にリンクレジスタ120cに格納し、復帰命令によって分岐するといった擬似的な間接分岐命令を利用する(プロセッサ100は、内部的に、リンクレジスタ120cに格納された値を、自動的にリターン・アドレス・スタック130に積む)ので、分岐予測を精度よく行うことができ、分岐によるペナルティなしに任意のアドレスへの分岐を完了することができる。結果、間接分岐命令に相当する処理を数倍〜数十倍高速に実行することができる。また、分岐先アドレスをまとめてリンクレジスタ120cに登録することで、実際の分岐処理に十分に先立って、分岐先アドレスをリンクレジスタ120cに登録しており、復帰命令により疑似的な間接分岐が実行される時までに、プロセッサ100によって、リンクレジスタ120cに登録されたデータをリターン・アドレス・スタック130に登録する作業が完了しており、分岐予測が間に合う(=予測がヒットする)。
なお、上述の実施例1および実施例2では、インタプリタが間接分岐命令を実行する代わりに擬似的な間接分岐命令を用いる場合を例にあげて説明したが、かかる実行方式を仮想マシンに適用することも可能である。すなわち、仮想マシン(Java(登録商標)等)がバイナリを実行する際に、間接分岐命令が必要となっても、かかる間接分岐命令の代わりに擬似的な間接分岐命令を実行して、プロセッサ100に分岐先となるアドレスをリターン・アドレス・スタック130に格納させ、分岐予測を成功させることができる。
上述した実施例1、2では、インタプリタがソースプログラムを逐次実行する場合において、間接分岐命令の代わりに擬似的な間接分岐命令を利用していたが、コンパイラによって、間接分岐命令の代わりに疑似的な間接分岐命令を利用するコードを生成することも可能である。
すなわち、コンパイラによってソースプログラムをコンパイルし、間接分岐命令の代わりに擬似的な間接分岐命令を含んだプログラム(以下、擬似間接分岐プログラムと表記する)を生成し、プロセッサが、かかる擬似間接分岐プログラムを実行することによって、間接分岐命令に相当する処理を高速化することができる。
次に、本実施例3にかかるプロセッサの構成について説明する。図15は、本実施例3にかかるプロセッサの構成を示す機能ブロック図である。同図に示すように、このプロセッサ300は、メインメモリ400に接続され、メモリアクセス制御部310と、レジスタ320と、リターン・アドレス・スタック330と、分岐予測部340と、デコード・制御部350と、演算パイプライン部360とを備えて構成される。
ここで、メモリアクセス制御部310、レジスタ320、リターン・アドレス・スタック330、分岐予測部340、デコード・制御部350、演算パイプライン部360は、図9において説明したメモリアクセス制御部110、レジスタ120、リターン・アドレス・スタック130、分岐予測部140、デコード・制御部150、演算パイプライン部160に対応するため、説明を省略する。
また、メインメモリ400は、各種のデータおよびプログラムを記憶する記憶装置であり、コンパイラプログラム400aと、ソースプログラム400bと、擬似間接分岐プログラム400cと、退避データ400dとを記憶する。
このうち、コンパイラプログラム400aは、プロセッサ300が実行可能な、コンパイルを行うためのプログラムである。プロセッサ300が、コンパイラを起動することによって、ソースプログラム400bをコンパイルし、擬似間接分岐プログラム400cを生成する。
コンパイラを起動したプロセッサ300は、ソースプログラム400bをコンパイルする過程において、ソースプログラム400bの命令を間接分岐命令(図7、図10参照)に変換する必要がある場合に、かかる間接分岐命令の代わりに擬似的な間接分岐命令に変換する(図8、図12参照)。すなわち、従来では、図7のようにソースプログラム400bをコンパイルしていたものを、図8のようにコンパイルする。あるいは、図10のようにソースプログラム400bをコンパイルしていたものを、図12のようにコンパイルする。
プロセッサ300は、コンパイラによって擬似間接分岐プログラム400cを生成した後に、擬似間接分岐プログラム400cを読み出して、擬似間接分岐プログラム400cに応じた処理を実行する。この擬似間接分岐プログラム400cには、間接分岐命令の代わりに擬似的な間接分岐命令が含まれているので、間接分岐命令に相当する処理を高速化することができる。
上述してきたように、本実施例3にかかるプロセッサ300は、コンパイラを起動してソースプログラム400bをコンパイルし、間接分岐命令の代わりに擬似的な間接分岐命令を含んだ擬似間接分岐プログラム400cを生成し、プロセッサ300が、かかる擬似間接分岐プログラム400cを実行するので、間接分岐命令に相当する処理を高速化することができる。
なお、本実施例3では、プロセッサ300がコンパイラを起動して、ソースプログラム400bから擬似間接分岐プログラム400cを作成していたが、これに限定されるものではなく、コンパイルを専用に実行するコンパイラ装置によって、ソースプログラム400bをコンパイルし、間接分岐命令の代わりに擬似間接分岐命令を含んだ擬似間接分岐プログラム400cを生成し、かかる擬似間接分岐プログラム400cをプロセッサ300、あるいはプロセッサ100が実行するようにしても構わない。
ところで、本実施例において説明した各処理のうち、自動的に行われるものとして説明した処理の全部または一部を手動的に行うこともでき、あるいは、手動的に行われるものとして説明した処理の全部あるいは一部を公知の方法で自動的に行うこともできる。この他、上記文書中や図面中で示した処理手順、制御手順、具体的名称、各種のデータやパラメータを含む情報については、特記する場合を除いて任意に変更することができる。
また、図9および図15に示したプロセッサ100,300の構成は機能概念的なものであり、必ずしも物理的に図示の如く構成されていることを要しない。すなわち、各装置の分散・統合の具体的形態は図示のものに限られず、その全部または一部を、各種の負荷や使用状況などに応じて、任意の単位で機能的または物理的に分散・統合して構成することができる。
また、図9および図15のメモリ200,400に記憶された各種プログラム(インタプリタプログラム200a、ソースプログラム200b,400b、コンパイラプログラム400a、擬似間接分岐プログラム400c)は、必ずしも最初からメインメモリ200,400に記憶させておく必要はない。たとえば、コンピュータに挿入されるフロッピー(登録商標)ディスク(FD)、CD−ROM、DVDディスク、光磁気ディスク、ICカードなどの「可搬用の物理媒体」、または、コンピュータの内外に備えられるハードディスクドライブ(HDD)などの「固定用の物理媒体」、さらには、公衆回線、インターネット、LAN、WANなどを介してコンピュータに接続される「他のコンピュータ(またはサーバ)」などに各種プログラムを記憶しておき、コンピュータ(プロセッサ)がこれらから各種プログラムを読み出して実行するようにしてもよい。
さて、これまで本発明の実施例について説明したが、本発明は上述した実施例以外にも、特許請求の範囲に記載した技術的思想の範囲内において種々の異なる実施例にて実施されてもよいものである。
上述したように、本発明は、現在広く利用されているインタプリタ等に対して、高速な実装方法を提供する物である。この手法は、現在利用されている計算機上で実現可能であり、また実装にかかるコストも大きくはない。また、産業上大きなインパクトを持つJava(商標登録)をはじめとする仮想マシンに対しても有効な最適化手法であるため、実用上の価値も高い。また、インタプリタを作り直すだけで、その上で動いていた全てのプログラムが高速に動作するようになる点も評価できる。
図1は、分岐処理を説明するための図である。 図2は、複数の分岐処理と間接分岐処理とを説明するための図である。 図3は、コンパイル方式とインタプリタ方式との違いを説明するための図である。 図4は、従来のインタプリタの処理を示すフローチャートである。 図5は、パイプライン処理を説明するための図である。 図6は、関数呼び出しの様子を説明するための図である。 図7は、間接分岐命令を用いるインタプリタの一例を示す図である。 図8は、擬似的な間接命令を用いるインタプリタの一例を示す図である。 図9は、本実施例1にかかるプロセッサの構成を示す機能ブロック図である。 図10は、複数の間接分岐命令を実行するインタプリタの一例を示す図である。 図11は、図10に示した「call %r6」と等価のプログラムを示す図である。 図12は、複数の擬似的な間接分岐命令を実行するインタプリタの一例を示す図である。 図13は、インタプリタの処理手順を示すフローチャート(1)である 図14は、インタプリタの処理手順を示すフローチャート(2)である。 図15は、本実施例3にかかるプロセッサの構成を示す機能ブロック図である。
100,300 プロセッサ
110,310 メモリアクセス制御部
120,320 レジスタ
120a,320a 汎用レジスタ群
120b,320b プログラムカウンタ
120c,320c リンクレジスタ
130,330 リターン・アドレス・スタック
140,340 分岐予測部
150,350 デコード・制御部
160,360 演算パイプライン部
200,400 メインメモリ
200a インタプリタプログラム
200b,400b ソースプログラム
400c 擬似間接分岐プログラム
200c,400d 退避データ
400a コンパイラプログラム

Claims (18)

  1. コンピュータに、
    記憶装置に記憶されたソースプログラムを読み込む読込手順と、
    前記ソースプログラムを実行する場合に必要となる間接分岐命令の代わりに、当該間接分岐命令の分岐先のアドレスを逆順にレジスタおよび/またはメモリに格納する命令を含んだ擬似間接分岐コードを生成するコード生成手順と、
    前記コード生成手順によって生成された擬似間接分岐コードを記憶装置に記憶させる記憶手順と、
    前記記憶装置に記憶された擬似間接分岐コードの命令を逐次読み出して実行する実行手順と、
    を実行させるための間接分岐処理プログラム。
  2. 前記コード生成手順は、汎用レジスタに記憶された分岐先のアドレスに処理を移行させる間接分岐命令を、前記レジスタおよび/またはメモリに格納された分岐先のアドレスに処理を移行させる命令で代用した擬似間接分岐コードを生成することを特徴とする請求項1に記載の間接分岐処理プログラム。
  3. 前記擬似間接分岐コードを前記コンピュータに実行させて、間接的に、前記コンピュータに搭載された所定の記憶領域に間接分岐命令の分岐先のアドレスを逆順に格納させることを特徴とする請求項2に記載の間接分岐処理プログラム。
  4. 前記ソースプログラムは分岐を伴う制御文が記述されており、前記擬似間接分岐コードは、前記制御文が記述されるまでの区間ごとに前記間接分岐命令の分岐先のアドレスを逆順にレジスタに格納する命令を含んでいることを特徴とする請求項3に記載の間接分岐処理プログラム。
  5. コンピュータに、
    記憶装置に記憶されたソースプログラムを読み込む読込手順と、
    前記ソースプログラムを実行する場合に必要となる間接分岐命令の代わりに、当該間接分岐命令の分岐先のアドレスを逆順にレジスタおよび/またはメモリに格納する命令を含んだ擬似間接分岐コードを生成するコード生成手順と、
    前記コード生成手順によって生成された擬似間接分岐コードを記憶装置に記憶させる記憶手順と、
    前記記憶装置に記憶された擬似間接分岐コードの命令を逐次読み出して実行する実行手順と、
    を実行させるためのコンピュータ読取可能なプログラムを記憶する記憶媒体。
  6. 前記コード生成手順は、汎用レジスタに記憶された分岐先のアドレスに処理を移行させる間接分岐命令を、前記レジスタおよび/またはメモリに格納された分岐先のアドレスに処理を移行させる命令で代用した擬似間接分岐コードを生成することを特徴とする請求項5に記載の記憶媒体。
  7. 前記擬似間接分岐コードを前記コンピュータに実行させて、間接的に、前記コンピュータに搭載された所定の記憶領域に間接分岐命令の分岐先のアドレスを逆順に格納させることを特徴とする請求項6に記載の記憶媒体。
  8. 前記ソースプログラムは分岐を伴う制御文が記述されており、前記擬似間接分岐コードは、前記制御文が記述されるまでの区間ごとに前記間接分岐命令の分岐先のアドレスを逆順にレジスタに格納する命令を含んでいることを特徴とする請求項7に記載の記憶媒体。
  9. 記憶装置に記憶されたソースプログラムを読み出して処理を実行するコンピュータの間接分岐処理方法であって、
    前記コンピュータは、
    記憶装置に記憶されたソースプログラムを読み込む読込工程と、
    前記ソースプログラムを実行する場合に必要となる間接分岐命令の代わりに、当該間接分岐命令の分岐先のアドレスを逆順にレジスタおよび/またはメモリに格納する命令を含んだ擬似間接分岐コードを生成するコード生成工程と、
    前記コード生成工程によって生成された擬似間接分岐コードを記憶装置に記憶させる記憶工程と、
    前記記憶装置に記憶された擬似間接分岐コードの命令を逐次読み出して実行する実行工程と、
    を含んだことを特徴とする間接分岐処理方法。
  10. ソースプログラムを解釈し、ソースプログラムの内容に応じた処理コードを選択して当該処理コードを呼び出すインタプリタをコンピュータに実行させるための間接分岐処理プログラムであって、
    前記インタプリタは、
    記憶装置に記憶されたソースプログラムを読み込む読込手順と、
    前記ソースプログラムに応じた処理コードを選択し、当該処理コードが間接分岐命令に対応する処理コードである場合に、前記間接分岐命令に対応する処理コードの代わりに、当該間接分岐命令の分岐先のアドレスを逆順にレジスタおよび/またはメモリに格納する命令を含んだ擬似間接分岐命令に対応する処理コードを呼び出す呼出手順と、
    を含んだことを特徴とする。
  11. 前記呼出手順は、汎用レジスタに記憶された分岐先のアドレスに処理を移行させる間接分岐命令の処理コードを、前記レジスタおよび/またはメモリに格納された分岐先のアドレスに処理を移行させる擬似間接分岐命令の処理コードで代用することを特徴とする請求項10に記載の間接分岐処理プログラム。
  12. 前記擬似間接分岐命令の処理コードを前記コンピュータに実行させて、間接的に、前記コンピュータに搭載された所定の記憶領域に間接分岐命令の分岐先のアドレスを逆順に格納させることを特徴とする請求項11に記載の間接分岐処理プログラム。
  13. 前記ソースプログラムは分岐を伴う制御文が記述されており、前記擬似間接分岐命令の処理コードは、前記制御文が記述されるまでの区間ごとに前記間接分岐命令の分岐先のアドレスを逆順にレジスタおよび/またはメモリに格納する命令を含んでいることを特徴とする請求項12に記載の間接分岐処理プログラム。
  14. ソースプログラムを解釈し、ソースプログラムの内容に応じた処理コードを選択して当該処理コードを呼び出すインタプリタをコンピュータに実行させるための間接分岐処理プログラムを記憶する記憶媒体であって、
    前記インタプリタは、
    記憶装置に記憶されたソースプログラムを読み込む読込手順と、
    前記ソースプログラムに応じた処理コードを選択し、当該処理コードが間接分岐命令に対応する処理コードである場合に、前記間接分岐命令に対応する処理コードの代わりに、当該間接分岐命令の分岐先のアドレスを逆順にレジスタおよび/またはメモリに格納する命令を含んだ擬似間接分岐命令に対応する処理コードを呼び出す呼出手順と、
    を含んだことを特徴とする。
  15. 前記呼出手順は、汎用レジスタに記憶された分岐先のアドレスに処理を移行させる間接分岐命令の処理コードを、前記レジスタおよび/またはメモリに格納された分岐先のアドレスに処理を移行させる擬似間接分岐命令の処理コードで代用することを特徴とする請求項14に記載の記憶媒体。
  16. 前記擬似間接分岐命令の処理コードを前記コンピュータに実行させて、間接的に、前記コンピュータに搭載された所定の記憶領域に間接分岐命令の分岐先のアドレスを逆順に格納させることを特徴とする請求項15に記載の記憶媒体。
  17. 前記ソースプログラムは分岐を伴う制御文が記述されており、前記擬似間接分岐命令の処理コードは、前記制御文が記述されるまでの区間ごとに前記間接分岐命令の分岐先のアドレスを逆順にレジスタに格納する命令を含んでいることを特徴とする請求項16に記載の記憶媒体。
  18. ソースプログラムを解釈し、ソースプログラムの内容に応じた処理コードを選択して当該処理コードを呼び出すインタプリタをコンピュータに実行させる間接分岐処理方法であって、
    前記インタプリタは、
    記憶装置に記憶されたソースプログラムを読み込む読込工程と、
    前記ソースプログラムに応じた処理コードを選択し、当該処理コードが間接分岐命令に対応する処理コードである場合に、前記間接分岐命令に対応する処理コードの代わりに、当該間接分岐命令の分岐先のアドレスを逆順にレジスタおよび/またはメモリに格納する命令を含んだ擬似間接分岐命令に対応する処理コードを呼び出す呼出工程と、
    を含んでいることを特徴とする間接分岐処理方法。
JP2009521463A 2007-07-02 2007-07-02 間接分岐処理プログラムおよび間接分岐処理方法 Pending JPWO2009004709A1 (ja)

Applications Claiming Priority (1)

Application Number Priority Date Filing Date Title
PCT/JP2007/063241 WO2009004709A1 (ja) 2007-07-02 2007-07-02 間接分岐処理プログラムおよび間接分岐処理方法

Publications (1)

Publication Number Publication Date
JPWO2009004709A1 true JPWO2009004709A1 (ja) 2010-08-26

Family

ID=40225779

Family Applications (1)

Application Number Title Priority Date Filing Date
JP2009521463A Pending JPWO2009004709A1 (ja) 2007-07-02 2007-07-02 間接分岐処理プログラムおよび間接分岐処理方法

Country Status (4)

Country Link
US (1) US20100095102A1 (ja)
EP (1) EP2182433A4 (ja)
JP (1) JPWO2009004709A1 (ja)
WO (1) WO2009004709A1 (ja)

Families Citing this family (7)

* Cited by examiner, † Cited by third party
Publication number Priority date Publication date Assignee Title
US7818551B2 (en) * 2007-12-31 2010-10-19 Microsoft Corporation Feedback mechanism for dynamic predication of indirect jumps
KR20120064446A (ko) 2010-12-09 2012-06-19 삼성전자주식회사 컴퓨팅 시스템 상의 바이트코드의 분기 처리 장치 및 방법
WO2013101152A1 (en) 2011-12-30 2013-07-04 Intel Corporation Embedded branch prediction unit
CN103294518B (zh) * 2012-12-31 2016-04-27 北京北大众志微系统科技有限责任公司 一种解释器中间接跳转预测方法及系统
US9442736B2 (en) 2013-08-08 2016-09-13 Globalfoundries Inc Techniques for selecting a predicted indirect branch address from global and local caches
JP5863855B2 (ja) * 2014-02-26 2016-02-17 ファナック株式会社 分岐命令を高速に処理するためのインストラクションキャッシュを有するプログラマブルコントローラ
TWI660307B (zh) 2017-06-09 2019-05-21 國立交通大學 二元碼轉譯裝置及方法

Citations (2)

* Cited by examiner, † Cited by third party
Publication number Priority date Publication date Assignee Title
JPS62293434A (ja) * 1986-06-12 1987-12-21 Nec Corp 分岐先予測制御方式
US6640297B1 (en) * 2000-06-19 2003-10-28 Transmeta Corporation Link pipe system for storage and retrieval of sequences of branch addresses

Family Cites Families (5)

* Cited by examiner, † Cited by third party
Publication number Priority date Publication date Assignee Title
US6157999A (en) * 1997-06-03 2000-12-05 Motorola Inc. Data processing system having a synchronizing link stack and method thereof
US5931944A (en) * 1997-12-23 1999-08-03 Intel Corporation Branch instruction handling in a self-timed marking system
US6243805B1 (en) * 1998-08-11 2001-06-05 Advanced Micro Devices, Inc. Programming paradigm and microprocessor architecture for exact branch targeting
US6823447B2 (en) * 2001-03-01 2004-11-23 International Business Machines Corporation Software hint to improve the branch target prediction accuracy
JP4286768B2 (ja) * 2004-11-30 2009-07-01 富士通株式会社 分岐予測装置およびその制御方法

Patent Citations (2)

* Cited by examiner, † Cited by third party
Publication number Priority date Publication date Assignee Title
JPS62293434A (ja) * 1986-06-12 1987-12-21 Nec Corp 分岐先予測制御方式
US6640297B1 (en) * 2000-06-19 2003-10-28 Transmeta Corporation Link pipe system for storage and retrieval of sequences of branch addresses

Also Published As

Publication number Publication date
US20100095102A1 (en) 2010-04-15
EP2182433A4 (en) 2011-06-29
EP2182433A1 (en) 2010-05-05
WO2009004709A1 (ja) 2009-01-08

Similar Documents

Publication Publication Date Title
US5901308A (en) Software mechanism for reducing exceptions generated by speculatively scheduled instructions
US5966537A (en) Method and apparatus for dynamically optimizing an executable computer program using input data
KR101523020B1 (ko) 결합된 분기 타깃 및 프레디킷 예측
KR101687213B1 (ko) 동적으로 로딩하는 그래프 기반 계산
JP5681473B2 (ja) プログラムの最適化装置、最適化方法および最適化プログラム
EP1728155B1 (en) Method and system for performing link-time code optimization without additional code analysis
US7140010B2 (en) Method and apparatus for simultaneous optimization of code targeting multiple machines
US20020066081A1 (en) Speculative caching scheme for fast emulation through statically predicted execution traces in a caching dynamic translator
JPWO2009004709A1 (ja) 間接分岐処理プログラムおよび間接分岐処理方法
CN101299192B (zh) 一种非对齐访存的处理方法
WO1998037485A1 (en) Method and apparatus for forwarding of operands in a computer system
US7320121B2 (en) Computer-implemented system and method for generating embedded code to add functionality to a user application
US8499293B1 (en) Symbolic renaming optimization of a trace
Packirisamy et al. Exploring speculative parallelism in SPEC2006
US7849292B1 (en) Flag optimization of a trace
CN101847096B (zh) 包含栈变量函数的优化方法
JP2015201119A (ja) コンパイルプログラム、コンパイル方法およびコンパイル装置
Suganuma et al. A region-based compilation technique for dynamic compilers
Kim et al. Dynamic binary translation for accumulator-oriented architectures
JP2007532990A (ja) ヘルパーサブスレッドを含むスレッドの実行の明示的ソフトウェア制御のための方法及び構造
JP4684571B2 (ja) エミュレーションコンピュータ技術を実行する直接命令
Petrov et al. Low-power branch target buffer for application-specific embedded processors
JP4420055B2 (ja) マルチスレッドプロセッサ及びそれに用いるスレッド間同期操作方法
KR20120064446A (ko) 컴퓨팅 시스템 상의 바이트코드의 분기 처리 장치 및 방법
US7937564B1 (en) Emit vector optimization of a trace

Legal Events

Date Code Title Description
A131 Notification of reasons for refusal

Free format text: JAPANESE INTERMEDIATE CODE: A131

Effective date: 20120619

A02 Decision of refusal

Free format text: JAPANESE INTERMEDIATE CODE: A02

Effective date: 20121016