(57)【特許請求の範囲】
【請求項１】
単一のプログラムを複数のスレッドに分割し複数のスレッド実行部で並列に実行するマルチスレッド実行方法において、ターム後で確定前のスレッドを持つスレッド実行部の前記スレッドをその直後の子スレッドへマージし、前記スレッド実行部へ新たなスレッドをフォークすることを特徴とするマルチスレッド実行方法。
【請求項２】
単一のプログラムを複数のスレッドに分割し複数のスレッド実行部で並列に実行するマルチスレッド実行方法において、個々のスレッド実行部を、フォーク可能なフリー状態、スレッドを実行しているビジー状態、ターム後で確定前のスレッドを持つターム状態の３つの状態で管理し、新たなスレッドをフォークする際、フリー状態のスレッド実行部が存在しない場合、ターム状態のスレッド実行部が持つスレッドをその直後の子スレッドへマージして当該スレッド実行部をフリー状態にし、新たなスレッドをフォークすることを特徴とするマルチスレッド実行方法。
【請求項３】
個々のスレッド実行部毎に仮実行用バッファを備え、ターム状態のスレッド実行部が持つスレッドをその直後の子スレッドへマージする際、ターム状態のスレッド実行部の仮実行用バッファに保存されている仮実行結果を前記子スレッドを実行するスレッド実行部の仮実行用バッファへ転送する請求項１または２記載のマルチスレッド実行方法。
【請求項４】
個々のスレッド実行部毎に仮実行用バッファを兼ねるキャッシュメモリを備え、前記キャッシュメモリの各キャッシュライン毎に、ターム後で確定前のスレッドが生成したデータと前記マージ後に新たに生成されたスレッドが生成したデータとを区別するバージョン情報を保持し、各スレッド実行部のキャッシュメモリは、他のスレッド実行部からのアクセスに対して、前記バージョン情報とスレッドの逐次実行順序とを考慮した選択的な応答を行う請求項１または２記載のマルチスレッド実行方法。
【請求項５】
各スレッド実行部で実行されるスレッドが自身のキャッシュメモリに書き込みを行う際、書き込み対象となるキャッシュラインのバージョン情報が自スレッドのバージョンより古い場合、当該キャッシュラインのバージョンが親スレッドの終了に応じて適宜変更されて自スレッドのバージョンに一致するまで待ち合わせを行う請求項４記載のマルチスレッド実行方法。
【請求項６】
単一のプログラムを複数のスレッドに分割し複数のスレッド実行部で並列に実行する並列プロセッサシステムにおいて、各スレッド実行部を相互に接続する通信路と、ターム後で確定前のスレッドを持つスレッド実行部の前記スレッドをその直後の子スレッドへマージし、前記スレッド実行部へ新たなスレッドをフォークする手段とを含むことを特徴とする並列プロセッサシステム。
【請求項７】
単一のプログラムを複数のスレッドに分割し複数のスレッド実行部で並列に実行する並列プロセッサシステムにおいて、各スレッド実行部を相互に接続する通信路と、個々のスレッド実行部を、フォーク可能なフリー状態、スレッドを実行しているビジー状態、ターム後で確定前のスレッドを持つターム状態の３つの状態で管理する手段と、新たなスレッドをフォークする際、フリー状態のスレッド実行部が存在しない場合、ターム状態のスレッド実行部が持つスレッドをその直後の子スレッドへマージして当該スレッド実行部をフリー状態にし、新たなスレッドをフォークする手段とを含むことを特徴とする並列プロセッサシステム。
【請求項８】
個々のスレッド実行部毎に仮実行用バッファを備え、ターム状態のスレッド実行部が持つスレッドをその直後の子スレッドへマージする際、ターム状態のスレッド実行部の仮実行用バッファに保存されている仮実行結果を前記子スレッドを実行するスレッド実行部の仮実行用バッファへ転送する構成を有する請求項６または７記載の並列プロセッサシステム。
【請求項９】
個々のスレッド実行部毎に仮実行用バッファを兼ねるキャッシュメモリを備え、前記キャッシュメモリの各キャッシュライン毎に、ターム後で確定前のスレッドが生成したデータと前記マージ後に新たに生成されたスレッドが生成したデータとを区別するバージョン情報を保持し、各スレッド実行部のキャッシュメモリは、他のスレッド実行部からのアクセスに対して、前記バージョン情報とスレッドの逐次実行順序とを考慮した選択的な応答を行う構成を有する請求項６または７記載の並列プロセッサシステム。
【請求項１０】
各スレッド実行部のキャッシュメモリは、自スレッド実行部で実行されるスレッドからの書き込み時、書き込み対象となるキャッシュラインのバージョン情報が前記スレッドのバージョンより古い場合、当該キャッシュラインのバージョンが親スレッドの終了に応じて適宜変更されて前記スレッドのバージョンに一致するまで待ち合わせを行う構成を有する請求項９記載の並列プロセッサシステム。
【発明の詳細な説明】
【０００１】
【発明の属する技術分野】
本発明は単一のプログラムを複数のスレッドに分割して複数のプロセッサにより並列に実行する並列プロセッサシステムに関し、特にターム後で確定前のスレッドをもつプロセッサへのフォークを可能にした並列プロセッサシステムに関する。
【０００２】
【従来の技術】
単一のプログラムを並列プロセッサシステムで並列に処理する手法として、プログラムをスレッドと呼ぶ命令流に分割して複数のプロセッサで並列に実行するマルチスレッド実行方法があり、この方法を記載した文献として、特開平１０−２７１０８号公報（以下、文献１と称す）、「Ｏｎ−Ｃｈｉｐ  Ｍｕｌｔｉｐｒｏｃｅｓｓｏｒ指向  制御並列アーキテクチャＭＵＳＣＡＴの提案」（並列処理シンポジウムＪＳＰＰ９７論文集、情報処理学会、ｐｐ．２２９−２３６、Ｍａｙ  １９９７）（以下、文献２と称す）、特開平１０−７８８８０号公報（以下、文献３と称す）、「非数値計算プログラムのスレッド間命令レベル並列を利用するプロセッサ・アーキテクチャＳＫＹ」（並列処理シンポジウムＪＳＰＰ９８論文集、情報処理学会、ｐｐ．８７−９４、平成１０年６月）（以下、文献４と称す）、「Ｍｕｌｔｉｓｃａｌａｒ  Ｐｒｏｃｅｓｓｏｒ」（Ｇ．Ｓ．Ｓｏｈｉ，Ｓ．Ｅ．Ｂｒｅａｃｈ  ａｎｄ  Ｔ．Ｎ．Ｖｉｊａｙｋｕｍａｒ，Ｔｈｅ  ２２ｎｄ  Ｉｎｔｅｒｎａｔｉｏｎａｌ  Ｓｙｍｐｏｓｉｕｍ  ｏｎ  Ｃｏｍｐｕｔｅｒ  Ａｒｃｈｉｔｅｃｔｕｒｅ，ＩＥＥＥ  Ｃｏｍｐｕｔｅｒ  ＳｏｃｉｅｔｙＰｒｅｓｓ，１９９５，ページ４１４−４２５）（以下、文献５と称す）等がある。以下、これらの文献に記載された従来の技術について説明する。
【０００３】
一般にマルチスレッド実行方法において、他のプロセッサ上に新たなスレッドを生成することを、スレッドをフォーク（ｆｏｒｋ）すると言い、フォーク動作を行った側のスレッドを親スレッド、生成された新しいスレッドを子スレッド、スレッドをフォークする箇所をフォーク点、子スレッドの先頭箇所をフォーク先アドレスまたは子スレッドの開始点と呼ぶ。文献１〜４では、スレッドのフォークを指示するためにフォーク点にフォーク命令が挿入される。フォーク命令にはフォーク先アドレスが指定され、フォーク命令の実行によりそのフォーク先アドレスから始まる子スレッドが他プロセッサ上に生成され、子スレッドの実行が開始される。また、スレッドの処理を終了させるターム（ｔｅｒｍ）命令と呼ばれる命令が用意されており、各プロセッサはターム命令を実行することによりスレッドの処理を終了する。
【０００４】
図１５にマルチスレッド実行方法の処理の概要を示す。同図（ａ）は３つのスレッドＡ、Ｂ、Ｃに分割された単一のプログラムを示す。このプログラムを単一のプロセッサで処理する場合、同図（ｂ）に示すように１つのプロセッサＰＥがスレッドＡ、Ｂ、Ｃを順番に処理していく。これに対して文献１〜５のマルチスレッド実行方法では、同図（ｃ）に示すように、１つのプロセッサＰＥ１にスレッドＡを実行させ、プロセッサＰＥ１でスレッドＡを実行している最中に、スレッドＡに埋め込まれたフォーク命令によってスレッドＢを他のプロセッサＰＥ２に生成し、プロセッサＰＥ２においてスレッドＢを実行させる。また、プロセッサＰＥ２はスレッドＢに埋め込まれたフォーク命令によってスレッドＣをプロセッサＰＥ３に生成する。プロセッサＰＥ１、ＰＥ２はそれぞれスレッドＢ、Ｃの開始点の直前に埋め込まれたターム命令によってスレッドの処理を終了し、プロセッサＰＥ３はスレッドＣの最後の命令を実行すると、その次の命令（一般にはシステムコール命令）を実行する。このように複数のプロセッサでスレッドを同時に並行して実行することにより、逐次処理に比べて性能の向上が図られる。
【０００５】
従来の他のマルチスレッド実行方法として、図１５（ｄ）に示すように、スレッドＡを実行しているプロセッサＰＥ１からフォークを複数回行うことにより、プロセッサＰＥ２にスレッドＢを、またプロセッサＰＥ３にスレッドＣをそれぞれ生成するマルチスレッド実行方法も存在する。この図１５（ｄ）のモデルに対して、同図（ｃ）に示したようにスレッドはその生存中に高々１回に限って有効な子スレッドを生成することができるという制約を課したマルチスレッド実行方法をフォーク１回モデルと呼ぶ。本発明はこのようなフォーク１回モデルを前提とする。フォーク１回モデルでは、スレッド管理の大幅な簡略化が可能となり、現実的なハードウェア規模でスレッド管理部のハードウェア化が実現できる。また、個々のプロセッサは子スレッドを生成する他プロセッサが１プロセッサに限定される。このため文献１〜４では、隣接するプロセッサを単方向にリング状に接続した並列プロセッサシステムを使ってマルチスレッド実行を行っている。
【０００６】
従来の並列プロセッサシステムでは、個々のプロセッサはフリー状態、ビジー状態の２種類の状態で管理される。フリー状態は、プロセッサ資源が解放されており、何時でも新たなスレッドの実行を開始できる状態である。プロセッサを単方向にリング状に接続した並列プロセッサシステムでは、或るプロセッサからフォーク要求があった場合、その隣接プロセッサがフリー状態である場合に限って子スレッドのフォークが行われる。フリー状態のプロセッサがスレッドの実行を開始するとビジー状態に遷移し、そのスレッドの実行が終了しスレッド管理部で終了許可が得られるとフリー状態に戻る。スレッド管理部で終了許可が得られることを条件としているのは、逐次的な実行順序関係を持つ複数のスレッドを並列に実行する際、子スレッドは親スレッドが終了しなければ終了できないという制約があり、この制約をスレッドの生成、終了を管理するスレッド管理部で保証するためである。
【０００７】
子スレッドをフォークした場合、親スレッドから子スレッドへのレジスタ継承が必要になる。このレジスタ継承に関しては、一般に２通りの方式がある。１つは、文献１〜３の並列プロセッサシステムで採用されているように、親スレッドのフォーク時点のレジスタファイルの内容だけを継承対象とし、フォーク後に更新されたレジスタは継承しない方式である。もう１つは、文献４、５の並列プロセッサシステムで採用されているように、フォーク後に更新されたレジスタも継承対象とする方式である。前者をフォーク時レジスタ転送方式、後者をフォーク後レジスタ転送方式と呼ぶ。
【０００８】
マルチスレッド実行方法では、実行の確定した先行スレッドを並列に実行することを基本とするが、実際のプログラムでは実行の確定するスレッドが充分に得られない場合も多い。また、動的に決定される依存やコンパイラ解析能力の限界等により並列化率が低く抑えられ所望の性能が得られない可能性が生じる。このためスレッド並列処理では、スレッド間の順序関係に起因するメモリ依存関係に考慮し、プログラムの正しい実行結果を保証しつつ、スレッド間の順序関係によらずにスレッドの実行を並列に行うことで、プログラム実行を高速化するというスレッド単位の非プログラム順序実行が採用されている。
【０００９】
スレッド単位の非プログラム順序実行においても、正しいプログラムの実行結果を得るためには、スレッドが含む命令間の依存関係の解消や保証が必要である。しかしながら、命令単位の非プログラム順序実行と同様に、特にメモリに関する正依存関係に対しては、本質的にプログラム順序で実行する必要があり、かつ、確定的にプログラム順序実行を行うと、非プログラム順序実行の実行性能向上の効果が十分得られないという問題がある。特に、スレッド単位の非プログラム順序実行では、複数の命令からなるスレッド単位で、非プログラム順序実行が妨げられるので、より問題は深刻である。この問題への対応としては、命令単位の非プログラム順序実行と同様に、データ依存投機実行が有効である。すわなち、スレッドが含む命令間の正依存関係の有無が判明するよりも以前に、正依存関係が存在しないと仮定して、投機的にスレッドの非プログラム順序実行を行う、スレッド単位のデータ依存投機実行である。
【００１０】
一方、メモリに関する逆依存関係及び出力依存関係に対しては、命令単位の非プログラム順序実行と同様に、ストア命令が書き込みを行うデータを、プロセッサに固有のバッファやメモリに一時的に格納するなどの対応で、逆依存関係あるいは出力依存関係を解消して、非プログラム順序実行することが可能となる。
【００１１】
例えば、それぞれが固有のキャッシュメモリを備える複数のプロセッサから構成される並列プロセッサシステムにおけるスレッド並列処理に関して、例えば特許第３１３９３９２号公報（以下、文献６と称す）に、メモリに関する逆依存関係及び出力依存関係を解消するキャッシュメモリの制御方式が開示されている。また、メモリに関する逆依存関係及び出力依存関係に加えて、正依存関係にも対応するキャッシュメモリの制御方式の例として、Ｓ．Ｇｏｐａｌ，Ｔ．Ｎ．Ｖｉｊａｙｋｕｍａｒ，  Ｊ．Ｅ．Ｓｍｉｔｈ，  Ｇ．Ｓ．Ｓｏｈｉ  らによる論文  ”Ｓｐｅｃｕｌａｔｉｖｅ  Ｖｅｒｓｉｏｎｉｎｇ  Ｃａｃｈｅ”，  Ｉｎ  Ｐｒｏｃｅｅｄｉｎｇｓ  ｏｆ  ｔｈｅ  ４ｔｈ  Ｉｎｔｅｒｎａｔｉｏｎａｌ  Ｓｙｍｐｏｓｉｕｍ  ｏｎ  Ｈｉｇｈ−Ｐｅｒｆｏｒｍａｎｃｅ  Ｃｏｍｐｕｔｅｒ  Ａｒｃｈｉｔｅｃｔｕｒｅ，Ｆｅｂｒｕａｒｙ  １９９８．  （以下、文献７と称す）がある。
【００１２】
その他、文献２に記載のＭＵＳＣＡＴでは、スレッド間の同期命令など、スレッドの並列動作を柔軟に制御するための専用命令が数多く用意されている。
【００１３】
【発明が解決しようとする課題】
隣接するプロセッサを単方向にリング状に接続した並列プロセッサシステムはハードウェアを簡素化できる利点を有するが、スレッドの粒度が異なる場合などにプロセッサ資源を有効に利用できず、スレッドの並列度が低下するという課題がある。図１６にその例を示す。同図（ａ）に示すように、スレッドの粒度が比較的小さく略均一であると、スレッドｔｈ０→スレッドｔｈ１→スレッドｔｈ２→スレッドｔｈ３と順次に子スレッドのフォークが行われ、最後のプロセッサＰＥ３が子スレッドをフォークする時点で隣接プロセッサＰＥ０がフリー状態になっている確率が高い。このため、スレッドｔｈ３から子スレッドｔｈ４をフォークできる。同様に、このスレッドｔｈ４から隣接プロセッサＰＥ１に子スレッドｔｈ５をフォークでき、高い並列度が確保できる。しかし、例えばスレッドｔｈ０の粒度が他のスレッドに比べて大きいと、図１６（ｂ）に示すように、プロセッサＰＥ３が子スレッドをフォークする時点で隣接プロセッサＰＥ０はスレッドｔｈ０を実行中で未だビジー状態にあるためフォークが行えず、スレッドの並列度が低下する。
【００１４】
他方、文献１の図３に示される並列化プロセッサシステムでは、複数のプロセッサを共通バスで相互に接続することにより、個々のプロセッサから子スレッドをフォークする他プロセッサを隣接プロセッサに限定しない構成を採用している。しかし、個々のプロセッサの状態をフリー状態とビジー状態で管理し、フリー状態のプロセッサの中から子スレッドをフォークするプロセッサを選択するようにしており、然も図１６（ｂ）のプロセッサＰＥ１のように親スレッドｔｈ０が未だ終了していないスレッドｔｈ１を実行しているプロセッサはビジー状態と管理している。従って、プロセッサＰＥ３のスレッドｔｈ３からプロセッサＰＥ１に子スレッドをフォークすることはできない。
【００１５】
また、スレッドｔｈ１が投機スレッドの場合、プロセッサＰＥ１の資源を解放する際にスレッドｔｈ１の処理結果の取り扱いが問題となる。何故なら、スレッドｔｈ１は親スレッドｔｈ０から取り消される可能性があり、スレッドｔｈ１の処理結果をメインメモリに書き戻すことはできず、また、スレッドｔｈ２等のスレッドｔｈ１の子スレッドはスレッドｔｈ１の処理結果を引き継ぐ必要があるためスレッドｔｈ１の処理結果をキャンセルすることはできないからである。
【００１６】
本発明はこのような事情に鑑みて提案されたものであり、その目的は、プロセッサ資源の有効活用が可能でスレッド並列度を高めることができる新規なマルチスレッド実行方法及び並列プロセッサシステムを提供することにある。
【００１７】
【課題を解決するための手段】
本発明は、単一のプログラムを複数のスレッドに分割し複数のスレッド実行部で並列に実行するマルチスレッド実行方法及び並列プロセッサシステムにおいて、ターム後で確定前のスレッドを持つスレッド実行部の前記スレッドをその直後の子スレッドへマージし、前記スレッド実行部へ新たなスレッドをフォークすることを基本とする。より具体的には、個々のスレッド実行部を、フォーク可能なフリー状態、スレッドを実行しているビジー状態、ターム後で確定前のスレッドを持つターム状態の３つの状態で管理し、新たなスレッドをフォークする際、フリー状態のスレッド実行部が存在しない場合、ターム状態のスレッド実行部が持つスレッドをその直後の子スレッドへマージして当該スレッド実行部をフリー状態にし、新たなスレッドをフォークする。これにより、プロセッサ資源の有効活用が可能になり、スレッド並列度を高めることができる。
【００１８】
ターム後で確定前のスレッドの仮実行結果の取り扱いに関しては、例えば、ターム状態のスレッド実行部が持つスレッドをその直後の子スレッドへマージする際、ターム状態のスレッド実行部の仮実行用バッファに保存されている仮実行結果を前記子スレッドを実行するスレッド実行部の仮実行用バッファへ転送することで対処する。また、より効率を高めるために、個々のスレッド実行部毎に仮実行用バッファを兼ねるキャッシュメモリを備え、前記キャッシュメモリの各キャッシュライン毎に、ターム後で確定前のスレッドが生成したデータと前記マージ後に新たに生成されたスレッドが生成したデータとを区別するバージョン情報を保持し、各スレッド実行部のキャッシュメモリは、他のスレッド実行部からのアクセスに対して、前記バージョン情報とスレッドの逐次実行順序とを考慮した選択的な応答を行うことで対処する。また、各スレッド実行部で実行されるスレッドが自身のキャッシュメモリに書き込みを行う際、書き込み対象となるキャッシュラインのバージョン情報が自スレッドのバージョンより古い場合、当該キャッシュラインのバージョンが親スレッドの終了に応じて適宜変更されて自スレッドのバージョンに一致するまで待ち合わせを行うことで対処する。
【００１９】
【作用】
ターム後で確定前のスレッドを持つスレッド実行部は、従来の並列プロセッサシステムではビジー状態として管理されていたが、本発明ではターム状態として管理し、ビジー状態と区別する。そして、フリー状態のスレッド実行部が１つも存在しない場合には、ターム状態のスレッド実行部のスレッドをその直後の子スレッドへマージすることにより、当該スレッド実行部をフリー状態にし、新たなスレッドをフォークする。例えば図１６（ｂ）と同様な状況を想定した図１の実行シーケンスにおいて、プロセッサＰＥ３が子スレッドをフォークする時点で他の全てのプロセッサＰＥ０、ＰＥ１、ＰＥ２がビジー状態にあるため、従来の並列プロセッサシステムではフォークは行えないが、本発明では、プロセッサＰＥ１のターム後で確定前のスレッドｔｈ１をその直後の子スレッドｔｈ２にマージすることにより、フリー状態となったプロセッサＰＥ１にスレッドｔｈ３からスレッドｔｈ４をフォークすることが可能になる。
【００２０】
【発明の実施の形態】
次に本発明の実施の形態の例について図面を参照して詳細に説明する。
【００２１】
図２を参照すると、本発明の並列プロセッサシステムの一例は、４スレッド並列実行型プロセッサであり、４個のスレッド実行部１−ｉ（ｉ＝０〜３）が第１のバス２及び第２のバス４に接続され、第１のバス２にはスレッドの生成、終了を管理するスレッド管理部３が接続され、第２のバス４には全てのスレッド実行部１−ｉで共有のメモリ（メインメモリ）５が接続されている。この例では、４スレッド並列実行型プロセッサを取り上げたが、８スレッドや１６スレッドの並列実行型プロセッサ等、一般にｎ（≧２）スレッド並列実行型プロセッサに対して本発明は適用可能である。また、スレッド実行部どうしを相互に接続する通信路（バス４）は、本実施の形態では共通バス形式としたが、クロスバスイッチ等の他の種類の通信路を採用することも可能である。なお、好ましくは、全てのスレッド実行部１−ｉはメモリ５及びスレッド管理部３と共に１つの半導体チップ上に集積化される。
【００２２】
各スレッド実行部１−ｉは、プロセッサを含んでいる。各プロセッサは、プログラムカウンタ（以下、ＰＣと称す）及びレジスタファイルを独立に有し、ＰＣに従って、メモリ５中のスレッドの命令を同時にフェッチ、解釈、実行する機能を有している。また、各スレッド実行部１−ｉは、スレッド実行の取り消し（キャンセル）が可能なようにスレッドを仮実行状態で実行する機能を有している。仮実行状態でスレッドを実行した際のそのスレッドの処理結果は、仮実行用バッファ（ｔｅｍｐｏｒａｒｙ  ｂｕｆｆｅｒ）に保存される。仮実行用バッファとしては、それ専用のバッファを使用する構成や、個々のプロセッサが独自に有するキャッシュメモリを仮実行用バッファとして兼ねる構成などが採用される。
【００２３】
各スレッド実行部１−ｉは、スレッド管理部３からバス２を通じてターゲットＰＣ値を伴うスレッド開始要求が送信された時点で、スレッドの実行を仮実行状態で開始する。この時点で当該スレッド実行部１−ｉはビジー状態として管理される。スレッドの実行を終了するスレッド実行部１−ｉは、スレッド管理部３に対してバス２を通じてスレッド終了通知を送信する。このスレッド終了通知は、当該スレッド実行部１−ｉが最古親スレッドを実行していた場合にスレッド管理部３で受理されて当該スレッド実行部１−ｉはフリー状態として管理され、プロセッサ１−ｉにスレッド終了許可が返却される。プロセッサ１−ｉはスレッド終了許可を受信した時点で仮実行状態を解き、スレッドの実行を終えてプロセッサ資源を解放する。他方、スレッド終了通知を送信したスレッド実行部１−ｉで実行されていたスレッドが最古親スレッドでない場合、スレッド管理部３は当該スレッド実行部１−ｉにスレッド終了許可を出さず、当該スレッド実行部１−ｉをターム状態として管理する。ターム状態のスレッド実行部１−ｉは、その親スレッドが全て終了するか、または当該スレッド実行部１−ｉのスレッドがその直後のスレッドにマージされた時点でフリー状態として管理される。
【００２４】
各スレッド実行部１−ｉは、スレッド管理部３を通じて、実行中の親スレッドに存在するフォーク命令によって他のスレッド実行部１−ｊ（ｉ≠ｊ）に子スレッドをフォークすることができる。本実施の形態では、各スレッド実行部１−ｉのフォーク先はその隣接するスレッド実行部にのみ限定されない。各スレッド実行部１−ｉは、子スレッドのフォークを行う際、バス２を通じてスレッド管理部３に対し、子スレッドのフォーク先アドレス（開始ＰＣ値）を伴うフォーク要求を送信する。スレッド管理部３は、フォーク要求を受信すると、他のスレッド実行部の状態に基づいて、他スレッド実行部１−ｊに対するフォークが可能か否かを判定する。その時点でフリー状態のスレッド実行部が存在していれば直ちにフォーク可能である。また、その時点でフリー状態のスレッド実行部が存在していなくてもターム状態のスレッド実行部が存在していれば、ターム状態のスレッド実行部のスレッドをその直後の子スレッドへマージすることによって、ターム状態のスレッド実行部をフリー状態にすることでフォークが可能である。
【００２５】
フォーク可能ならばフォーク先のスレッド実行部１−ｊに対してフォーク先アドレスを伴うスレッド開始要求を送信する一方、フォーク要求元のスレッド実行部１−ｉに対しては、フォーク応答を返却する。フォーク応答を受信したスレッド実行部１−ｉは、フォーク先のスレッド実行部１−ｊのレジスタファイルに対して、親スレッドのレジスタファイルの全内容をバス４を通じてコピーするか、当該子スレッドで必要なレジスタの値だけをコピーすることにより、レジスタ継承を行う。他方、スレッド実行部１−ｉからのフォーク要求時、他スレッド実行部１−ｊに対するフォークが不可能ならば、スレッド管理部３はその旨を要求元のスレッド実行部１−ｉに通知する。スレッド実行部１−ｉは、例えばフォークが可能になるまで処理を待ち合わせる。
【００２６】
図３を参照すると、スレッド管理部３の一例は、スレッド管理シーケンサ３０１とスレッド状態テーブル３０２とから構成される。スレッド状態テーブル３０２は、スレッド実行部１−ｉと１対１に対応する状態エントリ３０３−ｉ、親スレッド実行部番号エントリ３０４−ｉ及び子スレッド実行部番号エントリ３０５−ｉを有する。個々の状態エントリ３０３−ｉは、対応するスレッド実行部１−ｉがビジー状態か、ターム状態か、フリー状態かを記録するために使用される。個々の親スレッド実行部番号エントリ３０４−ｉは、対応するスレッド実行部１−ｉで実行中のスレッドの親スレッドが実行されている他スレッド実行部の番号を示す。個々の子スレッド実行部番号エントリ３０５−ｉは、対応するスレッド実行部１−ｉで実行中のスレッドの直後の子スレッドが実行されている他スレッド実行部の番号を示す。スレッド管理シーケンサ３０１は、このようなスレッド状態テーブル３０２を用いて各スレッド実行部１−ｉにおけるスレッド生成、スレッド終了を管理する。スレッド実行部１−ｉからフォーク要求、スレッド終了通知を受信した際のスレッド管理シーケンサ３０１の処理例を図４及び図５に示す。
【００２７】
図４を参照すると、スレッド管理シーケンサ３０１は、スレッド実行部１−ｉからフォーク要求を受信すると、スレッド状態テーブル３０２を参照して、フリー状態のスレッド実行部が存在するか否かを調べる（ステップＳ１）。フリー状態のスレッド実行部が存在した場合、その内から１つのスレッド実行部１−ｊを選択し（ステップＳ２）、スレッド管理テーブル３０２を更新する（ステップＳ３）。具体的には、ステップＳ２で選択したスレッド実行部１−ｊに対応する状態エントリ３０３−ｊをフリー状態からビジー状態に変更し、親スレッド実行部番号エントリ３０４−ｊにフォーク要求を行ったスレッド実行部１−ｉの番号を設定する。また、フォーク要求を行ったスレッド実行部１−ｉに対応する子スレッド実行部番号エントリ３０５−ｉに、ステップＳ２で選択したスレッド実行部１−ｊの番号を設定する。そして、フォーク要求に付随するフォーク先アドレスを添えたスレッド開始要求をフォーク先のスレッド実行部１−ｊに送信すると共に、要求元のスレッド実行部１−ｉに対してフォーク応答を送信する（ステップＳ４）。
【００２８】
他方、フリー状態のスレッド実行部が１つも存在しなかった場合（ステップＳ１でＮＯ）、スレッド管理部３は、スレッド状態テーブル３０２を参照して、ターム状態のスレッド実行部が存在するか否かを調べる（ステップＳ５）。ターム状態のスレッド実行部が１つも存在しない場合、子スレッドのフォークは物理的に不可能なので、その旨をフォーク要求元のスレッド実行部１−ｉへ送信する（ステップＳ８）。一方、ターム状態のスレッド実行部が存在した場合、その内から１つのスレッド実行部１−ｊを選択し（ステップＳ６）、この選択したスレッド実行部１−ｊのスレッドを当該スレッドが生成した子スレッドへマージし、当該スレッド実行部１−ｊをフリー状態とする（ステップＳ７）。そして、ステップＳ２〜Ｓ４を実行することにより、今回フリー状態にしたスレッド実行部に対する子スレッドのフォークを可能にする。
【００２９】
ステップＳ７の処理をより具体的に説明する。先ず、ステップＳ６で選択したスレッド実行部１−ｊに対応する状態エントリ３０３−ｊをターム状態からフリー状態に変更する。次に、子スレッド実行部番号エントリ３０５−ｊに設定されている番号で特定されるスレッド実行部１−ｋに対応する親スレッド実行部番号エントリ３０４−ｋに、スレッド実行部１−ｊに対応する親スレッド実行部番号エントリ３０３−ｊの内容を設定する。次に、親スレッド実行部番号エントリ３０５−ｊに設定されている番号で特定されるスレッド実行部１−ｍに対応する子スレッド実行部番号エントリ３０５−ｍに、スレッド実行部１−ｊに対応する子スレッド実行部番号エントリ３０５−ｊの内容を設定する。最後に、スレッド実行部１−ｊに対応する子スレッド実行部番号エントリ３０４−ｊをＮＵＬＬにする。これにより、スレッドの管理上、スレッド実行部１−ｊのスレッドがその直後の子スレッド実行部へマージされたことになる。
【００３０】
図３でターム状態になっているスレッド実行部１−１を例に説明すると、状態エントリ３０３−１をターム状態からフリー状態に変更し、子スレッドを実行しているスレッド実行部１−２の親スレッド実行部番号エントリ３０４−２に親スレッド実行部番号エントリ３０４−１の内容「０」を設定し、親スレッドを実行しているスレッド実行部１−０の子スレッド実行部番号エントリ３０５−０に子スレッド実行部番号エントリ３０５−１の内容「２」を設定し、子スレッド実行部番号エントリ３０５−１の内容をＮＵＬＬにする。
【００３１】
以上のような処理によって、スレッドの管理上はスレッド実行部１−ｊのスレッドがその直後の子スレッドへマージされたことになるわけであるが、スレッド実行部１−ｊに残っている仮実行結果の取り扱いが問題となる。この問題を解決する一つの方法は、スレッド実行部１−ｊの仮実行バッファの内容を、バス４を通じて、マージした子スレッドを実行しているスレッド実行部の仮実行バッファに転送して格納し、スレッド実行部１−ｊの仮実行バッファを解放することである。但し、この方法はデータ転送に伴うオーバヘッドが大きいため、性能低下が懸念される。他の方法は、スレッド実行部１−ｊの仮実行バッファにおいて、マージしたスレッドの仮実行結果と、当該スレッド実行部１−ｊで新たに実行される新スレッドの仮実行結果とを区別して管理し、マージしたスレッドの仮実行結果はその子スレッドに有効なデータとして扱うが、当該スレッド実行部１−ｊで新たに実行された新スレッドの仮実行結果はマージしたスレッドから当該新スレッドまでの間のスレッドでは無効なデータとして扱う方法である。この後者の方法については後に詳細な実施例を挙げて説明する。
【００３２】
図５を参照すると、スレッド管理シーケンサ３０１は、何れかのスレッド実行部１−ｉからスレッド終了通知を受信すると、スレッド状態テーブル３０２における当該スレッド実行部１−ｉに対応する親スレッド実行部番号エントリ３０４−ｉがＮＵＬＬにクリアされているか否かによって、当該スレッド実行部１−ｉで実行中のスレッドの親スレッドが存在しているか否かを判定する（ステップＳ１１）。親スレッドが存在している場合、当該スレッド実行部１−ｉに対応する状態エントリ３０３−ｉをビジー状態からターム状態に更新する（ステップＳ１２）。
【００３３】
他方、親スレッドが存在していない場合、ステップＳ１３でスレッド状態テーブル３０２を更新する。ここでは、当該スレッド実行部１−ｉに対応する状態エントリ３０３−ｉをビジー状態からフリー状態に変更し、その子スレッド実行部番号エントリ３０５−ｉがＮＵＬＬでなければその値で特定される子スレッドを実行しているスレッド実行部１−ｊに対応する親スレッド実行部番号エントリ３０４−ｊをＮＵＬＬにクリアし、子スレッド実行部番号エントリ３０５−ｉもＮＵＬＬにクリアする。また、親スレッド実行部番号エントリ３０４−ｊをＮＵＬＬにしたスレッド実行部１−ｊの状態エントリ３０３−ｊがターム状態なら、このスレッド実行部１−ｊもフリー状態にする。具体的には、状態エントリ３０３−ｊをフリー状態に設定し、その子スレッド実行部番号エントリ３０５−ｊがＮＵＬＬでなければその値で特定される子スレッドを実行しているスレッド実行部１−ｋに対応する親スレッド実行部番号エントリ３０４−ｋをＮＵＬＬにクリアし、子スレッド実行部番号エントリ３０５−ｋもＮＵＬＬにクリアする。以下、同様に親スレッドの終了によりフリー状態にできる全てのスレッド実行部をフリー状態に変更する。そして、次のステップＳ１４では、フリー状態に変更した全てのスレッド実行部に対してスレッド終了許可を送信する。
【００３４】
例えば図３で、スレッド実行部１−０からスレッド終了通知が出された場合、状態エントリ３０３−０がフリー状態に変更され、子スレッドを実行していたスレッド実行部１−１の親スレッド実行部番号エントリ３０４−１がＮＵＬＬに設定される。また、状態エントリ３０３−１がターム状態なので、状態エントリ３０３−１がフリー状態に変更され、子スレッドを実行しているスレッド実行部１−２の親スレッド実行部番号エントリ３０４−１がＮＵＬＬに設定される。この場合、スレッド終了通知は、スレッド実行部１−０とスレッド実行部１−１に送信される。
【００３５】
以上のように本実施の形態によれば、個々のスレッド実行部をフリー状態、ビジー状態、ターム状態の３つの状態の何れかで管理し、何れかのスレッド実行部から子スレッドのフォークが要求されたとき、フリー状態のスレッド実行部が存在しなければ、ターム状態のスレッド実行部で実行終了しているが未確定のスレッドをその直後の子スレッドにマージすることによりフリー状態のスレッド実行部を動的に生成し、そのスレッド実行部に対するフォークを可能にしたことにより、プロセッサ資源の有効活用が可能になり、スレッド並列度を高めることができる。
【００３６】
次に、直後の子スレッドへマージされたスレッドの仮実行結果を効率良く扱うことができる実施例について詳細に説明する。なお、以下では、実行は終了しているが親スレッドが未だ終了していない等により処理が確定していないスレッドのことを、ｔｅｒｍ後で確定前のスレッドと呼ぶ。また、ｔｅｒｍ後で確定前のスレッドをもつプロセッサへのフォークを、空きフォークと呼ぶ。空きフォークは、ｔｅｒｍ後で確定前のスレッドを直後の子スレッドへマージし、該フォークによる新スレッドを実行することである。
【００３７】
〔キャッシュメモリにおける問題点〕
先ず、個々のプロセッサが固有に備えるキャッシュメモリを仮実行用バッファとして兼用する場合の問題点を、スレッド実行シーケンス例を示す図６を参照して説明する。図６は以下のような実行シーケンスを示している。
【００３８】
（１）プロセッサＰ０上のスレッドからプロセッサＰｉにスレッドｔｈ０がフォークされ、このスレッドｔｈ０からスレッドｃ００、ｃ０１、…、ｃ０ｎが順次に複数の他プロセッサ上にフォークされる。スレッドｃ００〜ｃ０ｎは、スレッドｔｈ０から見て子スレッドである。
（２）スレッドｃ０ｎのフォーク時、プロセッサＰｉではスレッドｔｈ０はタームしているが、親スレッドがタームしていないので、スレッドｔｈ０はｔｅｒｍ後で確定前のスレッドである。このため、スレッドｔｈ０が直後の子スレッドｃ００にマージされ、このマージによりフリー状態となったプロセッサＰｉにスレッドｃ０ｎから新スレッドｔｈ１がフォークされている。以後、この新スレッドｔｈ１からスレッドｃ１０、ｃ１１、…、ｃ１ｎが順次にフォークされる。スレッドｃ１０〜ｃ１ｎは、新スレッドｔｈ１から見て子スレッドである。
（３）スレッドｃ１ｎのフォーク時、プロセッサＰｉではスレッドｔｈ１はタームしているが、親スレッドがタームしていないので、スレッドｔｈ１はｔｅｒｍ後で確定前のスレッドである。このため、スレッドｔｈ１が直後の子スレッドｃ１０にマージされ、このマージによりフリー状態となったプロセッサＰｉにスレッドｃ１ｎから新スレッドｔｈ２がフォークされている。以後、この新スレッドｔｈ２からスレッドｃ２０、ｃ２１、…、ｃ２ｎが順次にフォークされる。スレッドｃ２０〜ｃ２ｎは、新スレッドｔｈ２から見て子スレッドである。
（４）スレッドｃ２ｎのフォーク時、プロセッサＰｉではスレッドｔｈ２はタームしているが、親スレッドがタームしていないので、スレッドｔｈ２はｔｅｒｍ後で確定前のスレッドである。このため、スレッドｔｈ２が直後の子スレッドｃ２０にマージされ、このマージによりフリー状態となったプロセッサＰｉにスレッドｃ２ｎから新スレッドｔｈ３がフォークされている。
【００３９】
このようなシーケンスが実行されている場合、ｔｅｒｍ後で確定前のスレッドｔｈ０が生成しプロセッサＰｉのキャッシュメモリ上に格納されているデータは、スレッドｔｈ０の子スレッドｃ００〜ｃ０ｎにとって有効である。しかし、空きフォークにより生成されたスレッドｔｈ１が生成しプロセッサＰｉのキャッシュメモリ上に格納されているデータは、スレッドｔｈ０からスレッドｔｈ１までのスレッドｔｈ０の子スレッドｃ００〜ｃ０ｎに対しては、プログラム順序で後であるため、有効ではない。従って、スレッドｔｈ０が生成したデータとスレッドｔｈ１が生成したデータは、スレッドｃ００〜ｃ０ｎがすべてタームするまで区別する必要がある。同様にスレッドｔｈ２、ｔｈ３が生成したデータの区別も必要である。
【００４０】
しかし、例えばスレッドｔｈ０は確定前なので、スレッドｔｈ０が生成したデータをメインメモリへ書き戻すことはできない。また、スレッドｔｈ０が生成したデータを直後の子スレッドｃ００を実行するプロセッサのキャッシュメモリへ転送し格納する方法では、そのオーバヘッドは大きく、性能低下等が発生するという問題がある。
【００４１】
〔解決する手段〕
そこで、本実施例ではこの問題を以下のようにして解決する。
１．同一キャッシュ上でデータの複数のバージョンを区別し保持する。そのために、キャッシュライン毎にバージョンを示す記憶手段（ｖｉｄ）を備え、キャッシュライン毎にバージョンを管理する。新しいバージョンは、空きフォークにより生成されて現在実行しているスレッドがストア命令等で書き込みを行った場合に発生する。それ以外では発生しない。例えば、プロセッサＰｉのキャッシュ上に、スレッドｔｈ０が生成したバージョン、スレッドｔｈ１が生成したバージョン、…、を区別して保持する。
【００４２】
２．他プロセッサ（他スレッド）  からのアクセスに対して、バージョンを参照して、スレッド順序を考慮した選択的な応答を行う。例えば、スレッドｔｈ０からスレッドｔｈ１までのスレッドｔｈ０の子スレッドｃ００〜ｃ０ｎからのアクセスには、スレッドｔｈ０のバージョンのキャッシュラインは応答するが、スレッドｔｈ１以降のバージョンのキャッシュラインは応答しない。スレッドｔｈ１からスレッドｔｈ２までのスレッドｔｈ１の子スレッドｃ１０〜ｃ１ｎからのアクセスには、スレッドｔｈ０，ｔｈ１のバージョンのキャッシュラインは応答するが、スレッドｔｈ２以降のバージョンのラインは応答しない。
【００４３】
３．バージョンの区別が不要になった際にバージョンの縮退を行う。例えば、スレッドｔｈ０からスレッドｔｈ１までのスレッドｔｈ０の子スレッドｃ００〜ｃ０ｎがすべてタームしたら、スレッドｔｈ０のバージョンとスレッドｔｈ１のバージョンの区別は不要なので、その時点でスレッドｔｈ０とスレッドｔｈ１のバージョンを縮退する。
【００４４】
４．バージョンを参照した選択的なスレッド（データ）  の確定を行う。例えば、スレッドｔｈ０が確定した場合、スレッドｔｈ０のバージョンのキャッシュラインのみを確定する。スレッドｔｈ１，ｔｈ２のバージョンのラインは未確定（投機）  のままである。
【００４５】
５．同アドレスで異なるバージョンのキャッシュラインの生成については、以下の３通りの方式の何れかで対処することができる。
ａ）；同アドレスで異なるバージョンのキャッシュラインの生成を許可する。
この場合、バージョンの縮退時に複数の（同バージョンで）  同アドレスのラインが発生してしまう場合がある。そのため縮退時に、縮退の対象のバージョンのうち、古いバージョンのラインを無効化する処理を行う。
ｂ）；同アドレスで異なるバージョンのキャッシュラインを生成しない。
空きフォークにより生成されたスレッドが書き込みを行う際に、その対象のラインが古いバージョンをもち、かつ自プロセッサが前に書き込みを行ったライン（ｄｉｒｔｙ  なライン）の場合、前記古いバージョンが現在のバージョンに縮退されるまで書き込みの実行を遅らせて、複数のバージョンの発生を回避する。
ｃ）；ｂと同様に同アドレスで異なるバージョンのキャッシュラインを生成しないが、空きフォークにより生成されたスレッドが書き込みを行う際に、その対象のラインが古いバージョンをもつｄｉｒｔｙ  なラインの場合、該ラインを直後の子スレッドを実行するプロセッサのキャッシュメモリに転送後、該ラインを無効化し、その後書き込みを実行することで、複数のバージョンの発生を回避する。
ｄ）；ｂと同様に同アドレスで異なるバージョンのキャッシュラインを生成しないが、空きフォークにより生成されたスレッドが書き込みを行う際に、その対象のラインが古いバージョンをもつｄｉｒｔｙ  なラインの場合、そのまま書き込みを実行するとともに、前記古いバージョンのデータを破棄したこと記憶しておくことで、複数のバージョンの発生を回避する。前記破棄した古いバージョンのデータに対して、他のプロセッサからアクセスがあった場合には、前記破棄した古いバージョンのデータを生成したスレッド及びそのスレッドのすべての子スレッドの実行を取り消し、その後取り消したスレッドの再実行を行うことで、データの依存関係を保証する。本方式は、例えばキャッシュライン毎に古いバージョンのデータを破棄した旨を示す記憶手段を備えることで実現できる。
【００４６】
〔実施例〕
以上のような方針に添った実施例の概略を示せば以下のようになる。
【００４７】
先ず、キャッシュラインは、有効フラグ、変更フラグ、アドレスタグ、データエントリ等に加えて、少なくともデータのバージョンを示すバージョン識別子ｖｉｄを備える。バージョン識別子ｖｉｄは自プロセッサを除くマルチプロセッサシステムが備えるプロセッサ数分のビット数をもち、それぞれが自プロセッサを除く他プロセッサに対応する。
【００４８】
ストア命令等の書き込みを行った場合、その対象ラインのバージョン識別子ｖｉｄがセットされる。セットされるビットは、マージされたスレッドを除く該スレッドのすべての親スレッドを実行するプロセッサに対応するビットであり、それ以外のビットはリセットされる。
【００４９】
あるスレッドがタームした場合、該スレッドを実行していたプロセッサを除くすべてのプロセッサのキャッシュメモリのすべてのキャッシュラインのバージョン識別子ｖｉｄにおいて、該スレッドを実行していたプロセッサに対応するビットをリセットする。この処理は、例えばバージョン識別子ｖｉｄを一括リセット機能付きメモリセルで構成することで容易に実現できる。
【００５０】
すわなち、バージョン識別子ｖｉｄはその時点での、自キャッシュラインを生成したスレッドのすべての親スレッドのうち、いまだタームしていない親スレッドを実行するプロセッサを示している。あるプロセッサＰｉ上で実行された２つのスレッドにより生成された異なるバージョンのキャッシュラインは、その２つのスレッドのプログラム順序上で間のスレッドがすべてタームした時点で、バージョン識別子ｖｉｄは同じバージョンを示し、すなわち、縮退が行われたことになる。
【００５１】
他プロセッサから自キャッシュメモリにアクセスがあった場合にキャッシュヒットしたとき、バージョン識別子ｖｉｄが参照される。バージョン識別子ｖｉｄの前記他プロセッサに対応するビットがセットされている場合、自キャッシュラインにとっての親スレッドからのアクセスと判断できる。その場合、自キャッシュラインのデータはプログラム順序で後に位置し有効ではないので、前記アクセスに対して自キャッシュメモリからは応答しない。
【００５２】
一方、バージョン識別子ｖｉｄの前記他プロセッサに対応するビットがリセットされている場合、自キャッシュラインにとっての子スレッドからのアクセスと判断できる。その場合、自キャッシュラインのデータはプログラム順序で前に位置し有効であるので、前記アクセスに対して自キャッシュメモリから適切な応答処理を行う。
【００５３】
前記タームによるバージョン識別子ｖｉｄのリセットで、バージョン識別子ｖｉｄのすべてのビットがリセットされた場合、自キャッシュラインのデータは少なくとも確定することになる。すなわち、バージョン識別子ｖｉｄのすべてのビットがリセットされているキャッシュラインのデータは、メインメモリ等に書き戻すことができる。
【００５４】
〔具体例〕
次に図７を参照して、４つのプロセッサＰ０〜Ｐ３からなるマルチプロセッサシステムにおいて、プロセッサＰ１に注目して本実施例の具体例を示す。
【００５５】
図７の（１）において、プロセッサＰ１上で実行されているスレッドｔｈ０において、アドレスＡに対するストア命令（ｓｔＡ）が実行され、アドレスＡのキャッシュラインのバージョンは１００となる。図中”  Ａ、１００”  はアドレスがＡでバージョン識別子ｖｉｄの値が１００であることを示す。バージョン識別子ｖｉｄのそれぞれのビットは左からそれぞれプロセッサＰ０、Ｐ２、Ｐ３に対応する。すなわち、この時点でスレッドｔｈ０に対してプロセッサＰ０のみで親スレッドが実行されているのでバージョン識別子ｖｉｄには１００が設定される。
【００５６】
図７の（２）において、プロセッサＰ１でスレッドｔｈ０のターム後、スレッドｃ０１から空きフォークによりスレッドｔｈ１が生成される。スレッドｔｈ０はスレッドｃ００にマージされる。このマージによってデータの転送等の処理は発生しないので、従って、空きフォークのオーバヘッドは小さい。
【００５７】
図７の（３）において、スレッドｔｈ１でアドレスＢに対するストア命令が実行される。スレッドｔｈ１の親スレッドはプロセッサＰ０、Ｐ２、Ｐ３で実行されているので、アドレスＢのキャッシュラインのバージョンは１１１（図中”Ｂ，１１１”）となる。
【００５８】
図７の（４）において、プロセッサＰ３で実行されているスレッドｃ０１で、アドレスＡに対するロード命令（ｌｄＡ）、続いてアドレスＢに対するロード命令（ｌｄＢ）が実行される。ここで上記２つのロード命令ともプロセッサＰ３のキャッシュメモリにミスするとすると、プロセッサＰ１のキャッシュメモリもアクセスされる。プロセッサＰ１のキャッシュメモリに対するアクセスにおいてヒットすると、まずアドレスＡに対してはバージョン識別子ｖｉｄが１００であるため、スレッドｃ０１はアドレスＡのキャッシュラインのバージョンを生成したスレッドｔｈ０にとっての子スレッドであることが判明し、当該アクセスに対してデータの転送等のヒット時の応答処理が行われる。一方、アドレスＢに対するアクセスにおいては、アドレスＢのキャッシュラインのバージョン識別子ｖｉｄは１１１であるため、スレッドｃ０１はアドレスＢのキャッシュラインを生成したスレッドｔｈ１の親スレッドであることが判明し、当該アクセスに対しては応答しない。このように、他プロセッサからのアクセスに対して、バージョン識別子ｖｉｄ  を参照するのみで、バージョンを考慮した選択的な応答を容易に行うことができる。
【００５９】
図７の（５）において、プロセッサＰ３で実行されていたスレッドｃ０１がタームし、その旨がプロセッサＰ１にも通知される。これにより、プロセッサＰ１のキャッシュメモリの全キャッシュラインのバージョン識別子ｖｉｄにおいて、プロセッサＰ３に対応するビットがリセットされる。アドレスＡ及びアドレスＢのキャッシュラインも該当ビットがリセットされ、それぞれ１００及び１１０になる。
【００６０】
図７の（６）において、スレッドｔｈ１からプロセッサＰ３に空きフォークが実行され、プロセッサＰ３において、スレッドｃ１０が生成される。これによりタームしたスレッドｃ０１はスレッドｔｈ１にマージされる。
【００６１】
図７の（７）において、プロセッサＰ３で実行されているスレッドｃ１０で、アドレスＡに対するロード命令（ｌｄＡ）、続いてアドレスＢに対するロード命令（ｌｄＢ）が実行される。ここで上記２つのロード命令ともプロセッサＰ３のキャッシュメモリにミスするとすると、プロセッサＰ１のキャッシュメモリもアクセスされる。この場合、プロセッサＰ１のキャッシュメモリにおいてヒットすると、アドレスＡのラインのバージョン識別子ｖｉｄは１００、アドレスＢのラインのバージョン識別子ｖｉｄは１１０であるので、共にスレッドｃ１０は子スレッドであることが判明し、今度は共に当該アクセスに対して応答することになる。このように、他プロセッサからのアクセスに対して、バージョン識別子ｖｉｄを参照するのみで、バージョンを考慮した選択的な応答が行われた。
【００６２】
図７の（８）において、プロセッサＰ１において、スレッドｔｈ１のターム後、スレッドｃ１０から空きフォークが実行され、スレッドｔｈ２が生成される。スレッドｔｈ１はスレッドｃ１０にマージされる。
【００６３】
図７の（９）において、プロセッサＰ２で実行されていたスレッドｃ００がタームし、その旨がプロセッサＰ１にも通知される。これにより、プロセッサＰ１のキャッシュメモリの全キャッシュラインのバージョン識別子ｖｉｄにおいて、プロセッサＰ２に対応するビットがリセットされる。アドレスＡ及びアドレスＢのキャッシュラインも該当ビットがリセットされ、それぞれ１００及び１００になる。すなわち、上記２つのラインは同じバージョンを持つことになる。これは、アドレスＡのバージョンを生成したスレッドｔｈ０からアドレスＢのバージョンを生成したスレッドｔｈ１までの間のスレッドｃ００及びｃ０１がこの時点ですべてタームし、前記２つのバージョンを区別する必要が無くなった為、スレッドｔｈ０のバージョンがスレッドｔｈ１のバージョンに縮退されたことに対応する。このように、バージョンの区別が不要になった際のバージョンの縮退が容易であることも本実施例の特徴である。
【００６４】
図７の（１０）において、スレッドｔｈ２でアドレスＣに対するストア命令（ｓｔＣ）が実行される。スレッドｔｈ２の親スレッドはプロセッサＰ０、Ｐ３で実行されているので、アドレスＣのキャッシュラインのバージョン識別子ｖｉｄは１０１にセットされる。
【００６５】
図７の（１１）において、プロセッサＰ０において実行されていたスレッドがタームし、それにより、プロセッサＰ１のキャッシュメモリの全キャッシュラインのバージョン識別子ｖｉｄにおいて、プロセッサＰ０に対応するビットがリセットされる。アドレスＡ，Ｂ，Ｃのキャッシュラインも該当ビットがリセットされ、それぞれ０００、０００及び００１になる。すなわち、アドレスＡ及びＢのラインは、バージョン識別子ｖｉｄがすべてリセットされ、データが確定したことが判明する。これは、それぞれのバージョンを生成したスレッドｔｈ０及びｔｈ１が、その時点で最も古い親のスレッドになったことに対応する。一方、アドレスＣのラインのバージョン識別子ｖｉｄは００１であり、アドレスＣのバージョンを生成したスレッドｔｈ２にとっての親スレッドｃ１０がプロセッサＰ３に存在していて、データが確定していないことがわかる。このように、本実施例によれば、バージョン識別子ｖｉｄを参照するのみで、バージョンを考慮した選択的なキャッシュラインの確定判定を容易に行うことができる。
【００６６】
〔本実施例の効果〕
このように本実施例によれば、１つのキャッシュメモリ上に複数のデータのバージョンを管理することにより、スレッドのマージ、空きフォーク時にデータの転送等のオーバヘッドが生じず、高速なスレッド並列処理が実現できる。
【００６７】
また、バージョンをその時点での親スレッドを実行するプロセッサで表現することにより、アクセスに対するバージョンを考慮した選択的な応答、バージョンの縮退、バージョンを考慮した選択的な確定処理、等のデータ依存解消処理を容易、低オーバヘッドかつ高速に実現できる。
【００６８】
また、他スレッドのタームに応じて、バージョン識別子ｖｉｄが適切に変更され、バージョンの縮退が行われるので、空きフォークの回数に制限が存在しない。
【００６９】
また、上記した選択的なアクセス応答や確定処理に必要な情報はすべてバージョン識別子ｖｉｄに記憶されている為、以前にタームし未確定のスレッドやそのマージ、スレッド順序関係などの情報を別に記憶・管理する必要がない。
【００７０】
〔適用例〕
次に、上述したキャッシュメモリの制御方法を図２の並列プロセッサシステムに適用した例について図面を参照しながら詳細に説明する。
【００７１】
図８はスレッド実行部１−ｉの構成を示すブロック図である。図８を参照すると、スレッド実行部１−ｉは、プロセッサ１０とキャッシュメモリ１１とキャッシュ制御部１２とを含み、プロセッサ１０はバス２に接続され、キャッシュ制御部１２はバス４に接続されている。バス４は、キャッシュ制御に関連するバスとして、要求バス１３、応答バス１４、データバス１５を含んでいる。
【００７２】
プロセッサ１０は、キャッシュメモリ１１及びキャッシュ制御部１２と接続され、他のスレッド実行部のプロセッサと並列にスレッドを実行する。プロセッサ１０とスレッド管理部３及び他のスレッド実行部のプロセッサとはバス２により接続され、スレッドの生成、スレッド実行の終了や取り消し、スレッド間の順序関係、等のスレッド実行に関する制御情報が伝達される。プロセッサ１０は、バス２により伝達されるスレッド制御情報を参照して、自身が実行しているスレッドと他のプロセッサが実行しているスレッドとの順序関係を知ることができる。
【００７３】
キャッシュ制御部１２は、要求バス１３、応答バス１４及びデータバス１５を通じて、他のプロセッサ及びメインメモリ５とメモリ操作命令が対象とするメモリデータの受渡しを制御する。このとき、プロセッサより通知されるスレッドの順序関係を参照し、メモリに関する正依存関係、逆依存関係、及び出力依存関係を考慮して、メモリデータ間の整合性の維持を図る。要求バス１３、応答バス１４、データバス１５はそれぞれ一本のバスを各プロセッサで共有してもよいし、プロセッサ数分だけ固有のバスを備えてもよい。以下では、要求バス１３、応答バス１４、及びデータバス１５を総称して単にバスとも表記する。
【００７４】
図９は、キャッシュメモリ１１を構成するキャッシュラインの詳細を示す説明図である。一つのキャッシュラインは、アドレスタグ２５によって示されるアドレス範囲にあるデータを保持する。図９を参照すると、キャッシュメモリを構成するキャッシュラインは、有効フラグ２０、変更フラグ２１、共有フラグ２２、投機フラグ２３、更新フラグ２４、アドレスタグ２５、複数のデータエントリ２６、複数のストア・フラグ２７、複数の投機ロード・フラグ２８、バージョン識別子（ｖｉｄ）２９、から構成される。
【００７５】
有効フラグ２０は、そのキャッシュラインが有効であることを示す。有効フラグ２０は、キャッシュミスが発生した時など、データをキャッシュメモリに転送し、キャッシュラインを生成する（リフィルする）際にセットし、キャッシュラインを入れ換える時など、キャッシュラインを無効化する際にリセットする。
【００７６】
変更フラグ２１は、そのキャッシュラインのデータをストア命令等で変更しており、メインメモリにあるデータと異なっている（ｄｉｒｔｙ）ことを示す。変更フラグ２１は、ストア命令等のデータの書き込みを実行した際にセットし、キャッシュラインのメインメモリへの書き戻し（ライトバック）を行った際にリセットする。
【００７７】
共有フラグ２２は、そのキャッシュラインと同アドレスのキャッシュラインを、他のプロセッサに固有のキャッシュメモリも保持し、データを共有していることを示す。本実施例による共有フラグは、並列プロセッサシステムが備えるプロセッサ数分のフラグを備えている。すなわち、それぞれのフラグ部分が各プロセッサに対応しており、フラグがセットされている場合、該フラグに対応するプロセッサとデータを共有していることを示し、フラグがリセットされている場合、該フラグに対応するプロセッサとデータを共有していないことを示す。したがって、共有フラグ２２を参照すると、共有対象のプロセッサを特定することが可能である。共有フラグ２２はバスアクセスが行われた際にセットまたはリセットされる。詳細には、あるプロセッサがキャッシュ制御部１２を通じてバスアクセスを行った際には、全てのプロセッサのキャッシュ制御部１２には、応答バス１４を通じてすべてのキャッシュメモリ１１のキャッシュライン状態が通知される。このとき、どのプロセッサと共有しているかが判明するので、共有フラグ２２を構成するフラグのうち、共有しているプロセッサに対応するフラグをセットし、共有していないプロセッサに対応するフラグをリセットする。
【００７８】
投機フラグ２３は、そのキャッシュラインのデータが投機的なデータを含んでいることを示す。本実施例による投機フラグは、並列プロセッサシステムが備えるプロセッサ数分のフラグを備えている。すなわち、それぞれのフラグ部分が各プロセッサに対応しており、フラグがセットされている場合、該フラグに対応するプロセッサが、データが投機的である原因であることを示す。したがって、投機フラグ２３を参照すると、該キャッシュラインのデータを投機的にならしめた原因のプロセッサを特定することが可能である。投機フラグ２３は、キャッシュラインをリフィルする際、他のプロセッサのキャッシュメモリが保持している投機的なキャッシュラインからリフィル・データを得た場合、投機フラグ２３の前記他のプロセッサに対応するフラグをセットする。また、自プロセッサが実行するスレッド（以下では、自スレッドと表記する）が含む投機的なストア命令により、投機的なデータでキャッシュラインを更新した場合、投機フラグ２３の自プロセッサに対応するフラグをセットする。また、プログラム順序で先行するスレッド（親スレッド）が含む投機的なストア命令により、投機的なデータでキャッシュラインを更新した場合、投機フラグ２３の前記親スレッドを実行するプロセッサに対応するフラグ部分をセットする。一方、投機フラグ２３は、自スレッドの投機的な実行が確定して、そのキャッシュラインのデータが確定した際にリセットされる。
【００７９】
更新フラグ２４は、プログラム順序で後に位置するスレッド（子スレッド）により、そのキャッシュラインのデータが更新されたことを示す。すなわち、そのキャッシュラインのデータは、該プロセッサが実行する現スレッドには有効であるが、該プロセッサに次に割り当てられるスレッドには有効でない可能性があることを意味する。更新フラグ２４は、１ビットの更新有効フラグ２４ａと、並列プロセッサシステムが備える、自プロセッサを除くプロセッサ数ビット分の更新対象フラグ２４ｂとから構成される。更新有効フラグ２４ａは更新フラグ２４全体が有効であることを示す。スレッドが終了した際には、すべての更新有効フラグ２４ａがセットされるが、別の実施例として、更新対象フラグ２４ｂのいずれかがセットされている更新フラグ２４の更新有効フラグ２４ａのみをセットしてもよい。更新有効フラグ２４ａがセットされていて、かつ、更新対象フラグ２４ｂのいずれかがセットされている場合、当該キャッシュラインは次に実行されるスレッドでは有効でない可能性があることが示される。実際に当該キャッシュラインが有効か否かは、キャッシュミス時などに伴うバス要求の入出力時にキャッシュ制御部どうしで交換されるキャッシュライン状態によって調べられ、若し有効であれば更新対象フラグ２４ｂと共に更新有効フラグ２４ａがリセットされる。他方、更新有効フラグ２４ａがリセットされているか、更新対象フラグ２４ｂの全てがリセットされていれば、当該キャッシュラインは次に実行されるスレッドでも有効であることが示される。各更新対象フラグ２４ｂは、それぞれが他のプロセッサに対応し、対応するプロセッサにより該キャッシュラインが更新されたことを示す。
【００８０】
データエントリ２６は、そのキャッシュラインのメモリデータを保持する。通常、一つのキャッシュラインは、アドレスタグ２５が指定するアドレス範囲を構成する複数のデータエントリを備え、それぞれのデータエントリは、ストア命令等による書き込みの最小のデータ単位である。図９においては、複数のデータエントリ２６のそれぞれをデータエントリ２６ａ、データエントリ２６ｂ、データエントリ２６ｃ、データエントリ２６ｄ、…、と表記して区別している。
【００８１】
ストア・フラグ２７は、対応するデータエントリに、自プロセッサがストア命令などで書き込みを行ったことを示す。図９においては、ストア・フラグ２７ａはデータエントリ２６ａに、ストア・フラグ２７ｂはデータエントリ２６ｂに、ストア・フラグ２７ｃはデータエントリ２６ｃに、ストア・フラグ２７ｄはデータエントリ２６ｄに、それぞれ対応する。ストア・フラグは自プロセッサが書き込みを行った際にセットし、スレッドの実行が終了した際にリセットされる。
【００８２】
投機ロード・フラグ２８は、対応するデータエントリに、自プロセッサが投機的な読み出しを行ったことを示す。図９においては、投機ロード・フラグ２８ａはデータエントリ２６ａに、投機ロード・フラグ２８ｂはデータエントリ２６ｂに、投機ロード・フラグ２８ｃはデータエントリ２６ｃに、投機ロード・フラグ２８ｄはデータエントリ２６ｄに、それぞれ対応する。投機ロード・フラグは投機的な読み出しを行い、かつ読み出し対象のデータに対して先に書き込みを行っていない、すなわち対応するストア・フラグ２７がセットされていないならばセットされる。一方、スレッドの投機実行が確定した際にはリセットされる。
【００８３】
図９に示したキャッシュラインの実施例では、書き込みの最小データ単位に対応するデータエントリ２６ａ、２６ｂ、…、のそれぞれに固有のストア・フラグ２７ａ、２７ｂ、…、及び投機ロード・フラグ２８ａ、２８ｂ、…、を備えたが、複数のデータエントリに対して単一のストア・フラグまたは投機ロード・フラグを代表させてもよい。例えば、図１０は４つのデータエントリ２６ａ、２６ｂ、２６ｃ、２６ｄ、に対して、一つの投機ロード・フラグ２８ａを備えたキャッシュラインの第２の実施例である。データエントリ２６、ストア・フラグ２７、投機ロード・フラグ２８以外の構成要素は省略している。投機ロード・フラグ２８ａは、４つのデータエントリ２６ａ、２６ｂ、２６ｃ、２６ｄ、のいずれかに投機的な読み出しを行ったことを示す。この場合、データエントリそれぞれに固有の投機ロード・フラグを備えるのに比べて、キャッシュメモリの実装に必要なハードウェア量が小さくなるという効果がある。
【００８４】
バージョン識別子（ｖｉｄ）２９は、自プロセッサを除く並列プロセッサシステムが備えるプロセッサ数分のビット数をもち、それぞれが自プロセッサを除く他プロセッサに対応する。ストア命令等の書き込みを行った場合、その対象ラインのバージョン識別子２９がセットされる。セットされるビットは、マージされたスレッドを除く該スレッドのすべての親スレッドを実行するプロセッサに対応するビットであり、それ以外のビットはリセットされる。あるスレッドがタームした場合、該スレッドを実行していたプロセッサを除くすべてのプロセッサのキャッシュメモリのすべてのキャッシュラインのバージョン識別子２９において、該スレッドを実行していたプロセッサに対応するビットがリセットされる。すわなち、バージョン識別子２９はその時点での、自キャッシュラインを生成したスレッドのすべての親スレッドのうち、いまだタームしていない親スレッドを実行するプロセッサを示している。あるプロセッサＰｉ上で実行された２つのスレッドにより生成された異なるバージョンのキャッシュラインは、その２つのスレッドのプログラム順序上で間のスレッドがすべてタームした時点で、バージョン識別子ｖｉｄは同じバージョンを示し、すなわち、縮退が行われたことになる。他プロセッサから自キャッシュメモリにアクセスがあった場合、バージョン識別子２９が参照される。バージョン識別子２９の前記他プロセッサに対応するビットがセットされている場合、自キャッシュラインにとっての親スレッドからのアクセスと判断できる。その場合、自キャッシュラインのデータはプログラム順序で後に位置し有効ではないので、前記アクセスに対して自キャッシュメモリからは応答しない。一方、バージョン識別子２９の前記他プロセッサに対応するビットがリセットされている場合、自キャッシュラインにとっての子スレッドからのアクセスと判断できる。その場合、自キャッシュラインのデータはプログラム順序で前に位置し有効であるので、前記アクセスに対して自キャッシュメモリから適切な応答処理を行う。前記タームによるバージョン識別子２９のリセットで、バージョン識別子２９のすべてのビットがリセットされた場合、自キャッシュラインのデータは少なくとも確定することになる。すなわち、バージョン識別子２９のすべてのビットがリセットされているキャッシュラインのデータは、メインメモリ等に書き戻すことができる。なお、本実施例では、同アドレスで異なるバージョンのキャッシュラインは生成せず、空きフォークにより生成されたスレッドが書き込みを行う際に、その対象のラインが古いバージョンをもつｄｉｒｔｙ  なラインの場合、すべての古いバージョンが確定して縮退されるまで書き込みの実行を遅らせて、複数のバージョンの発生を回避する。
【００８５】
再び図８を参照すると、キャッシュ制御部１２は少なくとも、バス要求制御部３０、キャッシュ要求制御部３１、バス要求出力バッファ３２、バス要求入力バッファ３３を含んでいる。
【００８６】
バス要求制御部３０は、キャッシュメモリ１１からのキャッシュミス通知、ストア通知やその対象アドレス、ストア・データ、キャッシュライン状態等を受け取り、それらを参照してバス要求を生成し、バス要求出力バッファ３２に登録する。ここで、キャッシュライン状態は、図９に示したキャッシュラインを構成する、有効フラグ２０、変更フラグ２１、共有フラグ２２、投機フラグ２３、更新フラグ２４、ストア・フラグ２７、バージョン識別子２９を含み、キャッシュミスした場合は、そのミスによるリフィル処理対象のキャッシュラインの状態、キャッシュヒットした場合は、そのヒットしたキャッシュラインの状態を示す。
【００８７】
バス要求出力バッファ３２は、バス要求制御部３０によって生成されたバス要求を格納し、順次バスを通じて他のプロセッサやメインメモリに出力する。より詳細には、バス要求はコマンド、アドレス、キャッシュライン状態、データ等から構成され、コマンド、アドレスは要求バス１３、キャッシュライン状態は応答バス１４、データはデータバス１５に出力する。バス要求出力バッファ３２は同時に、要求バス１３に出力したコマンド、アドレス、及び応答バス１４に出力したキャッシュライン状態を、バス要求入力バッファ３３にも転送する。本実施例は、バス要求を出力する際には、キャッシュライン状態に含まれる共有フラグ２２を参照して、データを共有しているプロセッサにのみ宛てて、バス要求を出力する。すなわち、データを共有していないプロセッサでは、該バス要求によるキャッシュメモリへのアクセスが発生せず、キャッシュメモリのアクセス競合による性能低下が小さく、またキャッシュメモリにおいて消費される電力を削減することができるという効果がある。
【００８８】
バス要求入力バッファ３３は、他プロセッサやメインメモリから要求バス１３を通じて伝達されるバス要求のコマンド、アドレスや、応答バス１４を通じて伝達されるキャッシュライン状態や、データバス１５を通じて伝達されるデータなどを格納する。バス要求入力バッファ３３はまた、バス要求出力バッファ３２から要求バス１３に出力されたバス要求のコマンド、アドレス、及び応答バス１４に出力されたキャッシュライン状態を格納し、さらに、バス要求に応じて他プロセッサが応答バス１４に出力するキャッシュライン状態を、その到着を待って格納する。同時にバス要求入力バッファ３３は、格納しているバスから入力したバス要求、より詳細には、コマンド、アドレス、キャッシュライン状態、及びデータ、をキャッシュ要求制御部３１に順次出力していく。
【００８９】
キャッシュ要求制御部３１は、バス要求入力バッファ３３が保持し、順次入力されるバス要求を順次解釈する。まず、バスから入力された他プロセッサからのバス要求に対しては、キャッシュメモリ１１にアクセスして、バス要求の対象のキャッシュラインを保持しているか否かを判定し、保持していなければその旨が、保持していればそのキャッシュラインの状態が、バス要求制御部３０及びバス要求出力バッファ３２を通じて、応答バス１４に出力される。同時に、その自身のキャッシュメモリのキャッシュライン状態は、バス要求入力バッファ３３の該当エントリに格納される。バス要求入力バッファ３３において、自身のキャッシュライン状態も含めて、他プロセッサからのキャッシュライン状態の応答もすべて到着したら、再び、キャッシュ要求制御部３１において、バス要求のコマンドと、自身のキャッシュライン状態、及び他プロセッサのキャッシュライン状態をすべて参照して、キャッシュラインの次の状態を決定し、対象のキャッシュラインの更新を行う。
【００９０】
一方、自身が出力したバス要求に対しては、そのコマンド、アドレス、及びキャッシュライン状態が、バス要求入力バッファ３３に格納されるので、バス要求入力バッファ３３において、他プロセッサからのキャッシュライン状態の応答もすべて到着したら、キャッシュ要求制御部３１において、バス要求のコマンドと、自身のキャッシュライン状態、及び他プロセッサのキャッシュライン状態をすべて参照して、キャッシュラインの次の状態を決定し、対象のキャッシュラインの更新を行う。
【００９１】
次にフローチャートを参照しつつ、キャッシュメモリ１１及びキャッシュ制御部１２の動作の詳細を説明する。図１１は、ロード命令が発行された場合のキャッシュメモリ１１及びキャッシュ制御部１２の動作を示すフローチャートである。まず、プロセッサ１０でロード命令が発行されると（図１１のステップ２００）、キャッシュメモリ１１がアクセスされ、キャッシュメモリにヒットするか、ミスするかが判定される（図１１のステップ２０１）。ここで、キャッシュメモリにヒットするとは、有効フラグ２０がセットされていて、かつアドレスタグ２５で示されるアドレス範囲に該ロード命令の対象アドレスが入っているキャッシュラインが存在する場合である。前記条件を満たすキャッシュラインが存在しない場合、キャッシュメモリにミスするという。
【００９２】
キャッシュメモリにヒットした場合、ヒットしたキャッシュラインが読み出され、キャッシュライン内の更新フラグ２４が参照される（図１１のステップ２０２）。更新フラグ２４がセットされていない、すなわち、更新有効フラグ２４ａがセットされていないか、更新対象フラグ２４ｂのいずれもがセットされていない場合、そのキャッシュラインは子スレッドにより更新されておらず、そのキャッシュラインは有効であると判断される。その場合、キャッシュメモリ１１からプロセッサ１０にロード対象のデータが転送される（図１１のステップ２０６）。次に、該ロード命令がスレッド間の正依存関係に関して投機的な実行である場合、ロード対象のデータを格納したデータエントリ２６に対応する投機ロード・フラグ２８をセットして（図１１のステップ２０７）、ロード命令の実行は終了する。発行されたロード命令が投機的であるか、確定的であるかはプロセッサ１０からキャッシュメモリ１１に通知される。
【００９３】
一方、更新フラグ２４の参照（図１１のステップ２０２）で、更新フラグ２４がセットされていた、すなわち、更新有効フラグ２４ａがセットされていて、かつ、更新対象フラグ２４ｂのいずれかがセットされている場合、そのキャッシュラインは子スレッドにより更新されていて、そのキャッシュラインは既に無効である可能性があると判断される。ここで確定的に無効であると判定できないのは、子スレッドによる更新が投機的であって、かつ取り消されている場合があり、実際には有効である可能性もあるからである。確定的な判断は、子スレッドを実行したプロセッサのキャッシュメモリのキャッシュライン状態を参照する必要がある。そこで、バス要求制御部３０は他のプロセッサのキャッシュメモリを参照するリード要求を生成し、バス要求出力バッファ３２を通じて、要求バス１３にリード要求を発行する（図１１のステップ２０３）。同時にそのリード要求、リード要求の対象アドレス、及び自身のキャッシュライン状態は、バス要求入力バッファ３３に格納され、他のプロセッサのキャッシュ制御部から、リード要求に対する応答である、キャッシュライン状態が応答バス１４を通じて到着するのを待機する（図１１のステップ２０４）。
【００９４】
リード要求に対して、すべてのプロセッサからの応答が到着すると、前記した自身のキャッシュラインが実際に無効であるか、それとも有効であるかを判定する（図１１のステップ２０５）。より詳細には、セットされている更新対象フラグ２４ｂに対応するプロセッサのキャッシュライン状態を参照し、ヒットしていた場合は、実際にそのプロセッサに更新されていたと判断する。一方、セットされているすべての更新対象フラグ２４ｂに対して、いずれのプロセッサでもミスしていた場合、その更新は投機実行の失敗により取り消されていて、実際には更新されていないと判断する。
【００９５】
実際には更新されていなかった場合、該キャッシュラインは有効であるので、ただちに、読み出し処理を実行することができる。この場合、リフィル処理は必要なく、先に発行したリード要求を受信したプロセッサでは、そのリード要求に対する処理は行われない。読み出し処理では、キャッシュメモリ１１からプロセッサ１０にロード対象のデータを転送する（図１１のステップ２０６）。次に、キャッシュライン状態を更新して、ロード命令の実行を終了する（図１１のステップ２０７）。具体的には、まず、更新フラグ２４をリセットし、次に、該ロード命令が投機的な実行である場合、ロード対象のデータを格納したデータエントリ２６に対応する投機ロード・フラグ２８をセットする。
【００９６】
一方、実際に更新されていた場合、該キャッシュラインは無効であるので、他のプロセッサのキャッシュメモリ、またはメインメモリから、有効なデータをリフィルする必要がある。まず、リフィル処理の前に、該キャッシュラインのデータをライトバックする必要性を判断する（図１１のステップ２１１）。該キャッシュラインは、自プロセッサが現在実行しているスレッドに対しては無効であるが、親スレッドに対しては有効である場合がある。より詳細には、該キャッシュラインを更新したプロセッサのキャッシュメモリに、確定したキャッシュライン、すわなち投機フラグ２３がセットされていないキャッシュラインが存在しなければ、該キャッシュラインは唯一の確定したデータを保持しているため、ライトバックが必要であると判断する。一方、該キャッシュラインの更新元のプロセッサのキャッシュラインに、確定したキャッシュラインが存在すれば、ライトバックは必要ないと判断する。
【００９７】
ライトバックが必要であると判断した場合、バス要求制御部３０はライトバック要求を生成し、それをバス要求出力バッファ３２を通じて、要求バス１３に出力し（図１１のステップ２１６）、次にデータバス１５にライトバック対象のデータを出力する（図１１のステップ２１７）。次に、先に発行しているリード要求に対して、他のキャッシュメモリまたはメインメモリからデータバス１５を通じて伝達されるリフィル・データの到着を待つ（図１１のステップ２１２）。次に、キャッシュ要求制御部３１は到着したリフィル・データをキャッシュメモリ１１へリフィルする処理を行い（図１１のステップ２１３）、次に、キャッシュメモリ１１からプロセッサ１０にロード対象のデータを転送し（図１１のステップ２０６）、キャッシュライン状態を更新して、ロード命令の実行を終了する（図１１のステップ２０７）。
【００９８】
一方、図１１のステップ２１１でライトバックが必要でないと判断した場合、そのままリフィル・データの到着を待ち（図１１のステップ２１２）、キャッシュメモリ１１へのリフィルを行う（図１１のステップ２１３）。次に、キャッシュメモリ１１からプロセッサ１０にロード対象のデータを転送し（図１１のステップ２０６）、キャッシュライン状態を更新して、ロード命令の実行を終了する（図１１のステップ２０７）。
【００９９】
以上、図１１のステップ２０１において、ロード命令がキャッシュメモリにヒットした場合の動作について説明した。一方、ロード命令がキャッシュメモリにミスした場合は、スレッド実行が確定的か投機的かで動作が異なる（図１１のステップ２０８）。スレッド実行が投機的で、すなわち発行されたロード命令は投機的である場合、キャッシュメモリ１１にリフィル可能か否かを判断する（図１１のステップ２１４）。キャッシュメモリ１１のリフィル先の候補のエントリに空きがなく、かつ、それらエントリに格納されているすべてのキャッシュラインの投機フラグ２３及びストア・フラグ２７のいずれかがセットされているか、あるいは投機ロード・フラグ２８のいずれかがセットされている場合、リフィルすることができない。この場合、スレッドが確定するまで待機した後に（図１１のステップ２１５）、図１１のステップ２０９よりリフィル処理を開始する。
【０１００】
一方、キャッシュメモリ１１のリフィル先の候補のエントリに少なくとも１つの空きがあれば、リフィルは可能である。また、空きが無い場合でも、それらリフィル先候補のエントリに格納されているいずれかのキャッシュラインの投機フラグ２３かストア・フラグ２７のいずれかがセットされてなく、かつ投機ロード・フラグ２８のいずれもセットされていない場合、そのエントリにリフィルすることが可能である。この場合、図１１のステップ２０９よりリフィル処理を開始する。
【０１０１】
一方、スレッド実行が確定的で、すなわち発行されたロード命令は確定的である場合（図１１のステップ２０８、Ｙｅｓ）、常にリフィルは可能であるので、図１１のステップ２０９よりリフィル処理を開始する。具体的には、まず、要求バス１３にリード要求を出力し（図１１のステップ２０９）、それに対する他プロセッサからの応答を待つ（図１１のステップ２１０）。
【０１０２】
次に、ライトバックが必要か否かを判定する（図１１のステップ２１１）。リフィル先のエントリにストア命令により変更されたキャッシュライン、すわなち変更フラグ２１がセットされているキャッシュラインが存在すれば、ライトバックが必要である。その場合、ライトバック要求を要求バス１３に出力し（図１１のステップ２１６）、次にデータバス１５にライトバック対象のデータを出力する（図１１のステップ２１７）。次に、リフィル・データの到着を待ち（図１１のステップ２１２）、キャッシュメモリ１１へのリフィルを行う（図１１のステップ２１３）。次に、キャッシュメモリ１１からプロセッサ１０にロード対象のデータを転送し（図１１のステップ２０６）、キャッシュライン状態を更新して、ロード命令の実行を終了する（図１１のステップ２０７）。
【０１０３】
ライトバックが必要でない場合は、そのままリフィル・データの到着を待ち（図１１のステップ２１２）、キャッシュメモリ１１へのリフィルを行う（図１１のステップ２１３）。次に、キャッシュメモリ１１からプロセッサ１０にロード対象のデータを転送し（図１１のステップ２０６）、キャッシュライン状態を更新して、ロード命令の実行を終了する（図１１のステップ２０７）。
【０１０４】
以上、ロード命令が発行された場合のキャッシュメモリ１１及びキャッシュ制御部１２の動作を説明した。次に、図１２を参照して、ストア命令が発行された場合のキャッシュメモリ１１及びキャッシュ制御部１２の動作を説明する。
【０１０５】
まず、プロセッサ１０でストア命令が発行されると（図１２のステップ２２０）、キャッシュメモリ１１がアクセスされ、キャッシュメモリにヒットするか、ミスするかが判定される（図１２のステップ２２１）。ここで、キャッシュメモリにヒットするとは、有効フラグ２０がセットされていて、かつアドレスタグ２５で示されるアドレス範囲にストア命令の対象アドレスが入っているキャッシュラインが存在する場合である。前記条件を満たすキャッシュラインが存在しない場合、キャッシュメモリにミスするという。
【０１０６】
キャッシュメモリにヒットした場合、ヒットしたキャッシュラインが読み出され、まずキャッシュライン内のバージョン識別子が参照される（図１２のステップ２４２）。ここで、バージョン識別子で示されるヒットしたキャッシュラインのバージョンと現在実行しているスレッドのバージョンが一致せず、かつｄｉｒｔｙ  な（変更フラグ２１がセットされている）キャッシュラインの場合、一致するまで待機する。バージョン識別子に記憶されるバージョンは、親スレッドの終了に応じて適宜変更され、いずれ現在実行しているスレッドのバージョンに一致する。バージョンが一致したか、あるいはｄｉｒｔｙ  なキャッシュラインでない場合、次に図１２のステップ２２２において、キャッシュライン内の更新フラグ２４が参照される。
【０１０７】
更新フラグ２４がセットされていない、すなわち、更新有効フラグ２４ａがセットされていないか、更新対象フラグ２４ｂのいずれもがセットされていない場合、そのキャッシュラインは子スレッドにより更新されておらず、そのキャッシュラインは有効であると判断される。その場合、バス要求制御部３０は、ライト要求を生成し、バス要求出力バッファ３２を通じて、要求バス１３にライト要求を出力する（図１２のステップ２２６）。ライト要求は、ストア命令を実行したこと、及びそのストア・データを他のプロセッサやキャッシュメモリに通知し、それに対する処理を要求するバス要求である。
【０１０８】
次に、該ストア命令による書き込みの前に、以前のデータのメインメモリへのライトバックが必要か否かを判定する（図１２のステップ２２７）。該ストア命令がヒットしたキャッシュラインが確定的である、すなわち投機フラグ２３がセットされてなく、かつ該ストア命令が投機的な実行である場合、投機的なデータを書き込む前に、確定的なデータをメインメモリへライトバックする処理を行う。具体的には、要求バス１３にライトバック要求を出力し（図１２のステップ２３０）、続いてデータバス１５を通じてライトバックするデータを転送する（図１２のステップ２３１）。その後、該ストア命令が書き込みの対象とするキャッシュラインのデータエントリ２６に、ストア・データの書き込みを行う（図１２のステップ２２８）。次に、キャッシュライン状態を更新して、ストア命令の実行を終了する（図１２のステップ２２９）。具体的には、まず、変更フラグ２１、及びストア対象のデータを格納したデータエントリに対応するストア・フラグ２７をセットする。さらに、該ストア命令が投機的な実行である場合、投機フラグ２３の自プロセッサに対応するフラグ部分をセットする。さらに、バージョン識別子２９に現在実行しているスレッドのバージョンの書き込みを行う。
【０１０９】
一方、ライトバックが必要なかった場合（図１２のステップ２２７、Ｎｏ）、そのまま該ストア命令が書き込みの対象とするキャッシュラインのデータエントリに、ストア・データの書き込みを行う（図１２のステップ２２８）。次に、キャッシュライン状態を更新して、ストア命令の実行を終了する（図１２のステップ２２９）。
【０１１０】
一方、更新フラグの参照（図１２のステップ２２２）で、更新フラグ２４がセットされていた、すなわち、更新有効フラグ２４ａがセットされていて、かつ、更新対象フラグ２４ｂのいずれかがセットされている場合、そのキャッシュラインは子スレッドにより更新されていて、そのキャッシュラインは既に無効である可能性があると判断される。その場合、バス要求制御部３０はリード・ライト要求を生成し、要求バス１３にリード・ライト要求を発行する（図１２のステップ２２３）。リード・ライト要求は、同時に要求バスに出力する対象のアドレスに対して、リード要求に対する処理の後、ライト要求に対する処理を要求するバス要求である。
【０１１１】
次に、他のキャッシュ制御部からリード・ライト要求に対する応答の到着を待機し（図１２のステップ２２４）、その応答を参照して、該キャッシュラインが子スレッドにより実際に更新されているか否かを判定する（図１２のステップ２２５）。実際には更新されていなかった場合、該キャッシュラインは有効であるので、ただちにライト処理を開始することができる。この場合、リフィル処理は必要なく、先に発行したリード・ライト要求を受信したプロセッサでは、そのリード要求部分に対する処理は行われない。ライト処理では、まず、ライトバックが必要か否かの判断を行う（図１２のステップ２２７）。ライトバックが必要な場合、ライトバック要求の発行（図１２のステップ２３０）及び、ライトバック・データの転送（図１２のステップ２３１）を行う。次に、該ストア命令が書き込みの対象とするキャッシュラインのデータエントリに、ストア・データの書き込みを行う（図１２のステップ２２８）。次に、キャッシュライン状態を更新して、ストア命令の実行を終了する（図１２のステップ２２９）。
【０１１２】
一方、図１２のステップ２２５における子スレッドによる更新の有無の判断で、実際に更新されていた場合、該キャッシュラインは無効であるので、ロード命令の場合と同様に、他のプロセッサのキャッシュメモリ、またはメインメモリから、有効なデータをリフィルする必要がある。まず、リフィル処理の前に、該キャッシュラインのデータをライトバックする必要性を判断する（図１２のステップ２３５）。該キャッシュラインは、自プロセッサが現在実行するスレッドに対しては無効であるが、親スレッドに対しては有効である場合がある。より詳細には、該キャッシュラインを更新したプロセッサのキャッシュラインに、確定したキャッシュライン、すわなち投機フラグ２３がセットされていないキャッシュラインが存在しなければ、該キャッシュラインは唯一の確定したデータを保持しているため、ライトバックが必要であると判断する。一方、該キャッシュラインの更新元のプロセッサのキャッシュラインに、確定したキャッシュラインが存在すれば、ライトバックは必要ないと判断する。
【０１１３】
ライトバックが必要であると判断した場合は、ライトバック要求の発行（図１２のステップ２４０）及び、ライトバック・データの転送（図１２のステップ２４１）を行う。次に、先に発行しているリード・ライト要求に対して、他のキャッシュメモリまたはメインメモリからデータバス１５を通じて伝達されるリフィル・データの到着を待つ（図１２のステップ２３６）。次に、キャッシュ要求制御部３１は到着したリフィル・データをキャッシュメモリ１１へリフィルする処理を行う（図１２のステップ２３７）。次に、該ストア命令が書き込みの対象とするキャッシュラインのデータエントリに、ストア・データの書き込みを行う（図１２のステップ２２８）。次に、キャッシュライン状態を更新して、ストア命令の実行を終了する（図１２のステップ２２９）。
【０１１４】
一方、ライトバックが必要でないと判断した場合は、そのまま、リフィル・データの到着を待ち（図１２のステップ２３６）、キャッシュメモリ１１へリフィルを行う（図１２のステップ２３７）。次に、該ストア命令のストア・データの書き込みを行い（図１２のステップ２２８）、キャッシュライン状態を更新して、ストア命令の実行を終了する（図１２のステップ２２９）。
【０１１５】
以上、図１２のステップ２２１において、ストア命令がキャッシュメモリにヒットした場合の動作について説明した。一方、ストア命令がキャッシュメモリにミスした場合は、ロード命令の場合と同様に、スレッド実行が確定的か投機的かで動作が異なる（図１２のステップ２３２）。スレッド実行が投機的で、すなわち発行されたストア命令は投機的である場合、キャッシュメモリ１１にリフィル可能か否かを判断する（図１２のステップ２３８）。キャッシュメモリ１１のリフィル先の候補のエントリに空きがなく、かつ、それらエントリに格納されているすべてのキャッシュラインの投機フラグ２３及びストア・フラグ２７のいずれかがセットされているか、あるいは投機ロード・フラグ２８のいずれかがセットされている場合、リフィルすることができない。この場合、スレッドが確定するまで待機した後に（図１２のステップ２３９）、リフィル処理を開始する。
【０１１６】
一方、キャッシュメモリ１１のリフィル先の候補のエントリに少なくとも１つの空きがあれば、リフィルは可能である。また、空きが無い場合でも、それらリフィル先候補のエントリに格納されているいずれかのキャッシュラインの投機フラグ２３かストア・フラグ２７のいずれかがセットされてなく、かつ投機ロード・フラグ２８のいずれもセットされていない場合、そのエントリにリフィルすることが可能である。この場合、そのままリフィル処理を開始する。
【０１１７】
一方、スレッド実行が確定的で、すなわち発行されたストア命令は確定的である場合（図１２のステップ２３２、Ｙｅｓ）、常にリフィルは可能であるので、そのままリフィル処理を開始する。具体的には、まず、要求バス１３にリード・ライト要求を出力し（図１２のステップ２３３）、それに対する他プロセッサからの応答を待つ（図１２のステップ２３４）。
【０１１８】
次に、ライトバックが必要か否かを判定する（図１２のステップ２３５）。リフィル先のエントリに変更されたキャッシュライン、すわなち変更フラグ２１がセットされているキャッシュラインが存在すれば、ライトバックが必要であると判断する。ライトバックが必要であると判断した場合は、ライトバック要求の発行（図１２のステップ２４０）及び、ライトバック・データの転送（図１２のステップ２４１）を行った後、リフィル処理を続行する。一方、ライトバックが必要でないと判断した場合は、そのままリフィル処理を続行する。リフィル処理は、先に発行しているリード・ライト要求に対して、他のキャッシュメモリまたはメインメモリからデータバス１５を通じて伝達されるリフィル・データの到着を待つ（図１２のステップ２３６）。次に、キャッシュ要求制御部３１は到着したリフィル・データのキャッシュメモリ１１へのリフィルを行う（図１２のステップ２３７）。次に、該ストア命令が書き込みの対象とするキャッシュラインのデータエントリに、ストア・データの書き込みを行う（図１２のステップ２２８）。次に、キャッシュライン状態を更新して、ストア命令の実行を終了する（図１２のステップ２２９）。
【０１１９】
以上、ストア命令が発行された場合のキャッシュメモリ１１及びキャッシュ制御部１２の動作を説明した。次に、図１３を参照して、他のプロセッサからバスを通じてリード要求を受信した場合、及びリード・ライト要求を受信した場合のリード要求部分に対する、キャッシュメモリ１１及びキャッシュ制御部１２の動作を説明する。リード・ライト要求を受信した場合は、リード要求に対する処理を行った後、後述するライト要求に対する処理を行う。以下の説明ではリード要求またはリード・ライト要求のリード要求部分を、単にリード要求と表記する。
【０１２０】
まず、他プロセッサのキャッシュ制御部１２からのリード要求を、要求バス１３を通じて受信すると、バス要求入力バッファ３３は、該リード要求のコマンド、アドレス、リード要求を発行したプロセッサのキャッシュライン状態などを格納し、キャッシュ要求制御部３１に通知する（図１３のステップ２４５）。キャッシュ要求制御部３１はリード要求を解釈すると、キャッシュメモリ１１にアクセスし、リード要求の対象アドレスがキャッシュメモリにヒットするかミスするかを判定する（図１３のステップ２４６）。ここで、キャッシュメモリにヒットするとは、有効フラグ２０がセットされていて、かつアドレスタグ２５で示されるアドレス範囲に当該リード要求の対象アドレスが入っているキャッシュラインが存在する場合である。前記条件を満たすキャッシュラインが存在しない場合、キャッシュメモリにミスするという。
【０１２１】
リード要求がキャッシュメモリ１１にミスした場合、その旨を、バス要求制御部３０、バス要求出力バッファ３２、及び応答バス１４を通じて、他プロセッサに通知し、リード要求に対する処理を終了する（図１３のステップ２４７）。
【０１２２】
一方、リード要求がキャッシュメモリ１１にヒットした場合、ヒットしたキャッシュラインの状態を、バス要求制御部３０、バス要求出力バッファ３２、及び応答バス１４を通じて、その旨を他プロセッサに通知し（図１３のステップ２４８）、他プロセッサからの応答である他のキャッシュメモリのキャッシュライン状態が到着するのを待機する（図１３のステップ２４９）。次に、ヒットした自身のキャッシュライン状態の更新フラグ２４を参照して、更新フラグ２４がセットされているか否かを判定する（図１３のステップ２５０）。
【０１２３】
更新フラグ２４がセットされていない、すなわち、更新有効フラグ２４ａがセットされていないか、更新対象フラグ２４ｂのいずれもがセットされていない場合、そのキャッシュラインは子スレッドにより更新されておらず、そのキャッシュラインは有効であると判断される。その場合、自身のキャッシュラインのデータをリフィル・データとして供給するか否かの判定を行う（図１３のステップ２５６）。
【０１２４】
一方、更新フラグ２４がセットされていた、すなわち、更新有効フラグ２４ａがセットされていて、かつ、更新対象フラグ２４ｂのいずれかがセットされている場合、そのキャッシュラインは子スレッドにより更新されていて、そのキャッシュラインは既に無効である可能性があると判断される。その場合、他プロセッサからのキャッシュライン状態の応答を参照して、前記した自身のキャッシュラインが実際に無効であるか、それとも有効であるかを判定する（図１３のステップ２５１）。より詳細には、セットされている更新対象フラグ２４ｂに対応するプロセッサのキャッシュライン状態を参照し、ヒットしていた場合は、実際にそのプロセッサに更新されていたと判断する。一方、セットされているすべての更新対象フラグ２４ｂに対して、いずれのプロセッサでもミスしていた場合、その更新は投機実行の失敗に取り消されていて、実際には更新されていないと判断する。
【０１２５】
子スレッドにより、実際には更新されていなかった場合、自身のキャッシュラインのデータをリフィル・データとして供給するか否かの判定を行う（図１３のステップ２５６）。判定は、まず、リード要求を発行したプロセッサが、実際にリフィル処理を必要としているか否かを判断する。これは、リード要求を発行したが（図１１の２０３、または図１２の２２３）、実際にはキャッシュラインが有効でリフィル処理が必要ない場合（図１１の２０５、Ｎｏ、または図１２の２２５、Ｎｏ）があるからである。リード要求を受信したプロセッサでも、すべてのキャッシュメモリのキャッシュライン状態が参照できるので、リード要求を発行したプロセッサと同様の判断が可能である。
【０１２６】
リード要求を発行したプロセッサで、実際にリフィル処理を必要としていない場合は、リフィル・データの供給は行わない。一方、リード要求を発行したプロセッサで、実際にリフィル処理を必要としている場合、次に、プログラム順序の上で、ヒットした自身のキャッシュラインのデータを生成したスレッドと、リード要求を発行したプロセッサが実行するスレッドの間に位置するスレッドを実行するプロセッサのキャッシュライン状態を参照する。これら間に位置するスレッドを実行するプロセッサは、自身のキャッシュラインのバージョン識別子、及び他プロセッサから通知される他のキャッシュメモリでヒットしたキャッシュラインのバージョン識別子を参照して特定することができる。これは、バージョン識別子のうち、セットされているビットを参照すると、そのキャッシュラインのデータを生成したスレッドの親スレッドを実行しているプロセッサを特定できるためである。リフィル・データを供給するか否かは、それらの間のスレッドのキャッシュライン状態と自身のキャッシュライン状態により決定される。なお、スレッドの順序関係は、自身のプロセッサ１０から各キャッシュ制御部１２へ通知される。
【０１２７】
まず、前記間のスレッドのキャッシュラインの中に、投機的な（投機フラグ２３がセットされた）キャッシュラインが存在する場合、自身のキャッシュラインのデータはリフィル・データとして無効であり、自プロセッサはリフィル・データの供給は行わない。
【０１２８】
次に、前記間のスレッドのキャッシュラインの中に、投機的なキャッシュラインは存在しないが、確定的なキャッシュラインは存在し、かつ自身のキャッシュラインも確定的である場合、自プロセッサはリフィル・データの供給は行わない。
【０１２９】
次に、間のスレッドのキャッシュラインの中に、投機的なキャッシュラインは存在しないが、確定的なキャッシュラインは存在し、かつ自身のキャッシュラインは投機的である場合、自プロセッサは自身のキャッシュラインからリフィル・データの供給を行う。
【０１３０】
次に、間のスレッドを実行するプロセッサではすべてキャッシュメモリにミスし、有効なキャッシュラインが存在しない場合、自プロセッサは自身のキャッシュラインからリフィル・データの供給を行う。
【０１３１】
リフィル・データの供給を行わない場合、キャッシュライン状態の更新、具体的には更新フラグ２４のリセットを行い、リード要求に対する処理を終了する（図１３のステップ２５７）。一方、リフィル・データの供給を行う場合、データバス１５を通じて、自身のキャッシュラインが保持しているデータを転送し（図１３のステップ２５８）、次に、キャッシュライン状態の更新を行い、リード要求に対する処理を終了する（図１３のステップ２５７）。
【０１３２】
一方、子スレッドによる更新の有無判定で（図１３のステップ２５１）、実際に更新されていた場合、該キャッシュラインは既に無効であるので、キャッシュラインの無効化を行う。まず、無効化処理の前に、該キャッシュラインのデータをライトバックする必要性を判断する（図１３のステップ２５２）。該キャッシュラインは、自プロセッサが現在実行するスレッドに対しては無効であるが、親スレッドに対しては有効である場合がある。より詳細には、該キャッシュラインの更新元のプロセッサのキャッシュラインに、確定したキャッシュライン、すわなち投機フラグ２３がセットされていないキャッシュラインが存在しなければ、該キャッシュラインは唯一の確定したデータを保持しているため、ライトバックが必要であると判断する。一方、該キャッシュラインの更新元のプロセッサのキャッシュラインに、確定したキャッシュラインが存在すれば、ライトバックは必要ないと判断する。
【０１３３】
ライトバックが必要であると判断した場合、要求バス１３にライトバック要求を出力し（図１３のステップ２５４）、次にデータバス１５にライトバック対象のデータを出力する（図１３のステップ２５５）。その後、キャッシュラインの有効フラグ２０をリセットしてキャッシュラインの無効化を行い、リード要求に対する処理を終了する（図１３のステップ２５３）。一方、ライトバックが必要でないと判断した場合は、そのままキャッシュラインの有効フラグ２０をリセットしてキャッシュラインの無効化を行い、リード要求に対する処理を終了する（図１３のステップ２５３）。
【０１３４】
以上、他のプロセッサからバスを通じてリード要求を受信した場合、及びリード・ライト要求を受信した場合のリード要求部分に対する、キャッシュメモリ１１及びキャッシュ制御部１２の動作を説明した。次に、図１４を参照して、他のプロセッサからバスを通じてライト要求を受信した場合、及びリード・ライト要求を受信した場合のライト要求部分に対する、キャッシュメモリ１１及びキャッシュ制御部１２の動作を説明する。リード・ライト要求を受信した場合は、上述したリード要求に対する処理を行った後、ライト要求に対する処理を行う。以下の説明では、ライト要求、及びリード・ライト要求におけるライト要求部分を、単にライト要求と表記する。
【０１３５】
まず、他プロセッサのキャッシュ制御部１２からのライト要求を、要求バス１３を通じて受信すると、バス要求入力バッファ３３は、該ライト要求のコマンド、アドレス、ライト要求を発行したプロセッサのキャッシュライン状態、ライト・データなどを格納し、キャッシュ要求制御部３１に通知する（図１４のステップ２６０）。キャッシュ要求制御部３１はライト要求を解釈すると、キャッシュメモリ１１にアクセスし、ライト要求の対象アドレスがキャッシュメモリにヒットするかミスするかを判定する（図１４のステップ２６１）。ここで、キャッシュメモリにヒットするとは、有効フラグ２０がセットされていて、かつアドレスタグ２５で示されるアドレス範囲に当該ライト要求の対象アドレスが入っているキャッシュラインが存在する場合である。前記条件を満たすキャッシュラインが存在しない場合、キャッシュメモリにミスするという。
【０１３６】
ライト要求がキャッシュメモリ１１にミスした場合、その旨を、バス要求制御部３０、バス要求出力バッファ３２、及び応答バス１４を通じて、他プロセッサに通知し、ライト要求に対する処理を終了する（図１４のステップ２６２）。
【０１３７】
一方、ライト要求がキャッシュメモリ１１にヒットした場合、ヒットしたキャッシュラインの状態を、バス要求制御部３０、バス要求出力バッファ３２、及び応答バス１４を通じて、その旨を他プロセッサに通知し（図１４のステップ２６３）、他プロセッサからの応答である他のキャッシュメモリのキャッシュライン状態が到着するのを待機する（図１４のステップ２６４）。次に、ヒットした自身のキャッシュライン状態の更新フラグ２４を参照して、更新フラグ２４がセットされているか否かを判定する（図１４のステップ２６５）。
【０１３８】
更新フラグ２４がセットされていない、すなわち、更新有効フラグ２４ａがセットされていないか、更新対象フラグ２４ｂのいずれもがセットされていない場合、そのキャッシュラインは子スレッドにより更新されておらず、そのキャッシュラインは有効であると判断される。その場合、自身のキャッシュラインへのライト処理を開始する（図１４のステップ２６５、Ｎｏ）。
【０１３９】
一方、更新フラグ２４がセットされていた、すなわち、更新有効フラグ２４ａがセットされていて、かつ、更新対象フラグ２４ｂのいずれかがセットされている場合、そのキャッシュラインは子スレッドにより更新されていて、そのキャッシュラインは既に無効である可能性があると判断される。その場合、他プロセッサからのキャッシュライン状態の応答を参照して、前記した自身のキャッシュラインが実際に無効であるか、それとも有効であるかを判定する（図１４のステップ２６６）。より詳細には、セットされている更新対象フラグ２４ｂに対応するプロセッサのキャッシュライン状態を参照し、ヒットしていた場合は、実際にそのプロセッサに更新されていたと判断する。一方、セットされているすべての更新対象フラグ２４ｂに対して、いずれのプロセッサでもミスしていた場合、その更新は投機実行の失敗に取り消されていて、実際には更新されていないと判断する。
【０１４０】
子スレッドにより、実際には更新されていなかった場合、自身のキャッシュラインへのライト処理を開始する（図１４のステップ２６６、Ｎｏ）。ライト処理はまず、ヒットした自身のキャッシュラインのデータを生成したスレッドにとって、親スレッドからのライト要求か否かを判断する（図１４のステップ２７１）。この判断は、自身のキャッシュラインのバージョン識別子のうち、セットされているビットを参照して、該キャッシュラインのデータを生成したスレッドの親スレッドを実行するプロセッサを特定することで実現できる。子スレッドからのライト要求であった場合、それはプログラム順序の上で後に位置する書き込みなので、実際にデータの更新は行わず、子スレッドによって更新されたことを示す、キャッシュラインの更新フラグ２４のうち、ライト要求を発行したプロセッサに対応する更新対象フラグ２４ｂをセットして、ライト要求に対する処理を終了する（図１４のステップ２７３）。
【０１４１】
一方、親スレッドからのライト要求であった場合、次に有効なライト・データ部分が存在するか否かを判定する（図１４のステップ２７２）。判定には、まず、プログラム順序の上で、ライト要求を発行したプロセッサが実行するスレッドとヒットした自身のキャッシュラインのデータを生成したスレッドの間に位置するスレッドを実行するプロセッサのキャッシュライン状態を参照する。これら間に位置するスレッドを実行するプロセッサは、自身のキャッシュラインのバージョン識別子、及び他プロセッサから通知される他のキャッシュメモリでヒットしたキャッシュラインのバージョン識別子を参照して特定することができる。これは、バージョン識別子のうち、セットされているビットを参照すると、そのキャッシュラインのデータを生成したスレッドの親スレッドを実行しているプロセッサを特定できるためである。有効なライト・データ部分が存在するか否かは、それらの間のスレッドのキャッシュライン状態と自身のキャッシュライン状態により決定される。具体的には、ライト・データに対し、間のスレッドのキャッシュラインの中で、ストア・フラグ２７がセットされているライト・データ部分が存在する場合、そのライト・データ部分は自スレッドに対して無効である。逆に、間のスレッドのキャッシュラインのいずれにも、ストア・フラグ２７がセットされていないライト・データ部分が存在する場合、そのライト・データ部分は自スレッドに対して有効である。
【０１４２】
有効なライト・データ部分が存在しない場合、キャッシュライン状態を更新して、ライト要求に対する処理を終了する（図１４のステップ２７３）。一方、有効なライト・データ部分が存在する場合、そのライト・データ部分の書き込み処理を行う。まず、実際に書き込みを行う前に、以前のデータのメインメモリへのライトバックが必要か否かを判定する（図１４のステップ２７４）。該ライト要求がヒットしたキャッシュラインが確定的である、すなわち投機フラグ２３がセットされてなく、かつ該ライト要求が投機的な要求である場合、投機的なデータを書き込む前に、確定的なデータをメインメモリへライトバックする。具体的には、要求バス１３にライトバック要求を出力し（図１４のステップ２７５）、続いてデータバス１５を通じてライトバックするデータを転送する（図１４のステップ２７６）。その後、実際の書き込み処理を開始する。一方、ライトバックが必要なかった場合（図１４のステップ２７４、Ｎｏ）、そのまま実際の書き込み処理を開始する。ライト要求が投機的であるか、確定的であるかは、ライト要求の要因のストア命令が投機的であるか、確定的であるかにより、ライト要求と同時に要求を発行したプロセッサから与えられる。
【０１４３】
実際の書き込み処理では（図１４のステップ２７７）、前記した有効なライト・データ部分を自身のキャッシュラインの対応するデータエントリ２６へ書き込みを行う。ただし、自プロセッサが先に書き込みを行い、ストア・フラグ２７がセットされている、データエントリに対しては書き込みを行わない。
【０１４４】
次に、受信したライト要求のストア命令から、自プロセッサが先に実行した正依存関係に対して投機的なロード命令への、正依存関係の検出を行う（図１４のステップ２７８）。上記した有効なライト・データ部分に対応するデータエントリの投機ロード・フラグ２８のいずれかがセットされていた場合、正依存関係が存在し、投機的なロード命令の実行は失敗であったと判断できる。その場合、キャッシュメモリ１１はプロセッサ１０に投機実行失敗を通知し、プロセッサ１０はスレッド実行の取消しを行う（図１４のステップ２８０）。
【０１４５】
一方、上記した有効なライト・データ部分に対応するデータエントリの投機ロード・フラグ２８のいずれもセットされていない場合、正依存関係は存在せず、投機的なロード命令の実行は成功したと判断できる。その場合、キャッシュライン状態を更新して、ライト要求に対する処理を終了する（図１４のステップ２７９）。
【０１４６】
一方、子スレッドによる更新の有無判定で（図１４のステップ２６６）、実際に更新されていた場合、該キャッシュラインは既に無効であるので、キャッシュラインの無効化を行う。まず、無効化処理の前に、該キャッシュラインのデータをライトバックする必要性を判断する（図１４のステップ２６７）。該キャッシュラインは、自プロセッサが現在実行するスレッドに対しては無効であるが、親スレッドに対しては有効である場合がある。より詳細には、該キャッシュラインを更新したプロセッサのキャッシュラインに、確定したキャッシュライン、すわなち投機フラグ２３がセットされていないキャッシュラインが存在しなければ、該キャッシュラインは唯一の確定したデータを保持しているため、ライトバックが必要であると判断する。一方、該キャッシュラインの更新元のプロセッサのキャッシュラインに、確定したキャッシュラインが存在すれば、ライトバックは必要ないと判断する。
【０１４７】
ライトバックが必要であると判断した場合、要求バス１３にライトバック要求を出力し（図１４のステップ２６９）、次にデータバス１５にライトバック対象のデータを出力する（図１４のステップ２７０）。その後、キャッシュラインの有効フラグ２０をリセットしてキャッシュラインの無効化を行い、ライト要求に対する処理を終了する（図１４のステップ２６８）。一方、ライトバックが必要でないと判断した場合は、そのままキャッシュラインの有効フラグ２０をリセットしてキャッシュラインの無効化を行い、ライト要求に対する処理を終了する（図１４のステップ２６８）。
【０１４８】
以上、他のプロセッサからバスを通じてライト要求を受信した場合、及びリード・ライト要求を受信した場合のライト要求部分に対する、キャッシュメモリ１１及びキャッシュ制御部１２の動作を説明した。上記したように、本実施形態の特徴の一つに、同じアドレスに対するバス要求を結合して同時に発行することがある。さらに更新されて無効である可能性のあるキャッシュラインへの処理を、前記バス要求により暗黙的に実行することがある。これにより、発行されるバス要求を少なくすることができ、バスの競合による性能低下が小さく、バスで消費される電力が小さいという効果がある。上記説明では、同じアドレスに対するリード要求及びライト要求を統合してリード・ライト要求としたが、さらに同じアドレスに対するライトバック要求を統合しても良い。
【０１４９】
投機的なロード命令の実行に失敗した場合など、スレッドの実行が取り消された場合には、まず、キャッシュメモリ１１を構成するすべてのキャッシュラインのすべての投機ロード・フラグ２７をリセットすることで、投機実行したロード命令の記録を破棄する。次に、キャッシュメモリ１１を構成するキャッシュラインのうち、投機的なキャッシュラインの無効化を行うことで、投機実行に失敗して無効であるデータの破棄を行う。具体的には、投機的なキャッシュラインのうち、該キャッシュラインが投機的である原因のプロセッサでも、スレッドの実行の取り消しが行われた場合、該キャッシュラインの有効フラグ２０をリセットして無効化する。本実施例によれば、キャッシュラインが投機的なことを示す投機フラグ２３を、複数のビットから構成しており、該キャッシュラインを投機的にならしめた原因のプロセッサを特定することが可能である。このため、投機フラグを１ビットで構成する従来の方法では、厳密には無効化が不必要なキャッシュラインも無効化されてしまうのに対して、本実施例によれば、厳密に無効化が必要なキャッシュラインのみが無効化されるため、キャッシュミスが発生する確率が小さく、高速なスレッド並列処理が可能であるという効果がある。
【０１５０】
一方、投機的なスレッドの実行が確定した場合には、キャッシュメモリ１１を構成するキャッシュラインのうち、投機的なキャッシュラインの確定を行うことで、投機実行に成功して確定したデータの有効化を行う。この処理は、投機フラグ２３、ストア・フラグ２７、及び投機ロード・フラグ２８をリセットすることで実現できる。各プロセッサで実行されているスレッドのうち、少なくともプログラム順序で最も先に位置するスレッドは、実行が確定している。それ以外のスレッドの実行は確定している場合と、投機的である場合があるが、いずれにしても、先行するすべてのスレッドの実行が終了し、自スレッドが実行中の最も先行するスレッドになった時点で、実行が確定する。
【０１５１】
以上、本発明を実施例を挙げて説明したが、本発明は以上の実施例にのみ限定されず、その他各種の付加変更が可能である。例えば、前記の実施例では複数のスレッド実行部に共通にスレッド管理部を設ける集中スレッド管理型の並列プロセッサシステムに本発明を適用したが、スレッド実行部毎にスレッド管理部を設ける分散スレッド管理型の並列プロセッサシステムにも本発明は適用可能である。
【０１５２】
【発明の効果】
以上説明したように本発明によれば、ターム後で確定前のスレッドをその直後の子スレッドにマージすることによってプロセッサ資源を有効に活用でき、スレッドの並列度を高めることが可能となる。
【図面の簡単な説明】
【図１】本発明の作用の説明図である。
【図２】本発明の並列プロセッサシステムの一例を示すブロック図である。
【図３】本発明の並列プロセッサシステムにおけるスレッド管理部の構成例を示すブロック図である。
【図４】本発明の並列プロセッサシステムにおけるスレッド管理部のスレッド管理シーケンサがスレッド実行部からフォーク要求を受信した際の処理例を示すフローチャートである。
【図５】本発明の並列プロセッサシステムにおけるスレッド管理部のスレッド管理シーケンサがスレッド実行部からスレッド終了通知を受信した際の処理例を示すフローチャートである。
【図６】個々のプロセッサが固有に備えるキャッシュメモリを仮実行用バッファとして兼用する場合の問題点を説明するためのスレッド実行シーケンス図である。
【図７】本発明の一実施例におけるキャッシュメモリの制御方法の説明図である。
【図８】本発明の並列プロセッサシステムのスレッド実行部の構成例を示すブロック図である。
【図９】キャッシュメモリを構成するキャッシュラインの第１の実施例の詳細を示す説明図である。
【図１０】キャッシュメモリを構成するキャッシュラインの第２の実施例の詳細を示す説明図である。
【図１１】ロード命令が発行された場合のキャッシュメモリ及びキャッシュ制御部の動作を示すフローチャートである。
【図１２】ストア命令が発行された場合のキャッシュメモリ及びキャッシュ制御部の動作を示すフローチャートである。
【図１３】リード要求を受信した場合のキャッシュメモリ及びキャッシュ制御部の動作を示すフローチャートである。
【図１４】ライト要求を受信した場合のキャッシュメモリ及びキャッシュ制御部の動作を示すフローチャートである。
【図１５】従来のマルチスレッド実行方法の処理の概要を示す図である。
【図１６】従来の問題点の説明図である。
【符号の説明】
１−０〜１−３…スレッド実行部
２…第１のバス
３…スレッド管理部
４…第２のバス
５…メインメモリ
【図１】
0003632635.tif 000002
【図２】
0003632635.tif 000003
【図３】
0003632635.tif 000004
【図４】
0003632635.tif 000005
【図５】
0003632635.tif 000006
【図６】
0003632635.tif 000007
【図７】
0003632635.tif 000008
【図８】
0003632635.tif 000009
【図９】
0003632635.tif 000010
【図１０】
0003632635.tif 000011
【図１１】
0003632635.tif 000012
【図１２】
0003632635.tif 000013
【図１３】
0003632635.tif 000014
【図１４】
0003632635.tif 000015
【図１５】
0003632635.tif 000016
【図１６】
0003632635.tif 000017