(57)【要約】【課題】データの受信処理効率を向上させる。【解決手段】制御部２ｂは、情報処理装置１から、スレッド１１〜１３のうち送信元スレッドとスレッド２１〜２３のうち宛先スレッドとの組み合わせを示す識別子が付加されたデータ１０を受信すると、受信が完了したことを示す完了通知をキュー２５に登録する。また、制御部２ｂは、キュー２５に登録された完了通知を周期的に取り出し、キュー２５から完了通知が取り出されたとき、取り出された完了通知に対応する、受信したデータ１０を特定し、対応情報２４に基づいて、スレッド２１〜２３のうち、データ１０に付加された識別子に対応するコネクションＣＮ１に属するスレッド２１を特定し、スレッド２１にデータ１０を受け渡す。【選択図】図１
2018182628.tif 000002
【特許請求の範囲】
【請求項１】
情報処理装置において、
前記情報処理装置で実行される複数の第１のスレッドと、他の情報処理装置で実行される複数の第２のスレッドとの間でコネクションが確立されたスレッドの組み合わせごとに、固有の第１の識別子が登録された対応情報を記憶する記憶部と、
前記他の情報処理装置から、前記複数の第２のスレッドのうち送信元スレッドと前記複数の第１のスレッドのうち宛先スレッドとの組み合わせを示す第２の識別子が付加されたデータを受信すると、受信が完了したことを示す完了通知をキューに登録する受信処理と、
前記キューに登録された前記完了通知を周期的に取り出し、前記キューから前記完了通知が取り出されたとき、取り出された前記完了通知に対応する、前記他の情報処理装置から受信した受信データを特定し、前記対応情報に基づいて、前記複数の第１のスレッドのうち、前記受信データに付加された前記第２の識別子に対応する前記コネクションに属する第３のスレッドを特定し、前記第３のスレッドに前記受信データを受け渡す受信完了処理と、
を実行する制御部と、
を有する情報処理装置。
【請求項２】
前記受信完了処理は、
前記複数の第１のスレッドのうち第４のスレッドによって、前記複数の第２のスレッドのうち第５のスレッドを送信元とするデータの受信が要求された後、前記キューから前記完了通知を取り出し、取り出された前記完了通知に対応する、前記他の情報処理装置から受信した第１の受信データを特定し、前記第１の受信データに付加された前記第２の識別子が、前記第４のスレッドと前記第５のスレッドとの組み合わせに対応する前記第１の識別子と一致しない場合には、前記第４のスレッドを待機状態に遷移させる第１の受信要求処理と、
前記複数の第１のスレッドのうち第６のスレッドによって、前記複数の第２のスレッドのうち第７のスレッドを送信元とするデータの受信が要求された後、前記キューから前記完了通知を取り出し、取り出された前記完了通知に対応する、前記他の情報処理装置から受信した第２の受信データを特定し、前記第２の受信データに付加された前記第２の識別子が、前記第４のスレッドと前記第５のスレッドとの組み合わせに対応する前記第１の識別子と一致する場合には、前記第４のスレッドに前記第２の受信データを受け渡して前記第４のスレッドの実行を再開させる第２の受信要求処理と、
を含む請求項１記載の情報処理装置。
【請求項３】
前記受信完了処理は、
前記複数の第１のスレッドのうち第４のスレッドによって、前記複数の第２のスレッドのうち第５のスレッドを送信元とするデータの受信が要求された後、前記キューから前記完了通知を取り出し、取り出された前記完了通知に対応する、前記他の情報処理装置から受信した第１の受信データを特定し、前記第１の受信データに付加された前記第２の識別子が、前記第４のスレッドと前記第５のスレッドとの組み合わせに対応する前記第１の識別子と一致しない場合には、前記第４のスレッドを待機状態に遷移させる受信要求処理と、
前記複数の第１のスレッドの実行順を制御するとともに、前記キューから前記完了通知を周期的に取り出すスケジューリング処理と、
を含み、
前記スケジューリング処理によって前記キューから取り出された前記完了通知に対応する、前記他の情報処理装置から受信した第２の受信データに、前記第４のスレッドと前記第５のスレッドとの組み合わせに対応する前記第１の識別子と一致する前記第２の識別子が付加されている場合には、前記第４のスレッドに前記第２の受信データを受け渡して前記第４のスレッドの実行を再開させる、
請求項１記載の情報処理装置。
【請求項４】
前記他の情報処理装置が複数接続されている場合、前記他の情報処理装置のそれぞれに対応する前記キューが使用される、
請求項１乃至３のいずれか１項に記載の情報処理装置。
【請求項５】
前記第１の識別子は、前記複数の第１のスレッドのうち一の第１のスレッドと、前記複数の第２のスレッドのうち一の第２のスレッドとの間の前記コネクションが確立されたとき、前記一の第１のスレッドが実行される前記情報処理装置または前記一の第２のスレッドが実行される前記他の情報処理装置のいずれかを示す識別番号と、シーケンシャルに生成される番号とを組み合わせることで生成される、
請求項４記載の情報処理装置。
【請求項６】
コンピュータが、
他のコンピュータから、前記他のコンピュータで実行される複数の第２のスレッドのうち送信元スレッドと、前記コンピュータで実行される複数の第１のスレッドのうち宛先スレッドとの組み合わせを示す第２の識別子が付加されたデータを受信すると、受信が完了したことを示す完了通知をキューに登録する受信処理と、
前記キューに登録された前記完了通知を周期的に取り出し、前記キューから前記完了通知が取り出されたとき、取り出された前記完了通知に対応する、前記他のコンピュータから受信した受信データを特定し、前記複数の第１のスレッドと前記複数の第２のスレッドとの間でコネクションが確立されたスレッドの組み合わせごとに、固有の第１の識別子が登録された対応情報に基づいて、前記複数の第１のスレッドのうち、前記受信データに付加された前記第２の識別子に対応する前記コネクションに属する第３のスレッドを特定し、前記第３のスレッドに前記受信データを受け渡す受信完了処理と、
を実行する情報処理方法。
【請求項７】
コンピュータに、
他のコンピュータから、前記他のコンピュータで実行される複数の第２のスレッドのうち送信元スレッドと、前記コンピュータで実行される複数の第１のスレッドのうち宛先スレッドとの組み合わせを示す第２の識別子が付加されたデータを受信すると、受信が完了したことを示す完了通知をキューに登録する受信処理と、
前記キューに登録された前記完了通知を周期的に取り出し、前記キューから前記完了通知が取り出されたとき、取り出された前記完了通知に対応する、前記他のコンピュータから受信した受信データを特定し、前記複数の第１のスレッドと前記複数の第２のスレッドとの間でコネクションが確立されたスレッドの組み合わせごとに、固有の第１の識別子が登録された対応情報に基づいて、前記複数の第１のスレッドのうち、前記受信データに付加された前記第２の識別子に対応する前記コネクションに属する第３のスレッドを特定し、前記第３のスレッドに前記受信データを受け渡す受信完了処理と、
を含む処理を実行させる情報処理プログラム。
【発明の詳細な説明】
【技術分野】
【０００１】
本発明は、情報処理装置、情報処理方法および情報処理プログラムに関する。
【背景技術】
【０００２】
装置間で通信するためのバスの規格として、ＩｎｆｉｎｉＢａｎｄ（登録商標）が知られている。ＩｎｆｉｎｉＢａｎｄを用いた通信では、送信側装置と受信側装置のそれぞれにおいて、要求された通信処理が完了したことを示す完了通知が格納されるキューが用いられる。このキューは、ＣＱ（Completion Queue）と呼ばれる。例えば、受信側装置で実行されるスレッドは、データの受信を要求した後、ＣＱのポーリングを行う。要求されたデータが送信側装置から受信されると、完了通知がＣＱに格納される。スレッドは、ポーリングによってＣＱから完了通知を取得できたとき、データの受信が完了したことを認識する。
【０００３】
また、ＩｎｆｉｎｉＢａｎｄに関する技術の例として、受信メッセージにＱＰ（Queue Pair）番号が付加されているかを判定し、付加されている場合だけＱＰ番号のチェックを行うことで、チェック効率を高めた情報処理装置が提案されている。
【０００４】
また、ネットワークインタフェースに関する技術の例として、それぞれＲＤＭＡ（Remote Direct Memory Access）に対応する主要なＮＩＣ（Network Interface Controller）と代替のＮＩＣとが共有する待ち行列ペアを作成し、スイッチオーバイベントの検出に応答して、待ち行列ペアの扱いを主要なＮＩＣから代替のＮＩＣに切り替える方法が提案されている。
【先行技術文献】
【特許文献】
【０００５】
【特許文献１】特開２０１５−２１６４５０号公報
【特許文献２】特表２００５−５３８５８８号公報
【発明の概要】
【発明が解決しようとする課題】
【０００６】
ここで、ＩｎｆｉｎｉＢａｎｄを用いて、送信側装置で実行される複数のスレッドと、受信側装置で実行される複数のスレッドとの間で通信が行われるケースを想定する。このケースでは、通信を行うスレッドの組み合わせごとにスレッド間のコネクションを確立し、確立されたコネクションごとに前述のＣＱを用意する方法が、最も単純な方法である。なぜなら、この方法によれば、受信側のスレッドは、自分に対応するＣＱのポーリングを行うだけで、ＣＱから自分宛ての完了通知を取得できるからである。
【０００７】
しかし、この方法には次のような問題がある。確立されたコネクションの数が多くなるほど、スレッドがデータの受信を要求してから、完了通知をＣＱから取得するまでの遅延時間が長くなる可能性がある。また、これらのコネクションの間に通信頻度の偏りがある場合、通信頻度が高いコネクションに対応するＣＱには、上記の遅延時間が長くなったとしても、ＣＱに対して時間当たりに格納される完了通知の数が多くなる。そのため、通信頻度が高いコネクションほど、受信側のスレッドがＣＱのポーリングを行ったときに完了通知を取得できる確率が高まる。
【０００８】
その反面、通信頻度が低いコネクションほど、受信側のスレッドがＣＱのポーリングを行ったときに完了通知を取得できる確率が低下する。このように通信頻度が低いコネクション上のスレッドは、完了通知を取得できない無駄なポーリングを多く実行することになる。そのため、プロセッサやメモリなどのリソースが浪費され、処理効率が低いという問題がある。
【０００９】
１つの側面では、本発明は、データの受信処理効率を向上させることが可能な情報処理装置、情報処理方法および情報処理プログラムを提供することを目的とする。
【課題を解決するための手段】
【００１０】
１つの案では、記憶部と制御部とを有する次のような情報処理装置が提供される。記憶部は、情報処理装置で実行される複数の第１のスレッドと、他の情報処理装置で実行される複数の第２のスレッドとの間でコネクションが確立されたスレッドの組み合わせごとに、固有の第１の識別子が登録された対応情報を記憶する。制御部は、他の情報処理装置から、複数の第２のスレッドのうち送信元スレッドと複数の第１のスレッドのうち宛先スレッドとの組み合わせを示す第２の識別子が付加されたデータを受信すると、受信が完了したことを示す完了通知をキューに登録する受信処理を実行する。また、制御部は、キューに登録された完了通知を周期的に取り出し、キューから完了通知が取り出されたとき、取り出された完了通知に対応する、他の情報処理装置から受信した受信データを特定し、対応情報に基づいて、複数の第１のスレッドのうち、受信データに付加された第２の識別子に対応するコネクションに属する第３のスレッドを特定し、第３のスレッドに受信データを受け渡す受信完了処理を実行する。
【００１１】
また、１つの案では、上記の情報処理装置と同様の処理をコンピュータが実行する情報処理方法が提供される。
さらに、１つの案では、上記の情報処理装置と同様の処理をコンピュータに実行させる情報処理プログラムが提供される。
【発明の効果】
【００１２】
１つの側面では、データの受信処理効率を向上させることができる。
【図面の簡単な説明】
【００１３】
【図１】第１の実施の形態に係る情報処理システムの構成例および処理例を示す図である。
【図２】第２の実施の形態に係るストレージシステムの構成例を示す図である。
【図３】ノードのハードウェア構成例を示す図である。
【図４】送信側ノードと受信側ノードとの間の基本的な通信処理手順について説明するための図である。
【図５】複数スレッド同士での通信処理の比較例を示す図である。
【図６】本実施の形態におけるＱＰ／ＣＱの配置を示す図である。
【図７】複数スレッド同士の通信について説明するための図である。
【図８】ノードが備える処理機能の構成例を示すブロック図である。
【図９】スレッドスケジューリングの第１の比較例を示す図である。
【図１０】スレッドスケジューリングの第２の比較例を示す図である。
【図１１】本実施の形態でのスレッドスケジューリングの例を示す図である。
【図１２】スレッドスケジューリングで使用されるデータ構造の例を示す図である。
【図１３】キュー間のエントリ移動によるサスペンドおよび起床動作について説明するための図である。
【図１４】スレッドの状態遷移についての第１の例を示す図である。
【図１５】スレッドの状態遷移についての第２の例を示す図である。
【図１６】スレッド間のコネクション確立を要求する処理手順の例を示すフローチャートである。
【図１７】メッセージの送信を要求する処理手順の例を示すフローチャートである。
【図１８】メッセージの受信を要求する処理手順の例を示すフローチャート（その１）である。
【図１９】メッセージの受信を要求する処理手順の例を示すフローチャート（その２）である。
【図２０】メッセージの受信を要求する処理手順の例を示すフローチャート（その３）である。
【図２１】スレッドスケジューラの処理手順の例を示すフローチャート（その１）である。
【図２２】スレッドスケジューラの処理手順の例を示すフローチャート（その２）である。
【図２３】スレッドの処理例を示す図である。
【発明を実施するための形態】
【００１４】
以下、本発明の実施の形態について図面を参照して説明する。
〔第１の実施の形態〕
図１は、第１の実施の形態に係る情報処理システムの構成例および処理例を示す図である。図１に示す情報処理システムは、情報処理装置１，２を有する。情報処理装置１と情報処理装置２との間は、例えば、ＩｎｆｉｎｉＢａｎｄによって接続されている。そして、情報処理装置１と情報処理装置２とは、互いに通信することが可能になっている。
【００１５】
情報処理装置１では、スレッド１１〜１３が実行される。一方、情報処理装置２では、スレッド２１〜２３が実行される。そして、スレッド１１とスレッド２１との間でコネクションＣＮ１が確立されており、コネクションＣＮ１を介してスレッド１１とスレッド２１との通信が行われる。また、スレッド１２とスレッド２２との間でコネクションＣＮ２が確立されており、コネクションＣＮ２を介してスレッド１２とスレッド２２との通信が行われる。さらに、スレッド１３とスレッド２３との間でコネクションＣＮ３が確立されており、コネクションＣＮ３を介してスレッド１３とスレッド２３との通信が行われる。
【００１６】
以下、情報処理装置１から情報処理装置２に対してデータが送信される場合について説明する。
受信側の情報処理装置２は、記憶部２ａと制御部２ｂとを有する。記憶部２ａは、例えば、ＲＡＭ（Random Access Memory）やＨＤＤ（Hard Disk Drive）など、情報処理装置２が備える記憶装置の記憶領域として実現される。制御部２ｂは、例えば、情報処理装置２が備えるプロセッサとして実現される。
【００１７】
記憶部２ａには、対応情報２４が記憶されている。対応情報２４には、情報処理装置１で実行される複数のスレッドと、情報処理装置２で実行される複数のスレッドとの間でコネクションが確立されたスレッドの組み合わせごとに、固有の識別子が登録されている。図１の例では、スレッド１１とスレッド２１との間のコネクションＣＮ１に対して、識別子「００」が登録されている。また、スレッド１２とスレッド２２との間のコネクションＣＮ２に対して、識別子「０１」が登録されている。さらに、スレッド１３とスレッド２３との間のコネクションＣＮ３に対して、識別子「０２」が登録されている。
【００１８】
また、記憶部２ａには、ＦＩＦＯ（First In First Out）方式で情報を格納するキュー２５が記憶されている。キュー２５には、情報処理装置２のスレッド２１〜２３のいずれかが、情報処理装置１からのデータの受信を要求し、要求されたデータを情報処理装置１が受信したときに、受信完了を示す完了通知が格納される。ある受信要求に対応する完了通知を制御部２ｂが取得できたとき、制御部２ｂは、この受信要求に対応するデータの受信が完了したことを認識できる。
【００１９】
情報処理装置１から情報処理装置２に対しては、確立されたコネクションＣＮ１〜ＣＮ３のいずれかを介してデータが送信される。このとき、送信されるデータには、コネクション（すなわち、送信元スレッドと宛先スレッドとの組み合わせ）を示す識別子が付加される。
【００２０】
例えば、スレッド１１が、情報処理装置１の通信インタフェース（図示せず）に対してデータの送信を要求することで、コネクションＣＮ１を介してデータ１０が送信されたとする。このとき、送信されるデータ１０には、コネクションＣＮ１を示す識別子「００」が付加される。一方、スレッド２１は、情報処理装置２の通信インタフェース（図示せず）に対してデータの受信を要求し、受信待ち状態になる。
【００２１】
制御部２ｂは、情報処理装置１からデータ１０を受信すると、受信が完了したことを示す完了通知をキュー２５に登録する（ステップＳ１）。その後、制御部２ｂは、キュー２５に登録された完了通知を周期的に取り出す（ステップＳ２）。
【００２２】
キュー２５から完了通知が取り出されると、制御部２ｂは、取り出された完了通知に対応する受信データを特定し、その受信データに付加された識別子を取得する。制御部２ｂは、対応情報２４を参照し、スレッド２１〜２３の中から、取得した識別子に対応するコネクションに属するスレッドを特定する。
【００２３】
例えば、取り出された完了通知に対応する受信データとしてデータ１０が特定されたとする。この場合、データ１０に付加された識別子「００」が取得され、識別子「００」が示すコネクションＣＮ１に属するスレッド２１が特定される。すると、制御部２ｂは、特定されたスレッド２１に受信されたデータ１０を受け渡す（ステップＳ３）。これにより、スレッド２１は、受信待ち状態から復帰し、データ１０を用いて処理を続行できる。
【００２４】
以上の情報処理装置２では、完了通知が格納されるキュー２５がスレッド２１〜２３によって共用される。これとともに、情報処理装置１から送信されるデータに、通信で使用されたコネクションを識別する識別子が付加される。これにより、制御部２ｂは、キュー２５から取得した完了通知に対応する受信データから識別子を取得することで、受信データの宛先がスレッド２１〜２３のどれであるかを判別可能になる。そして、このように宛先のスレッドを判別可能になることで、１つのキュー２５をスレッド２１〜２３によって共用できるようになる。
【００２５】
キュー２５をスレッド２１〜２３のそれぞれに対して個別に用意せずに、１つだけ用意したことで、キュー２５には、１つのコネクションだけでなく、コネクションＣＮ１〜ＣＮ３のどれを介して受信されたデータに対応する完了通知も、格納されるようになる。このため、コネクションＣＮ１〜ＣＮ３の間で通信頻度に偏りがある場合でも、キュー２５に完了通知が格納されている可能性が高くなる。
【００２６】
したがって、制御部２ｂがキュー２５からの完了通知の取り出しを周期的に行ったときに、取り出せる完了通知がキュー２５に存在しない可能性が低くなる。その結果、完了通知を取り出せない無駄な取り出し処理が実行される可能性が低減されるので、制御部２ｂによる受信処理全体の処理効率を向上させることができる。
【００２７】
〔第２の実施の形態〕
図２は、第２の実施の形態に係るストレージシステムの構成例を示す図である。図２に示すストレージシステムは、ノード１００−１〜１００−４を有する。ノード１００−１，１００−２，１００−３，１００−４には、それぞれストレージ２００−１，２００−２，２００−３，２００−４が接続されている。そして、ノード１００−１，１００−２，１００−３，１００−４は、それぞれストレージ２００−１，２００−２，２００−３，２００−４に対するアクセスを制御するストレージ制御装置として動作する。
【００２８】
なお、ストレージ２００−１〜２００−４のそれぞれには、１台または複数台の不揮発性記憶装置が搭載されている。不揮発性記憶装置は、例えば、ＳＳＤ（Solid State Drive）やＨＤＤ（Hard Disk Drive）である。また、ノード１００−１とストレージ２００−１、ノード１００−２とストレージ２００−２、ノード１００−３とストレージ２００−３、ノード１００−４とストレージ２００−４は、それぞれストレージノードを形成する。なお、ストレージシステムに含まれるストレージノードの数は、図２のように４ノードに限定されるものではなく、２以上の任意の数とすることができる。
【００２９】
ノード１００−１〜１００−４は、スイッチ３００を介して互いに接続されている。本実施の形態では、ノード１００−１〜１００−４は、ＩｎｆｉｎｉＢａｎｄで互いに接続されている。また、ノード１００−１〜１００−４は、ネットワーク４００を介してホスト装置４１０，４２０と接続されている。ノード１００−１〜１００−４とホスト装置４１０，４２０との間は、例えば、ＳＡＳ（Serial Attached SCSI，SCSI：Small Computer System Interface）やＦＣ（Fibre Channel）を用いたＳＡＮ（Storage Area Network）によって接続されている。
【００３０】
このストレージシステムは、例えば、ホスト装置４１０，４２０から書き込みが要求されたデータが分散して格納される分散ストレージシステムとして動作する。例えば、次のようなストレージアクセス制御が実行される。
【００３１】
ストレージシステムは、ホスト装置４１０，４２０に対して複数の論理ボリュームを提供する。ホスト装置４１０，４２０は、ある論理ボリュームにアクセスする際、ノード１００−１〜１００−４のいずれかに対してＩＯ（Input／Output）要求を送信する。また、論理ボリュームにおける書き込みアドレスの範囲ごとに、データの格納を行う担当ノードがあらかじめ決められている。
【００３２】
例えば、あるノードがＩＯ要求として書き込み要求を受信したとする。書き込み要求を受信したノードは、書き込みアドレスを解析して、ノード１００−１〜１００−４の中から担当ノードを判別し、担当ノードに対して書き込みデータを転送する。担当ノードは、転送された書き込みデータを一旦キャッシュに格納した後、非同期のタイミングで、担当ノードに接続されているストレージに書き込みデータを格納する。
【００３３】
また、例えば、担当ノードは、書き込みデータのハッシュ値に基づいて決められていてもよい。この場合、担当ノードは、書き込みデータのハッシュ値に基づいて、同一内容のデータが重複してストレージに格納されないように制御する「重複除去」を行うこともできる。
【００３４】
なお、ストレージシステムに接続可能なホスト装置の台数は、図２のように２台に限定されるものではない。
図３は、ノードのハードウェア構成例を示す図である。図３に示すノード１００は、図２に示したノード１００−１〜１００−４のいずれかを示す。以下の説明では、ノード１００−１〜１００−４のそれぞれを特に区別せずに示す場合には、「ノード１００」と記載する場合がある。
【００３５】
ノード１００は、例えば、図３に示すようなコンピュータとして実現される。ノード１００は、ＣＰＵ（Central Processing Unit）１０１ａ〜１０１ｃ、メモリ１０２、ＳＳＤ１０３、読み取り装置１０４、ホストインタフェース１０５、ドライブインタフェース１０６およびＨＣＡ（Host Channel Adapter）１０７を有する。
【００３６】
ＣＰＵ１０１ａ〜１０１ｃは、ノード１００全体を統括的に制御する。なお、ＣＰＵの個数は３つに限定されるものではない。メモリ１０２は、ＤＲＡＭ（Dynamic Random Access Memory）などの揮発性記憶装置であり、ノード１００の主記憶装置として使用される。メモリ１０２には、ＣＰＵ１０１ａ〜１０１ｃに実行させるＯＳ（Operating System）プログラムやアプリケーションプログラムの少なくとも一部が一時的に格納される。また、メモリ１０２には、ＣＰＵ１０１ａ〜１０１ｃによる処理に必要な各種データが格納される。
【００３７】
ＳＳＤ１０３は、ノード１００の補助記憶装置として使用される。ＳＳＤ１０３には、ＯＳプログラム、アプリケーションプログラム、および各種データが格納される。なお、補助記憶装置としては、ＨＤＤなどの他の種類の不揮発性記憶装置が用いられてもよい。読み取り装置１０４には、可搬型記録媒体１０４ａが脱着される。読み取り装置１０４は、可搬型記録媒体１０４ａに記録されたデータを読み取ってＣＰＵ１０１ａ〜１０１ｃに送信する。可搬型記録媒体１０４ａとしては、光ディスク、光磁気ディスク、半導体メモリなどがある。
【００３８】
ホストインタフェース１０５は、ネットワーク４００を介してホスト装置４１０，４２０との間で通信するためのインタフェース装置である。ドライブインタフェース１０６は、ストレージ２００との間で通信するためのインタフェース装置である。ＨＣＡ１０７は、スイッチ３００を介して他のノード１００と通信するための、ＩｎｆｉｎｉＢａｎｄに準拠したインタフェース装置である。
【００３９】
以上のハードウェア構成によってノード１００（ノード１００−１〜１００−４）の処理機能を実現することができる。なお、ホスト装置４１０，４２０も、ノード１００と同様にＣＰＵやメモリなどを有するコンピュータとして実現することができる。
【００４０】
＜スレッドに対するキューの割り当て＞
次に、ノードで実行されるスレッドに対する、ノード間の通信で用いられるキューの割り当てについて説明する。ここではまず、図４、図５を用いて、ＩｎｆｉｎｉＢａｎｄを用いたノード間通信の比較例について説明し、その後に本実施の形態におけるノード間通信について説明する。
【００４１】
図４は、送信側ノードと受信側ノードとの間の基本的な通信処理手順について説明するための図である。図４では、ＨＣＡ５１１を有するノード５１０と、ＨＣＡ５２１を有するノード５２０とを示し、ノード５１０からノード５２０に対してＩｎｆｉｎｉＢａｎｄを介してデータが送信される場合について説明する。
【００４２】
ＩｎｆｉｎｉＢａｎｄでは、送信用のＱＰ５１２と、受信用のＱＰ５２２とを用いて通信が行われる。送信用のＱＰ５１２は、送信要求を示すエントリを格納するＦＩＦＯであり、「ＳＱ（Send Queue）」とも呼ばれる。ＱＰ５１２に格納されるエントリには、例えば、送信メッセージが格納されている送信バッファのアドレスなどが含まれる。また、受信用のＱＰ５２２は、受信要求を示すエントリを格納するＦＩＦＯであり、「ＲＱ（Receive Queue）」とも呼ばれる。ＱＰ５２２に格納されるエントリには、例えば、受信メッセージが格納される受信バッファのアドレスなどが含まれる。
【００４３】
送信側のノード５１０において、アプリケーション５１３は、メッセージを送信する際、送信関数「ｓｅｎｄ」（例えば、ibv＿post＿send()）を発行する。すると、送信要求を示すエントリがＱＰ５１２に格納されるとともに、引数として指定されたアドレスが示す送信バッファに送信メッセージがセットされる。なお、ＱＰ５１２に格納されるエントリはＷＱＥ（Work Queue Element）と呼ばれる。ＨＣＡ５１１は、ＱＰ５１２から取得したエントリに基づいて送信メッセージを送信する。
【００４４】
また、ＩｎｆｉｎｉＢａｎｄでは、ＱＰに加えてＣＱが用いられる。ＣＱは、完了を示すエントリを格納するＦＩＦＯである。ＣＱに格納されるエントリは、ＣＱＥ（Completion Queue Entry）と呼ばれる。このエントリが示す「完了（Completion）」の内容としては、ＱＰのエントリに対応する処理が正常に終了したことを示す「Successful Completion」と、エラーで終了したことを示す「Completion Error」とがある。
【００４５】
ＨＣＡ５１１によるメッセージ送信処理が完了すると、完了を示すエントリがＣＱ５１４に格納される。アプリケーション５１３は、送信関数「ｓｅｎｄ」の発行後にＣＱ５１４のポーリングを行うことで、送信要求に応じた処理の完了を示すエントリをＣＱ５１４から取得する。
【００４６】
一方、受信側のノード５２０において、アプリケーション５２３は、メッセージを受信する際、受信関数「ｒｅｃｖ」（例えば、ibv＿post＿recv()）を発行する。すると、受信要求を示すエントリがＱＰ５２２に格納される。ＨＣＡ５２１は、ＱＰ５２２から取得したエントリに基づいてメッセージを受信し、エントリに含まれるアドレスが示す受信バッファに受信メッセージをセットする。また、ＨＣＡ５２１によるメッセージ受信処理が完了すると、完了を示すエントリがＣＱ５２４に格納される。アプリケーション５２３は、受信関数「ｒｅｃｖ」の発行後にＣＱ５２４のポーリングを行うことで、受信要求に応じた処理の完了を示すエントリをＣＱ５２４から取得する。アプリケーション５２３は、取得したエントリに含まれるアドレスが示す受信バッファから、受信メッセージを取得する。
【００４７】
このように、ＩｎｆｉｎｉＢａｎｄを通じて通信する場合、アプリケーションは、メッセージの送信または受信を要求した後、ＣＱをポーリングすることで、要求した処理が完了したことを検知する。
【００４８】
図５は、複数スレッド同士での通信処理の比較例を示す図である。なお、これ以後、「ＱＰ／ＣＱ」とは、送信用のＱＰと、これに対応するＣＱと、受信用のＱＰと、これに対応するＣＱとを含むものとする。ただし、ＣＱは、送信用のＱＰと受信用のＱＰとで共用することも可能である。
【００４９】
ここでは、あるノードで実行される特定のスレッドと、それとは異なるノードで実行される特定のスレッドとの間で通信が行われる場合を想定する。この場合には、一方のノードの１つのスレッドと他方のノードの１つのスレッドとの間で、論定的な通信路であるコネクションを確立し、コネクションごとに個別のＱＰ／ＣＱを割り当てる方法が最も単純な方法である。なぜなら、この方法によれば、各スレッドは、送信や受信を要求した後、割り当てられたＣＱをポーリングするだけで、自分宛てのエントリを容易に取得できるからである。
【００５０】
例えば図５では、ノード５１０でスレッド５１５ａ〜５１５ｄが実行され、ノード５２０でスレッド５２５ａ〜５２５ｄが実行されている。そして、スレッド５１５ａとスレッド５２５ａとの間、スレッド５１５ｂとスレッド５２５ｂとの間、スレッド５１５ｃとスレッド５２５ｃとの間、スレッド５１５ｄとスレッド５２５ｄとの間で、それぞれ通信が行われる。
【００５１】
この場合、スレッド５１５ａとスレッド５２５ａとの間のコネクション５３１ａにおいては、スレッド５１５ａに対してＱＰ／ＣＱ５１６ａが割り当てられ、スレッド５２５ａに対してＱＰ／ＣＱ５２６ａが割り当てられる。同様に、スレッド５１５ｂとスレッド５２５ｂとの間のコネクション５３１ｂにおいては、スレッド５１５ｂに対してＱＰ／ＣＱ５１６ｂが割り当てられ、スレッド５２５ｂに対してＱＰ／ＣＱ５２６ｂが割り当てられる。また、スレッド５１５ｃとスレッド５２５ｃとの間にコネクション５３１ｃにおいては、スレッド５１５ｃに対してＱＰ／ＣＱ５１６ｃが割り当てられ、スレッド５２５ｃに対してＱＰ／ＣＱ５２６ｃが割り当てられる。さらに、スレッド５１５ｄとスレッド５２５ｄとの間のコネクション５３１ｄにおいては、スレッド５１５ｄに対してＱＰ／ＣＱ５１６ｄが割り当てられ、スレッド５２５ｄに対してＱＰ／ＣＱ５２６ｄが割り当てられる。
【００５２】
このような構成とすることで、例えば、ＱＰ／ＣＱ５２６ａのＣＱには、スレッド５２５ａ宛てのエントリだけが格納される。そのため、スレッド５２５ａは、メッセージの受信を要求した後、ＱＰ／ＣＱ５２６ａのＣＱを監視するだけで、受信要求に対応する完了のエントリを容易に取得できる。
【００５３】
しかしながら、このような構成では、スレッド間で確立されたコネクションの数が多くなった場合に次のような問題がある。
スレッド間で確立されたコネクション５３１ａ〜５３１ｄは、共通の物理的な通信経路上に存在する。そのため、確立されたコネクションの数が多いほど、スレッドが送信または受信を要求してから、その要求に対応する完了のエントリをＣＱから取得できるまでの遅延時間が長くなる可能性がある。
【００５４】
また、コネクション５３１ａ〜５３１ｄの間で通信頻度に偏りがある場合、通信頻度が高いスレッドに対応するＣＱには、上記の遅延時間が長くなったとしても、ＣＱに対して時間当たりに格納されるエントリの数が多くなる。そのため、通信頻度が高いコネクション上のスレッドほど、ＣＱに対してポーリングしたときに完了のエントリを取得できる確率が高まる。しかし、その一方で、通信頻度が低いコネクション上のスレッドほど、ＣＱに対してポーリングしたときに完了のエントリを取得できる確率が低下する。このように通信頻度が低いコネクション上のスレッドは、無駄なポーリングを多く実行していることになり、ＣＰＵやメモリなどのリソースを浪費するという問題がある。
【００５５】
このような問題に対して、本実施の形態では、次の図６のようにＱＰ／ＣＱが配置される。
図６は、本実施の形態におけるＱＰ／ＣＱの配置を示す図である。本実施の形態では、１つのノードは、通信相手のノードごとにＱＰ／ＣＱをそれぞれ１つだけ有する。具体的には、図６に示すように、ノード１００−１は、ノード１００−２，１００−３，１００−４とそれぞれ通信するためのＱＰ／ＣＱ１１１ａ−１，１１１ｂ−１，１１１ｃ−１を有する。ノード１００−２は、ノード１００−１，１００−３，１００−４とそれぞれ通信するためのＱＰ／ＣＱ１１１ａ−２，１１１ｂ−２，１１１ｃ−２を有する。ノード１００−３は、ノード１００−１，１００−２，１００−４とそれぞれ通信するためのＱＰ／ＣＱ１１１ａ−３，１１１ｂ−３，１１１ｃ−３を有する。ノード１００−４は、ノード１００−１，１００−２，１００−３とそれぞれ通信するためのＱＰ／ＣＱ１１１ａ−４，１１１ｂ−４，１１１ｃ−４を有する。
【００５６】
このように、本実施の形態では、１つのノード内で他の１つのノードとの通信で用いられるＱＰ／ＣＱが１つだけに限定される。そして、次の図７に示すように、１つのノードでは、他の１つのノードと通信する複数のスレッドが、１つのＱＰ／ＣＱを共用する。
【００５７】
図７は、複数スレッド同士の通信について説明するための図である。図７では、例として、ノード１００−１とノード１００−２との間の通信について説明する。また、ノード１００−１でスレッド５１５ａ〜５１５ｄが実行され、ノード１００−２でスレッド５２５ａ〜５２５ｄが実行されるものとする。そして、スレッド５１５ａとスレッド５２５ａとの間、スレッド５１５ｂとスレッド５２５ｂとの間、スレッド５１５ｃとスレッド５２５ｃとの間、スレッド５１５ｄとスレッド５２５ｄとの間で、それぞれ通信が行われるものとする。
【００５８】
ノード１００−１は、ノード１００−２との通信のためのＱＰ／ＣＱ１１１ａ−１を有する。そして、ＱＰ／ＣＱ１１１ａ−１は、ノード１００−２との通信の際にスレッド５１５ａ〜５１５ｄによって共用される。一方、ノード１００−２は、ノード１００−１との通信のためのＱＰ／ＣＱ１１１ａ−２を有する。そして、ＱＰ／ＣＱ１１１ａ−２は、ノード１００−１との通信の際にスレッド５２５ａ〜５２５ｄによって共用される。
【００５９】
ただし、この構成では、例えばスレッド５２５ａ〜５２５ｄからそれぞれ受信要求が発行された場合、ＱＰ／ＣＱ１１１ａ−２のＣＱには、スレッド５２５ａ〜５２５ｄのそれぞれを宛先とする完了のエントリが混在する。このとき、スレッド５２５ａ〜５２５ｄは、ＱＰ／ＣＱ１１１ａ−２のＣＱに格納されたエントリがどのスレッド宛てのものかを判別できない。
【００６０】
そこで、本実施の形態では、スレッド間で確立されたコネクションごとに、システム全体でユニークな識別番号である「ＸＩＤ」が付与される。そして、あるスレッドから他のノードのスレッド宛てにメッセージが送信される際に、それらのスレッド間のコネクションに対応するＸＩＤが送信メッセージに付加される。これにより、受信側ノードのスレッドは、ＣＱから取得したエントリに基づいて受信メッセージを取得したとき、受信メッセージに含まれるＸＩＤから、エントリが自分宛てであるか否かを判別できるようになる。
【００６１】
ＸＩＤは、ＸＩＤの発行元ノードを示すノード番号と、発行のたびにシーケンシャルに変更される番号とを組み合わせて生成される。ＸＩＤが発行元ノード番号を含むことで、他のいずれのノードでも同じＸＩＤが生成されないようにすることができる。なお、後述するように、ＸＩＤは、スレッド間のコネクションが確立される際に生成される。「発行元ノード」とは、コネクションの確立を持ちかけたノードを指す。
【００６２】
さらに、本実施の形態では、あるスレッドがポーリングによりＣＱからエントリを取得したとき、そのエントリが他のスレッド宛てであった場合には、その旨を他のスレッドに認識させることが可能となっている。例えば、スレッド５２５ａがＱＰ／ＣＱ１１１ａ−２のＣＱをポーリングして、受信完了を示すエントリを取得したとき、そのエントリがスレッド５２５ｂ宛てであった場合には、スレッド５２５ａは、エントリに対応する受信メッセージをスレッド５２５ｂに受け渡す。スレッド５２５ｂは、その受信メッセージを用いて処理を継続することができる。
【００６３】
以上のように、本実施の形態では、１つのノード内で他の１つのノードとの通信で用いられるＣＱが１つだけに限定される。また、ノード上のスレッドは、ポーリングによりＣＱからエントリを取得したとき、そのエントリがどのスレッド宛てのものかをＸＩＤから判別し、宛先のスレッドに対してそのエントリに対応する通信処理の完了を認識させる。
【００６４】
これにより、スレッド間で通信頻度に偏りがある場合でも、各スレッドがＣＱのポーリングを行ったときに、どのスレッド宛てのエントリも取得できないという確率が低くなる。その結果、無駄なポーリングの回数を減少させることができ、ＣＰＵやメモリなどのリソースの利用効率が向上する。また、ノードにおけるリソースの利用効率が向上することで、ホスト装置からのＩＯ要求に対する応答速度を高めることもできる。
【００６５】
なお、ＱＰ／ＣＱは、例えば、ストレージシステムの運用を開始した初期段階において、各ノードのメモリ領域に作成される。例えば、各ノードは、他のノードのＨＣＡ１０７のアドレスを指定することでそのＨＣＡ１０７のデバイス情報を取得し、デバイス情報を基に他のノードに対応するＱＰ／ＣＱを作成する。接続されたノード間でＱＰ／ＣＱの作成完了が認識されることで、ノード間の通信が可能になる。
【００６６】
＜ノードの処理機能＞
図８は、ノードが備える処理機能の構成例を示すブロック図である。ノード１００は、記憶部１１０、アプリケーション１２０、スレッドスケジューラ１３１〜１３３およびＨＣＡドライバ１４０を有する。
【００６７】
記憶部１１０は、例えば、メモリ１０２の記憶領域として実装される。記憶部１１０には、ＱＰ／ＣＱ１１１ａ〜１１１ｃ、ＸＩＤ−Ｑｓｔｒ対応テーブル１１２、コネクションプール１１３、スレッド−関数対応テーブル１１４およびＲｅａｄｙキュー１１５ａ〜１１５ｃが記憶される。
【００６８】
ＱＰ／ＣＱ１１１ａ〜１１１ｃは、他のノードとの通信で使用されるＱＰ／ＣＱである。前述のように、ＱＰ／ＣＱ１１１ａ〜１１１ｃは、それぞれ個別のノードに対応付けられている。
【００６９】
ＸＩＤ−Ｑｓｔｒ対応テーブル１１２は、ＸＩＤと待ち合わせ構造体（Ｑ−Ｓｔｒｕｃｔｕｒｅ）との対応関係を保持する。ＸＩＤ−Ｑｓｔｒ対応テーブル１１２には、ノード間のコネクションが確立されて新たなＸＩＤが発行されるたびに、ＸＩＤと待ち合わせ構造体を示す情報とを含むレコードが追加登録される。なお、待ち合わせ構造体とは、後述するように、サスペンド状態のスレッドを管理するためのデータ構造体であり、１つのＸＩＤに対して１つ生成される。
【００７０】
コネクションプール１１３は、未使用のコネクション構造体を保持する。コネクション構造体とは、後述するように、スレッド間のコネクションを介した通信のために使用されるデータ構造体であり、１つのＸＩＤに対して１つ使用される。
【００７１】
スレッド−関数対応テーブル１１４は、スレッドの処理内容の種別と、その種別のスレッドで実行される関数との対応関係を保持する。
Ｒｅａｄｙキュー１１５ａ〜１１５ｃは、実行されるスレッドに対応するエントリを格納するキューである。Ｒｅａｄｙキュー１１５ａ，１１５ｂ，１１５ｃは、それぞれスレッドスケジューラ１３１，１３２，１３３から参照される。
【００７２】
アプリケーション１２０の処理は、例えば、ＣＰＵ１０１ａ〜１０１ｃによって所定のアプリケーションプログラムが実行されることで実現される。アプリケーション１２０は、例えば、ストレージのアクセス制御処理を実行する。アプリケーション１２０の処理は、複数のスレッドを含む。
【００７３】
スレッドスケジューラ１３１〜１３３およびＨＣＡドライバ１４０の処理は、例えば、ＣＰＵ１０１ａ〜１０１ｃによってＯＳプログラムが実行されることで実現される。
スレッドスケジューラ１３１は、Ｒｅａｄｙキュー１１５ａに基づいて、アプリケーション１２０のスレッドのうち、ＣＰＵ１０１ａによって実行されるスレッド１２１ａ，１２１ｂ，・・・の実行順を制御する。スレッドスケジューラ１３２は、Ｒｅａｄｙキュー１１５ｂに基づいて、アプリケーション１２０のスレッドのうち、ＣＰＵ１０１ｂによって実行されるスレッド１２２ａ，１２２ｂ，・・・の実行順を制御する。スレッドスケジューラ１３３は、Ｒｅａｄｙキュー１１５ｃに基づいて、アプリケーション１２０のスレッドのうち、ＣＰＵ１０１ｃによって実行されるスレッド１２３ａ，１２３ｂ，・・・の実行順を制御する。
【００７４】
ＨＣＡドライバ１４０は、ＨＣＡ１０７の動作を制御する。また、ＨＣＡドライバ１４０は、アプリケーション１２０に対して、ＨＣＡ１０７を使用するためのＡＰＩ（Application Programming Interface）を提供する。
【００７５】
＜ＣＱのポーリングとスレッドスケジューリング＞
次に、ＣＱのポーリングとスレッドスケジューリングについて説明する。まず、図９、図１０を用いて、スレッドスケジューリングの比較例について説明した後、図１１を用いて、本実施の形態のスレッドスケジューリングについて説明する。
【００７６】
図９は、スレッドスケジューリングの第１の比較例を示す図である。図９では例として、スレッドスケジューラ１３１によるスレッドのスケジューリングについて示す。スレッドスケジューラ１３１は、Ｒｅａｄｙキュー１１５ａからエントリを順に取得し、取得したエントリに対応するスレッドの実行を開始させる。スレッドは、ある一定の長さを限度とする処理を実行すると、サスペンドして、制御をスレッドスケジューラ１３１に移す。
【００７７】
例えば、図９に示すように、スレッドスケジューラ１３１は、スレッド１２１ａの実行を開始させる。スレッド１２１ａは、処理Ａ１を実行した後、サスペンドして、制御をスレッドスケジューラ１３１に移す。次に、スレッドスケジューラ１３１は、スレッド１２１ｂの実行を開始させる。スレッド１２１ｂは、処理Ｂ１を実行した後、サスペンドして、制御をスレッドスケジューラ１３１に移す。次に、スレッドスケジューラ１３１は、スレッド１２１ｃの実行を開始させる。スレッド１２１ｃは、処理Ｃ１を実行した後、サスペンドして、制御をスレッドスケジューラ１３１に移す。次に、スレッドスケジューラ１３１は、スレッド１２１ａの実行を開始させる。スレッド１２１ａは、処理Ａ１の次の処理Ａ２を実行する。
【００７８】
図１０は、スレッドスケジューリングの第２の比較例を示す図である。この図１０では、スレッド１２１ａ，１２１ｂが実行され、スレッド１２１ａによってメッセージの受信処理が行われる場合の例を示す。
【００７９】
まず、スレッドスケジューラ１３１は、スレッド１２１ａの実行を開始させる（タイミングＴ１１）。スレッド１２１ａは、ＨＣＡドライバ１４０に対して受信関数「ｒｅｃｖ」を発行する。これにより、受信メッセージに対応するエントリがＱＰに登録される。また、スレッド１２１ａは、メッセージの受信待ち状態となり、ＣＱに対してポーリングするための関数（ibv＿poll＿cq）を、受信要求に対応するエントリをＣＱから取得できるまでの間、一定時間ごとに発行する。しかし、所定回数だけ関数を発行しても対応するエントリを取得できなかった場合、スレッド１２１ａは、一旦サスペンドして、制御をスレッドスケジューラ１３１に移す（タイミングＴ１２）。
【００８０】
スレッドスケジューラ１３１は、スレッド１２１ｂの実行を開始させる（タイミングＴ１３）。スレッド１２１ｂは、処理Ｂ１を実行した後、サスペンドして、制御をスレッドスケジューラ１３１に移す（タイミングＴ１４）。スレッドスケジューラ１３１は、スレッド１２１ａを起床させる（タイミングＴ１５）。起床したスレッド１２１ａは、ポーリングのための関数の発行を再度繰り返す。しかし、所定回数だけ関数を発行しても対応するエントリを取得できなかった場合、スレッド１２１ａは、サスペンドして、制御をスレッドスケジューラ１３１に移す（タイミングＴ１６）。
【００８１】
スレッドスケジューラ１３１は、スレッド１２１ｂの実行を開始させる（タイミングＴ１７）。スレッド１２１ｂは、処理Ｂ１の次の処理Ｂ２を実行した後、サスペンドして、制御をスレッドスケジューラ１３１に移す（タイミングＴ１８）。スレッドスケジューラ１３１は、スレッド１２１ａを起床させる（タイミングＴ１９）。起床したスレッド１２１ａは、ポーリングのための関数の発行を再度繰り返す。しかし、所定回数だけ関数を発行しても対応するエントリを取得できなかった場合、スレッド１２１ａは、サスペンドして、制御をスレッドスケジューラ１３１に移す（タイミングＴ２０）。スレッドスケジューラ１３１は、スレッド１２１ｂの実行を開始させ（タイミングＴ２１）、スレッド１２１ｂは、処理Ｂ２の次の処理Ｂ３を実行する。
【００８２】
以上の例のように、受信関数「ｒｅｃｖ」の発行後に長期間受信メッセージが到着しない場合、スレッド１２１ａは、起床、ポーリング、サスペンドという動作を何度も繰り返すことになる。スレッド１２１ａの起床やサスペンドが行われるたびに、コンテキストスイッチが発生する。コンテキストスイッチは、レジスタのデータ退避などの処理を伴うため、ＣＰＵの処理負荷が大きい。このため、上記のようにスレッド１２１ａの起床やサスペンドが繰り返されると、ＣＰＵの処理負荷が増大して、実行可能な他のスレッド１２１ｂの処理が遅延してしまい、処理効率が低下するという問題がある。
【００８３】
このような問題に対して、本実施の形態では、スレッドだけでなく、スレッドスケジューラもＣＱのポーリングを実行可能にする。そして、スレッドは、受信関数「ｒｅｃｖ」の発行後、ＣＱのポーリングを１回だけ実行し、自分宛てのメッセージが到着していない場合にはサスペンドする。このスレッドに対応するエントリを取得するためのポーリングは、それ以後、スレッドスケジューラ（または他のスレッド）によって実行される。
【００８４】
図１１は、本実施の形態でのスレッドスケジューリングの例を示す図である。図１１では、図１０の比較例と同様に、スレッド１２１ａ，１２１ｂが実行され、スレッド１２１ａによってメッセージの受信処理が行われる場合の例を示す。
【００８５】
まず、スレッドスケジューラ１３１は、スレッド１２１ａの実行を開始させる（タイミングＴ３１）。スレッド１２１ａは、ＨＣＡドライバ１４０に対して受信関数「ｒｅｃｖ」を発行し、その後１回だけＣＱのポーリングを行う。このとき、対応するエントリを取得できなかった場合、スレッド１２１ａは、即座にサスペンドして、制御をスレッドスケジューラ１３１に移す（タイミングＴ３２）。
【００８６】
一方、スレッドスケジューラ１３１は、制御が移されるたびに、次に実行させるスレッドのスケジューリングとともに、ＣＱのポーリングを行う。図１１の例では、タイミングＴ３２でスレッド１２１ａから制御が移されると、スレッドスケジューラ１３１は、次に実行させるスレッドとしてスレッド１２１ｂを選択するとともに、ＣＱのポーリングを行う。そして、それが終了すると、スレッドスケジューラ１３１はスレッド１２１ｂの実行を開始させる（タイミングＴ３３）。
【００８７】
スレッド１２１ｂによる処理Ｂ１の実行が終了すると、制御がスレッドスケジューラ１３１に移り（タイミングＴ３４）、スレッドスケジューラ１３１によるスケジューリングとポーリングとが行われる。スレッド１２１ａに対応するエントリをＣＱから取得できない場合、スレッド１２１ｂが起床して後続の処理Ｂ２を実行する（タイミングＴ３５）。
【００８８】
処理Ｂ２の実行が終了すると、制御がスレッドスケジューラ１３１に移り（タイミングＴ３６）、スレッドスケジューラ１３１によるスケジューリングとポーリングとが行われる。ここでもスレッド１２１ａに対応するエントリをＣＱから取得できない場合、スレッド１２１ｂが起床して後続の処理Ｂ３を実行する（タイミングＴ３７）。
【００８９】
処理Ｂ３の実行が終了すると、制御がスレッドスケジューラ１３１に移り（タイミングＴ３８）、スレッドスケジューラ１３１によるスケジューリングとポーリングとが行われる。ここで、スレッド１２１ａに対応するエントリをＣＱから取得できた場合、スレッドスケジューラ１３１は、スレッド１２１ａを起床させる（タイミングＴ３９）。スレッド１２１ａは、受信メッセージを取得して、後続の処理を再開する。
【００９０】
以上のように、スレッド１２１ａは、受信関数「ｒｅｃｖ」の発行後、ＣＱのポーリングを１回だけ実行し、対応するエントリを取得できなかった場合にはサスペンドする。このスレッドに対応するエントリを取得するためのポーリングは、それ以後、スレッドスケジューラ１３１によって実行される。そして、スレッドスケジューラ１３１によってスレッド１２１ａに対応するエントリがＣＱから取得された場合、スレッド１２１ａが起床する。
【００９１】
このような処理により、ポーリングに失敗したスレッド１２１ａが起床とサスペンドを何度も繰り返すことが防止される。このため、無駄なコンテキストスイッチの発生回数が少なくなり、ＣＰＵの処理負荷が低下する。その結果、ＣＰＵの処理効率が向上し、実行可能なスレッド１２１ｂの実行遅延を小さくすることができる。
【００９２】
図１２は、スレッドスケジューリングで使用されるデータ構造の例を示す図である。本実施の形態では、上記のようなスレッドスケジューリングを実現するための、コネクション構造体１５１および待ち合わせ構造体１５２が使用される。
【００９３】
コネクション構造体１５１は、スレッド間のコネクションが確立されるたびに、そのコネクションの両側のスレッドによってそれぞれ作成され、各スレッドが他方のスレッドとの通信を行うために使用される。コネクション構造体１５１は、自ノード側スレッド、他ノード側スレッドの各識別番号、ＸＩＤ、ＱＰ／ＣＱへのポインタ、および待ち合わせ構造体へのポインタを保持する。
【００９４】
自ノード側スレッドは、コネクションの両側のノードのうち、自ノードのスレッドを示し、他ノード側スレッドは、他ノードのスレッドを示す。ＸＩＤは、前述のように、スレッド間のコネクションごとに生成される固有の番号である。ＱＰ／ＣＱへのポインタは、通信相手のスレッドとの通信で用いられるＱＰ／ＣＱ１１１内のＱＰおよびＣＱの位置を示す。待ち合わせ構造体へのポインタは、対応する待ち合わせ構造体１５２の位置を示す。
【００９５】
待ち合わせ構造体１５２は、自ノード側のスレッドの状態を管理するために使用されるデータ構造体である。待ち合わせ構造体１５２は、Ｂｌｏｃｋｅｄキュー１５２ａとメッセージ情報キュー１５２ｂとを保持する。Ｂｌｏｃｋｅｄキュー１５２ａには、サスペンド状態のスレッドに対応するエントリが、Ｒｅａｄｙキュー１１５ａ〜１１５ｃから取り出されて格納される。メッセージ情報キュー１５２ｂには、受信メッセージを格納するためのバッファ領域を示すポインタを含むエントリが格納される。
【００９６】
図１３は、キュー間のエントリ移動によるサスペンドおよび起床動作について説明するための図である。受信関数「ｒｅｃｖ」を発行したスレッドは、ポーリングに失敗すると、対応するエントリをＲｅａｄｙキュー１１５ａ〜１１５ｃのいずれかから取り出し、待ち合わせ構造体１５２のＢｌｏｃｋｅｄキュー１５２ａに格納することで、サスペンド状態に遷移する。このとき、スレッドは、受信メッセージを格納するためのバッファ領域を示すポインタを含むエントリを、待ち合わせ構造体１５２のメッセージ情報キュー１５２ｂに登録する。このバッファ領域は、ＨＣＡドライバ１４０によって受信バッファに格納された受信メッセージを退避するためのメモリ領域である。
【００９７】
その後、スレッドスケジューラまたは他のスレッドによって、受信バッファに格納された受信メッセージがバッファ領域にセットされ、対応するエントリがＢｌｏｃｋｅｄキュー１５２ａから取り出され、Ｒｅａｄｙキュー１１５ａ〜１１５ｃのいずれかに登録される。これにより、このエントリに対応するスレッドが起床する。
【００９８】
なお、スレッドが起床している状態とは、対応するエントリがＲｅａｄｙキュー１１５１ａ〜１１５ｃのいずれかに登録されており、そのスレッドが、スレッドスケジューラが次に実行させるスレッドを選択する際の選択対象に含まれている状態を指す。そして、そのエントリがＲｅａｄｙキュー１１５ａ〜１１５ｃのいずれかからスレッドスケジューラに取り出されることで、そのエントリに対応するスレッドの実行が開始される。
【００９９】
以下、図１４、図１５を用いて、スレッドの状態遷移の具体例について説明する。図１４、図１５では、例として、ノード１００−１においてスレッド＃０とスレッド＃１が実行される場合について示す。
【０１００】
図１４は、スレッドの状態遷移についての第１の例を示す図である。図１４の初期状態では、スレッド＃０と、他のノードのスレッド（ここでは、ノード１００−２のスレッド＃０１とする）とのコネクションが確立されている。そして、このコネクションにＸＩＤ「０」が付与され、ＸＩＤ−Ｑｓｔｒ対応テーブル１１２において、ＸＩＤ「０」に対して待ち合わせ構造体Ｑｓｔｒ＃０が対応付けられている。また、スレッド＃１と、ノード１００−２の他のスレッド（スレッド＃１１とする）とのコネクションが確立されている。そして、このコネクションにＸＩＤ「１」が付与され、ＸＩＤ−Ｑｓｔｒ対応テーブル１１２において、ＸＩＤ「１」に対して待ち合わせ構造体Ｑｓｔｒ＃１が対応付けられている。
【０１０１】
さらに、スレッド＃０は、メッセージの受信を要求した後にサスペンド状態になっており、待ち合わせ構造体Ｑｓｔｒ＃０のＢｌｏｃｋｅｄキュー１５２ａには、スレッド＃０に対応するエントリが格納されている。また、待ち合わせ構造体Ｑｓｔｒ＃０のメッセージ情報キュー１５２ｂには、受信メッセージを格納するためのバッファ領域Ｂ０を示すポインタを含むエントリが登録されている。
【０１０２】
なお、ＩｎｆｉｎｉＢａｎｄでは、メッセージの送信順序や受信順序は入れ替わらないことが保証されている。
上記状態から、スレッドスケジューラ１３１が、Ｒｅａｄｙキュー１１５ａからスレッド＃１に対応するエントリを取得し、スレッド＃１の実行を開始させたとする（ステップＳ１１）。スレッド＃１は、受信関数「ｒｅｃｖ」をＨＣＡドライバ１４０に発行して、メッセージの受信を要求する（ステップＳ１２）。これにより、スレッド＃１からの受信要求に対応するエントリがＱＰ／ＣＱ１１１ａのＱＰに格納される。さらに、スレッド＃１は、ＱＰ／ＣＱ１１１ａのＣＱに対するポーリングを行う（ステップＳ１３）。
【０１０３】
スレッド＃１は、ＣＱからエントリＥ０を取得し、エントリＥ０が示す受信バッファＲ０から受信メッセージを取得する。ここで、仮に、取得した受信メッセージがＸＩＤ「１」を含んでいれば、スレッド＃１は、エントリが自分宛てであることを認識し、受信メッセージを用いて後続の処理を実行できる。
【０１０４】
しかし、図１４の例では、取得した受信メッセージがＸＩＤ「０」を含んでいたとする。この場合、スレッド＃０が受信を要求したメッセージがＨＣＡ１０７によって受信済みであり、その受信メッセージが受信バッファＲ０に格納されている。スレッド＃１は、取得したエントリが自分宛てではないことを認識して、ＸＩＤ−Ｑｓｔｒ対応テーブル１１２を参照し、ＸＩＤ「０」に対応する待ち合わせ構造体Ｑｓｔｒ＃０を特定する（ステップＳ１４）。
【０１０５】
スレッド＃１は、待ち合わせ構造体Ｑｓｔｒ＃０のメッセージ情報キュー１５２ｂからエントリを取得し、取得したエントリが示すバッファ領域Ｂ０に、受信バッファＲ０に格納されている受信メッセージを書き込む（ステップＳ１５）。さらに、スレッド＃１は、待ち合わせ構造体Ｑｓｔｒ＃０のＢｌｏｃｋｅｄキュー１５２ａからエントリを取り出して、このエントリをＲｅａｄｙキュー１１５ａに移動させる（ステップＳ１６）。これにより、スレッド＃０が起床する。すなわち、移動されたエントリがスレッドスケジューラ１３１に取得されてスレッド＃０の実行が開始されたとき、スレッド＃０は、バッファ領域Ｂ０に書き込まれた受信メッセージを用いて処理を続行できる。
【０１０６】
なお、バッファ領域Ｂ０は、受信バッファＲ０に格納された受信メッセージを退避するために用いられる。ステップＳ１３のポーリングが完了することにより、取得されたエントリＥ０が示す受信バッファＲ０は解放されてしまう。しかし、受信バッファＲ０に格納されていた受信メッセージがバッファ領域Ｂ０に退避されることで、スレッド＃０は、ポーリングの完了後にバッファ領域Ｂ０から受信メッセージを取得できるようになる。
【０１０７】
スレッド＃１は、以上の処理が完了すると、ステップＳ１１でＲｅａｄｙキュー１１５ａから取得されたエントリを、待ち合わせ構造体Ｑｓｔｒ＃１のＢｌｏｃｋｅｄキュー１５２ａに移動させる（ステップＳ１７）。さらに、スレッド＃１は、待ち合わせ構造体Ｑｓｔｒ＃１のメッセージ情報キュー１５２ｂに、受信メッセージを格納するためのバッファ領域Ｂ１を示すポインタを含むエントリを格納する。これにより、スレッド＃１はサスペンドする。
【０１０８】
図１５は、スレッドの状態遷移についての第２の例を示す図である。図１４に示したようにスレッド＃１がサスペンドした後に、スレッドスケジューラ１３１によるＱＰ／ＣＱ１１１ａのＣＱのポーリングによって、エントリＥ１が取得される。そして、取得されたエントリＥ１が示す受信バッファＲ１から、ＸＩＤ「１」を含む受信メッセージが取得されたとする（ステップＳ２１）。
【０１０９】
スレッドスケジューラ１３１は、ＸＩＤ−Ｑｓｔｒ対応テーブル１１２を参照し、ＸＩＤ「１」に対応する待ち合わせ構造体Ｑｓｔｒ＃１を特定する（ステップＳ２２）。スレッドスケジューラ１３１は、待ち合わせ構造体Ｑｓｔｒ＃１のメッセージ情報キュー１５２ｂからエントリを取得し、取得したエントリが示すバッファ領域Ｂ１に、受信バッファＲ１に格納されている受信メッセージを書き込む（ステップＳ２３）。さらに、スレッドスケジューラ１３１は、待ち合わせ構造体Ｑｓｔｒ＃１のＢｌｏｃｋｅｄキュー１５２ａからエントリを取り出して、このエントリをＲｅａｄｙキュー１１５ａに移動させる（ステップＳ２４）。
【０１１０】
これにより、スレッド＃１が起床する。すなわち、移動されたエントリがスレッドスケジューラ１３１に取得されてスレッド＃１の実行が開始されたとき、スレッド＃１は、バッファ領域Ｂ１に書き込まれた受信メッセージを用いて処理を続行できる。
【０１１１】
以上の図１４、図１５の例のように、本実施の形態では、ＣＱのポーリングに１回失敗したスレッドは、それ以上ポーリングを行わずにサスペンドする。その後、スレッドスケジューラまたは他のスレッドによるＣＱのポーリングにより、サスペンドしたスレッドに対応するエントリがＣＱから取得されることで、サスペンドしたスレッドが起床する。
【０１１２】
このような仕組みにより、ポーリングに失敗してサスペンドしたスレッドは、要求したメッセージが受信されるまで起床しない。そのため、ポーリングに失敗したスレッドがポーリングの再実行のために起床とサスペンドを何度も繰り返すことがなくなり、無駄なコンテキストスイッチの発生回数が減少する。その結果、ＣＰＵの処理効率を向上させることができる。
【０１１３】
また、上記の仕組みにより、ＣＱに格納されたあるスレッド宛てのエントリは、そのスレッドによるポーリングだけでなく、他のスレッドやスレッドスケジューラによるポーリングによっても取得される。そして、取得されたエントリに対応する受信メッセージを、宛先のスレッドが利用できるようになる。これにより、ポーリングを行ったときに、どのスレッド宛てのエントリも取得できないという確率が低くなる。その結果、無駄なポーリングの回数を減少させることができ、ＣＰＵやメモリなどのリソースの利用効率が向上する。
【０１１４】
＜フローチャート＞
次に、ノード１００の処理についてフローチャートを用いて説明する。
図１６は、スレッド間のコネクション確立を要求する処理手順の例を示すフローチャートである。ここでは例として、ノード１００−１のスレッド＃１１が、ノード１００−２のスレッド＃２１との間でコネクションを確立するケースについて示す。
【０１１５】
［ステップＳ５１］スレッド＃１１は、コネクションプール１１３から未使用のコネクション構造体１５１を取得する。このとき、未使用の待ち合わせ構造体１５２も取得される。スレッド＃１１は、取得したコネクション構造体１５１に対して、自ノード側スレッドとしてスレッド＃１１を登録し、他ノード側スレッドとしてスレッド＃２１を登録する。また、スレッド＃１１は、取得したコネクション構造体１５１に対して、ノード１００−２との通信に使用するＱＰ／ＣＱ１１１ａに対するポインタと、取得した待ち合わせ構造体１５２に対するポインタとを登録する。
【０１１６】
さらに、スレッド＃１１は、新たなＸＩＤを発行して、取得したコネクション構造体１５１に登録する。ＸＩＤは、ノード１００−１の番号と、直前に発行されたシーケンシャル番号に「１」を加算した値とを組み合わせることによって算出される。ここでは、説明を簡単にするためにＸＩＤ「１１」が発行されたとする。
【０１１７】
［ステップＳ５２］スレッド＃１１は、発行したＸＩＤ「１１」と、取得した待ち合わせ構造体１５２を示す情報とを含むレコードを、ＸＩＤ−Ｑｓｔｒ対応テーブル１１２に新たに登録する。
【０１１８】
［ステップＳ５３］スレッド＃１１は、コネクション確立依頼フラグと、通信相手のスレッド＃２１の種別を示すスレッド種別番号ｔｉｄと、ＸＩＤ「１１」とを、送信バッファにセットする。コネクション確立依頼フラグは、コネクションの確立要求であることを示す「１」にセットされる。
【０１１９】
［ステップＳ５４］スレッド＃１１は、ＨＣＡドライバ１４０に対して送信関数「ｓｅｎｄ」を発行する。このとき、スレッド＃１１は、引数として、コネクション構造体１５１へのポインタと、送信バッファのアドレスとをセットする。
【０１２０】
これにより、ＱＰ／ＣＱ１１１ａのＱＰに、コネクション確立のための送信要求を示すエントリが登録される。ＨＣＡドライバ１４０は、このエントリを取得すると、送信バッファにセットされた情報をノード１００−２に送信する。これにより、新たに発行されたＸＩＤ「１１」が相手のノード１００−２に伝達される。
【０１２１】
図１７は、メッセージの送信を要求する処理手順の例を示すフローチャートである。ここでは例として、図１６の処理によってスレッド＃２１とのコネクションが確立された後に、スレッド＃１１がスレッド＃２１に対してメッセージを送信するケースについて示す。
【０１２２】
［ステップＳ６１］スレッド＃１１は、自ノード側スレッドとしてスレッド＃１１が登録され、他ノード側スレッドとしてスレッド＃２１が登録されたコネクション構造体１５１を参照し、このコネクション構造体１５１からＸＩＤ「１１」を取得する。
【０１２３】
［ステップＳ６２］スレッド＃１１は、コネクション確立依頼フラグと、通信相手のスレッド＃２１の種別を示すスレッド種別番号ｔｉｄと、ＸＩＤ「１１」とが付加された送信メッセージを、送信バッファにセットする。コネクション確立依頼フラグは、コネクションの確立要求でないことを示す「０」にセットされる。
【０１２４】
［ステップＳ６３］スレッド＃１１は、ＨＣＡドライバ１４０に対して送信関数「ｓｅｎｄ」を発行する。このとき、スレッド＃１１は、引数として、コネクション構造体１５１へのポインタと、送信バッファのアドレスとをセットする。
【０１２５】
これにより、ＱＰ／ＣＱ１１１ａのＱＰに、メッセージの送信要求を示すエントリが登録される。ＨＣＡドライバ１４０は、このエントリを取得すると、送信バッファにセットされた送信メッセージをノード１００−２に送信する。これにより、送信メッセージとともにＸＩＤ「１１」が相手のノード１００−２に伝達される。
【０１２６】
図１８〜図２０は、メッセージの受信を要求する処理手順の例を示すフローチャートである。ここでは例として、ノード１００−２のスレッド＃２２が、ノード１００−１のスレッド＃１２から送信されるメッセージを受信するケースについて示す。なお、スレッド＃１２とスレッド＃２２との間のコネクションは確立済みであり、このコネクションに対してＸＩＤ「１２」が付与されているものとする。
【０１２７】
［ステップＳ７１］スレッド＃２２は、自ノード側スレッドとしてスレッド＃２２が登録され、他ノード側スレッドとしてスレッド＃１２が登録されたコネクション構造体１５１を参照し、このコネクション構造体１５１からＸＩＤ「１２」を取得する。
【０１２８】
［ステップＳ７２］スレッド＃２２は、ＨＣＡドライバ１４０に対して受信関数「ｒｅｃｖ」を発行する。このとき、スレッド＃２２は、引数として、ステップＳ７１で参照したコネクション構造体１５１へのポインタと、受信バッファのアドレスとをセットする。
【０１２９】
これにより、ＱＰ／ＣＱ１１１ａのＱＰに、メッセージの受信要求を示すエントリが登録される。ＨＣＡドライバ１４０は、このエントリを取得すると、ノード１００−２からメッセージを受信して受信バッファにセットする。そして、ＨＣＡドライバ１４０は、ＱＰ／ＣＱ１１１ａのＣＱに、受信完了を示すエントリを登録する。ただし、次のステップＳ７３の実行時点では、このエントリがＣＱに登録されているとは限らない。
【０１３０】
［ステップＳ７３］スレッド＃２２は、ＨＣＡドライバ１４０に対して、ノード１００−１との通信用のＣＱ、すなわち、ＱＰ／ＣＱ１１１ａのＣＱにポーリングするための関数を発行する。これにより、ＣＱのポーリングが行われる。
【０１３１】
［ステップＳ７４］スレッド＃２２は、ポーリングの結果として、受信完了を示すエントリをＣＱから取得できたかを判定する。スレッド＃２２は、該当エントリを取得できた場合、図１９のステップＳ８１の処理を実行し、取得できなかった場合、ステップＳ７５の処理を実行する。
【０１３２】
なお、ステップＳ７４で取得されるエントリは、ステップＳ７２による受信要求に対応する受信完了を示すとは限らない。
また、ステップＳ７４では、送信完了を示すエントリが取得される場合もある。この場合、スレッド＃２２は、送信要求を行ったスレッドを起床させた後、ステップＳ７５の処理を実行する。
【０１３３】
［ステップＳ７５］スレッド＃２２は、Ｒｅａｄｙキューからスレッドスケジューラによって取得された、スレッド＃２２に対応するエントリを、待ち合わせ構造体１５２のＢｌｏｃｋｅｄキュー１５２ａに移動させる。移動先の待ち合わせ構造体１５２は、ステップＳ７１で参照されたコネクション構造体１５１に登録されたポインタによって示される待ち合わせ構造体１５２である。
【０１３４】
また、スレッド＃２２は、この待ち合わせ構造体１５２のメッセージ情報キュー１５２ｂに、受信メッセージを格納するためのバッファ領域を示すポインタを含むエントリを格納する。以上のステップＳ７５の処理により、スレッド＃２２はサスペンド状態に遷移する。
【０１３５】
以下、図１９を用いて説明を続ける。
［ステップＳ８１］スレッド＃２２は、ＨＣＡドライバ１４０によって受信されたメッセージが格納されている受信バッファから、ステップＳ７４で取得されたエントリに対応する受信メッセージを取得する。スレッド＃２２は、受信メッセージから、コネクション確立依頼フラグと、スレッド種別番号ｔｉｄと、ＸＩＤとを取得する。
【０１３６】
［ステップＳ８２］スレッド＃２２は、コネクション確立依頼フラグが「１」の場合、ステップＳ８３の処理を実行し、「０」の場合、図２０のステップＳ９１の処理を実行する。
【０１３７】
［ステップＳ８３］コネクション確立依頼フラグが「１」の場合、スレッド間のコネクションを新たに確立することが要求されている。ここでは例として、図１６の処理によってスレッド＃１１とスレッド＃２１との間のコネクションの確立が要求されたものとして説明する。この場合、受信メッセージにはＸＩＤ「１１」が含まれている。
【０１３８】
スレッド＃２２は、まず、待ち合わせ構造体１５２を新たに作成する。
［ステップＳ８４］スレッド＃２２は、受信メッセージから取得したＸＩＤ「１１」と、ステップＳ８３で作成した待ち合わせ構造体１５２を示すポインタとを含むレコードを、ＸＩＤ−Ｑｓｔｒ対応テーブル１１２に対して新たに登録する。
【０１３９】
［ステップＳ８５］スレッド＃２２は、スレッド−関数対応テーブル１１４を参照し、受信メッセージから取得したスレッド種別番号ｔｉｄに対応付けられたスレッド＃２１を特定する。スレッド＃２２は、特定されたスレッド＃２１を起動する。この後、スレッド＃２２は、図１８のステップＳ７５の処理を実行して、サスペンド状態に遷移する。
【０１４０】
［ステップＳ８６］ステップＳ８５で起動したスレッド＃２１は、コネクションプール１１３から未使用のコネクション構造体１５１を取得する。スレッド＃２１は、取得したコネクション構造体１５１に対して、自ノード側スレッドとしてスレッド＃２１を登録し、他ノード側スレッドとしてスレッド＃１１を登録する。また、スレッド＃２１は、取得したコネクション構造体１５１に対して、ステップＳ８１で受信メッセージから取得したＸＩＤを登録する。さらに、スレッド＃２１は、ノード１００−１との通信に使用するＱＰ／ＣＱ１１１ａに対するポインタと、ステップＳ８３で作成された待ち合わせ構造体１５２に対するポインタとを登録する。これにより、スレッド＃１１とスレッド＃２１とのコネクションが確立される。
【０１４１】
なお、この後、起動したスレッド＃２１は、スレッドスケジューラの制御の下で後続の処理を実行する。
以下、図２０を用いて説明を続ける。
【０１４２】
［ステップＳ９１］図１９のステップＳ８２でコネクション確立依頼フラグが「０」の場合、ＣＱから取得されたエントリは受信完了を示すエントリである。スレッド＃２２は、受信メッセージから取得したＸＩＤが、図１８のステップＳ７１で取得したＸＩＤ「１２」と一致するかを判定する。ＸＩＤが一致した場合、ＣＱから取得されたエントリはスレッド＃２２宛てのエントリである。この場合、スレッド＃２２は、ステップＳ９２の処理を実行する。一方、ＸＩＤが一致しない場合、ＣＱから取得されたエントリはスレッド＃２２以外の他のスレッド宛てのエントリである。この場合、スレッド＃２２は、ステップＳ９３の処理を実行する。
【０１４３】
［ステップＳ９２］スレッド＃２２は、取得した受信メッセージを用いて後続の処理を実行する。
［ステップＳ９３］スレッド＃２２は、ＸＩＤ−Ｑｓｔｒ対応テーブル１１２を参照し、受信メッセージから取得したＸＩＤに対応する待ち合わせ構造体１５２を特定する。
【０１４４】
［ステップＳ９４］スレッド＃２２は、特定された待ち合わせ構造体１５２のメッセージ情報キュー１５２ｂからエントリを取得し、取得したエントリが示すバッファ領域に受信メッセージを書き込む。さらに、スレッド＃２２は、この待ち合わせ構造体１５２のＢｌｏｃｋｅｄキュー１５２ａからエントリを取り出して、このエントリをＲｅａｄｙキューに移動させる。ＣＱから取得されたエントリが、例えばスレッド＃２３宛てであったとすると、ステップＳ９４の処理により、スレッド＃２３が起床する。
【０１４５】
スレッド＃２２は、この後、図１８のステップＳ７５の処理を実行して、サスペンド状態に遷移する。
図２１、図２２は、スレッドスケジューラの処理手順の例を示すフローチャートである。ここでは例として、ノード１００−２のスレッドスケジューラ１３１の処理について示す。なお、図２１、図２２の処理は、繰り返し実行される。
【０１４６】
［ステップＳ１０１］スレッドスケジューラ１３１は、ノード１００−２のＣＱの中にポーリングしていないＣＱがあるかを判定する。スレッドスケジューラ１３１は、ポーリングしていないＣＱがある場合、ステップＳ１０２の処理を実行し、すべてのＣＱについてポーリング済みである場合、ステップＳ１０４の処理を実行する。
【０１４７】
［ステップＳ１０２］スレッドスケジューラ１３１は、ポーリングしていないＣＱに対してポーリングを行う。
［ステップＳ１０３］スレッドスケジューラ１３１は、ポーリングの結果として、受信完了を示すエントリをＣＱから取得できたかを判定する。スレッドスケジューラ１３１は、該当エントリを取得できた場合、図２２のステップＳ１１１の処理を実行し、取得できなかった場合、ステップＳ１０１の処理を実行する。
【０１４８】
［ステップＳ１０４］スレッドスケジューラ１３１は、Ｒｅａｄｙキュー１１５ａから先頭のエントリを取得し、そのエントリに対応するスレッドの実行を開始させる。
以下、図２２を用いて説明を続ける。
【０１４９】
［ステップＳ１１１］スレッドスケジューラ１３１は、ＨＣＡドライバ１４０によって受信されたメッセージが格納されている受信バッファから、図２１のステップＳ１０３で取得されたエントリに対応する受信メッセージを取得する。スレッドスケジューラ１３１は、受信メッセージから、コネクション確立依頼フラグと、スレッド種別番号ｔｉｄと、ＸＩＤとを取得する。
【０１５０】
［ステップＳ１１２］スレッドスケジューラ１３１は、コネクション確立依頼フラグが「１」の場合、ステップＳ１１３の処理を実行し、「０」の場合、ステップＳ１１６の処理を実行する。
【０１５１】
［ステップＳ１１３］コネクション確立依頼フラグが「１」の場合、スレッド間のコネクションを新たに確立することが要求されている。ここでは例として、図１６の処理によってスレッド＃１１とスレッド＃２１との間のコネクションの確立が要求されたものとして説明する。この場合、受信メッセージにはＸＩＤ「１１」が含まれている。
【０１５２】
スレッドスケジューラ１３１は、まず、待ち合わせ構造体１５２を新たに作成する。
［ステップＳ１１４］スレッドスケジューラ１３１は、受信メッセージから取得したＸＩＤ「１１」と、ステップＳ１１３で作成した待ち合わせ構造体１５２を示すポインタとを含むレコードを、ＸＩＤ−Ｑｓｔｒ対応テーブル１１２に対して新たに登録する。
【０１５３】
［ステップＳ１１５］スレッドスケジューラ１３１は、スレッド−関数対応テーブル１１４を参照し、受信メッセージから取得したスレッド種別番号ｔｉｄに対応付けられたスレッド＃２１を特定する。スレッドスケジューラ１３１は、特定されたスレッド＃２１を起動する。この後、スレッドスケジューラ１３１は、図２１のステップＳ１０１の処理を実行する。
【０１５４】
［ステップＳ１１６］スレッドスケジューラ１３１は、ＸＩＤ−Ｑｓｔｒ対応テーブル１１２を参照し、受信メッセージから取得したＸＩＤに対応する待ち合わせ構造体１５２を特定する。
【０１５５】
［ステップＳ１１７］スレッドスケジューラ１３１は、特定された待ち合わせ構造体１５２のメッセージ情報キュー１５２ｂからエントリを取得し、取得したエントリが示すバッファ領域に受信メッセージを書き込む。さらに、スレッドスケジューラ１３１は、この待ち合わせ構造体１５２のＢｌｏｃｋｅｄキュー１５２ａからエントリを取り出して、このエントリをＲｅａｄｙキューに移動させる。ＣＱから取得されたエントリが、例えばスレッド＃２３宛てであったとすると、ステップＳ１１７の処理により、スレッド＃２３が起床する。
【０１５６】
この後、スレッドスケジューラ１３１は、図２１のステップＳ１０１の処理を実行する。
＜スレッドの具体例＞
次に、スレッドの具体的な処理例について説明する。
【０１５７】
図２３は、スレッドの処理例を示す図である。図２３の例では、ノード１００−１のスレッド＃１５と、ノード１００−２のスレッド＃２５との間でコネクションが確立されているものとする。スレッド＃１５は、ホスト装置からの書き込み要求を受け付けるスレッドであり、スレッド＃２５は、書き込みデータの格納を担当する「担当ノード」において、他のノードから転送された書き込みデータを受け付けるスレッドである。
【０１５８】
［ステップＳ１２１］スレッド＃１５は、ホスト装置から、書き込み要求および書き込みデータを受信する。
［ステップＳ１２２］スレッド＃１５は、書き込みアドレスを解析して、ノード１００−２を担当ノードと判別する。
【０１５９】
［ステップＳ１２３］スレッド＃１５は、担当ノードであるノード１００−２に対して書き込みデータを送信する。
［ステップＳ１２４］スレッド＃２５は、書き込みデータを受信する。
【０１６０】
［ステップＳ１２５］スレッド＃２５は、受信した書き込みデータをキャッシュに書き込む。
［ステップＳ１２６］スレッド＃２５は、書き込みの完了通知をノード１００−１に送信する。
【０１６１】
［ステップＳ１２７］スレッド＃１５は、完了通知を受信し、ホスト装置に対して書き込みが完了したことを通知する。
［ステップＳ１２８］スレッド＃１５は、次の書き込みデータの受信待ち状態になる。
【０１６２】
以上の処理において、スレッド＃２５は、例えば、ステップＳ１２４で書き込みデータを受信するために受信関数「ｒｅｃｖ」を発行し、続いてＣＱをポーリングする。スレッド＃２５は、ポーリングにより自分宛てのエントリを取得できなかった場合、サスペンドして受信待ち状態となる。その後、スレッド＃１５とスレッド＃２５とのコネクションに対応するＸＩＤが付加された書き込みデータが受信されると、ノード１００−２上の他のスレッドまたはスレッドスケジューラによるポーリングによって、ＣＱからスレッド＃２５宛てのエントリが取得される。すると、スレッド＃２５は起床し、受信された書き込みデータを取得して、ステップＳ１２５からの後続処理の実行を開始する。
【０１６３】
このような処理により、スレッド＃２５は、ポーリングによる書き込みデータの取得に失敗するとサスペンドし、書き込みデータの受信が完了するまで起床しない。このため、スレッド＃２５のサスペンドおよび起床の回数が低減されて、コンテキストスイッチの発生が抑制され、その結果、ノード１００−２のＣＰＵの利用効率が向上される。
【０１６４】
一方、スレッド＃１５は、例えば、ステップＳ１２３の書き込みデータ送信が完了した後、ステップＳ１２７で完了通知を受信するために受信関数「ｒｅｃｖ」を発行し、続いてＣＱをポーリングする。スレッド＃１５は、ポーリングにより自分宛てのエントリを取得できなかった場合、サスペンドして受信待ち状態となる。その後、スレッド＃１５とスレッド＃２５とのコネクションに対応するＸＩＤが付加された完了通知が受信されると、ノード１００−１上の他のスレッドまたはスレッドスケジューラによるポーリングによって、ＣＱからスレッド＃１５宛てのエントリが取得される。すると、スレッド＃１５は起床し、受信された完了通知を取得して、ステップＳ１２８からの後続処理の実行を開始する。
【０１６５】
このような処理により、スレッド＃１５は、ポーリングによる完了通知の取得に失敗するとサスペンドし、完了通知の受信が完了するまで起床しない。このため、スレッド＃１５のサスペンドおよび起床の回数が低減されて、コンテキストスイッチの発生が抑制され、その結果、ノード１００−１のＣＰＵの利用効率が向上される。
【０１６６】
なお、上記の各実施の形態に示した装置（例えば、情報処理装置１，２、ノード１００，１００−１〜１００−４）の処理機能は、コンピュータによって実現することができる。その場合、各装置が有すべき機能の処理内容を記述したプログラムが提供され、そのプログラムをコンピュータで実行することにより、上記処理機能がコンピュータ上で実現される。処理内容を記述したプログラムは、コンピュータで読み取り可能な記録媒体に記録しておくことができる。コンピュータで読み取り可能な記録媒体としては、磁気記憶装置、光ディスク、光磁気記録媒体、半導体メモリなどがある。磁気記憶装置には、ハードディスク装置（ＨＤＤ）、フレキシブルディスク（ＦＤ）、磁気テープなどがある。光ディスクには、ＤＶＤ（Digital Versatile Disc）、ＤＶＤ−ＲＡＭ、ＣＤ−ＲＯＭ（Compact Disc-Read Only Memory）、ＣＤ−Ｒ（Recordable）／ＲＷ（ReWritable）などがある。光磁気記録媒体には、ＭＯ（Magneto-Optical disk）などがある。
【０１６７】
プログラムを流通させる場合には、例えば、そのプログラムが記録されたＤＶＤ、ＣＤ−ＲＯＭなどの可搬型記録媒体が販売される。また、プログラムをサーバコンピュータの記憶装置に格納しておき、ネットワークを介して、サーバコンピュータから他のコンピュータにそのプログラムを転送することもできる。
【０１６８】
プログラムを実行するコンピュータは、例えば、可搬型記録媒体に記録されたプログラムまたはサーバコンピュータから転送されたプログラムを、自己の記憶装置に格納する。そして、コンピュータは、自己の記憶装置からプログラムを読み取り、プログラムにしたがった処理を実行する。なお、コンピュータは、可搬型記録媒体から直接プログラムを読み取り、そのプログラムにしたがった処理を実行することもできる。また、コンピュータは、ネットワークを介して接続されたサーバコンピュータからプログラムが転送されるごとに、逐次、受け取ったプログラムにしたがった処理を実行することもできる。
【符号の説明】
【０１６９】
１，２  情報処理装置
２ａ  記憶部
２ｂ  制御部
１０  データ
１１〜１３，２１〜２３  スレッド
２４  対応情報
２５  キュー
ＣＮ１〜ＣＮ３  コネクション
Ｓ１〜Ｓ３  ステップ
【図１】
2018182628.tif 000003
【図２】
2018182628.tif 000004
【図３】
2018182628.tif 000005
【図４】
2018182628.tif 000006
【図５】
2018182628.tif 000007
【図６】
2018182628.tif 000008
【図７】
2018182628.tif 000009
【図８】
2018182628.tif 000010
【図９】
2018182628.tif 000011
【図１０】
2018182628.tif 000012
【図１１】
2018182628.tif 000013
【図１２】
2018182628.tif 000014
【図１３】
2018182628.tif 000015
【図１４】
2018182628.tif 000016
【図１５】
2018182628.tif 000017
【図１６】
2018182628.tif 000018
【図１７】
2018182628.tif 000019
【図１８】
2018182628.tif 000020
【図１９】
2018182628.tif 000021
【図２０】
2018182628.tif 000022
【図２１】
2018182628.tif 000023
【図２２】
2018182628.tif 000024
【図２３】
2018182628.tif 000025
【手続補正書】
【提出日】平成30年7月10日(2018.7.10)
【手続補正１】
【補正対象書類名】明細書
【補正対象項目名】００１０
【補正方法】変更
【補正の内容】
【００１０】
１つの案では、記憶部と制御部とを有する次のような情報処理装置が提供される。記憶部は、情報処理装置で実行される複数のスレッドと、他の情報処理装置で実行される複数のスレッドとの間でコネクションが確立されたスレッドの組み合わせごとに別々に規定される識別子と、組み合わせとの対応関係が登録された対応情報を記憶する。制御部は、他の情報処理装置から、識別子のいずれかに対応する情報が付加されたデータを受信し、受信が完了したことを示す完了通知を、組み合わせごとに確立されるコネクションにおける各々の完了通知の登録のために複数のスレッドで共用されるキューに登録する受信処理を実行する。また、制御部は、キューに登録される１以上の完了通知の周期的な確認において、受信したデータに対応する完了通知が確認されてキューから受信したデータに対応する完了通知が取り出された場合に、情報処理装置で実行されるスレッドのうち、受信したデータに付加された情報に基づき対応関係から特定される組み合わせに含まれるスレッドに、受信したデータを受け渡す受信完了処理を実行する。
【手続補正２】
【補正対象書類名】特許請求の範囲
【補正対象項目名】全文
【補正方法】変更
【補正の内容】
【特許請求の範囲】
【請求項１】
情報処理装置において、
前記情報処理装置で実行される複数のスレッドと、他の情報処理装置で実行される複数のスレッドとの間でコネクションが確立されたスレッドの組み合わせごとに別々に規定される識別子と、前記組み合わせとの対応関係が登録された対応情報を記憶する記憶部と、
前記他の情報処理装置から、前記識別子のいずれかに対応する情報が付加されたデータを受信し、受信が完了したことを示す完了通知を、前記組み合わせごとに確立される前記コネクションにおける各々の完了通知の登録のために前記複数のスレッドで共用されるキューに登録する受信処理と、
前記キューに登録される１以上の完了通知の周期的な確認において、前記受信したデータに対応する完了通知が確認されて前記キューから前記受信したデータに対応する完了通知が取り出された場合に、前記情報処理装置で実行されるスレッドのうち、前記受信したデータに付加された前記情報に基づき前記対応関係から特定される前記組み合わせに含まれるスレッドに、前記受信したデータを受け渡す受信完了処理と、
を実行する制御部と、
を有する情報処理装置。
【請求項２】
前記受信完了処理は、
前記情報処理装置で実行されるスレッドのうち第１のスレッドによって、前記他の情報処理装置で実行されるスレッドのうち第２のスレッドを送信元とするデータの受信が要求された後、前記キューから完了通知を取り出し、当該完了通知に対応する、前記他の情報処理装置から受信した第１の受信データを特定し、前記第１の受信データに付加された、前記識別子のいずれかに対応する付加情報が、前記第１のスレッドと前記第２のスレッドとの組み合わせに対応する前記識別子と一致しない場合には、前記第１のスレッドを待機状態に遷移させる第１の受信要求処理と、
前記情報処理装置で実行されるスレッドのうち第３のスレッドによって、前記他の情報処理装置で実行されるスレッドのうち第４のスレッドを送信元とするデータの受信が要求された後、前記キューから完了通知を取り出し、当該完了通知に対応する、前記他の情報処理装置から受信した第２の受信データを特定し、前記第２の受信データに付加された、前記識別子のいずれかに対応する付加情報が、前記第１のスレッドと前記第２のスレッドとの組み合わせに対応する前記識別子と一致する場合には、前記第１のスレッドに前記第２の受信データを受け渡して前記第１のスレッドの実行を再開させる第２の受信要求処理と、
を含む請求項１記載の情報処理装置。
【請求項３】
前記受信完了処理は、
前記情報処理装置で実行されるスレッドのうち第１のスレッドによって、前記他の情報処理装置で実行されるスレッドのうち第２のスレッドを送信元とするデータの受信が要求された後、前記キューから完了通知を取り出し、当該完了通知に対応する、前記他の情報処理装置から受信した第１の受信データを特定し、前記第１の受信データに付加された、前記識別子のいずれかに対応する付加情報が、前記第１のスレッドと前記第２のスレッドとの組み合わせに対応する前記識別子と一致しない場合には、前記第１のスレッドを待機状態に遷移させる受信要求処理と、
前記情報処理装置で実行されるスレッドの実行順を制御するとともに、前記キューから完了通知を周期的に取り出すスケジューリング処理と、
を含み、
前記スケジューリング処理によって前記キューから取り出された完了通知に対応する、前記他の情報処理装置から受信した第２の受信データに付加された、前記識別子のいずれかに対応する付加情報が、前記第１のスレッドと前記第２のスレッドとの組み合わせに対応する前記識別子と一致する場合には、前記第１のスレッドに前記第２の受信データを受け渡して前記第１のスレッドの実行を再開させる、
請求項１記載の情報処理装置。
【請求項４】
前記識別子は、前記コネクションが確立された前記情報処理装置または前記他の情報処理装置を示す識別番号と、シーケンシャルに生成される番号とを組み合わせることで生成される情報を含む、
請求項１乃至３のいずれか１項に記載の情報処理装置。
【請求項５】
前記他の情報処理装置が複数接続されている場合、前記他の情報処理装置のそれぞれに対応する前記キューが使用され、
前記識別子は、前記情報処理装置で実行されるスレッドのうち第５のスレッドと、前記他の情報処理装置で実行されるスレッドのうち第６のスレッドとの間の前記コネクションが確立されたとき、前記第５のスレッドが実行される前記情報処理装置または前記第６のスレッドが実行される前記他の情報処理装置のいずれかを示す識別番号と、シーケンシャルに生成される番号とを組み合わせることで生成される情報を含む、
請求項１乃至３のいずれか１項に記載の情報処理装置。
【請求項６】
コンピュータが、
他のコンピュータから、前記コンピュータで実行される複数のスレッドと、前記他のコンピュータで実行される複数のスレッドとの間でコネクションが確立されたスレッドの組み合わせごとに別々に規定される識別子のいずれかに対応する情報が付加されたデータを受信し、受信が完了したことを示す完了通知を、前記組み合わせごとに確立される前記コネクションにおける各々の完了通知の登録のために前記複数のスレッドで共用されるキューに登録する受信処理と、
前記キューに登録される１以上の完了通知の周期的な確認において、前記データに対応する完了通知が確認されて前記キューから前記データに対応する完了通知が取り出された場合に、前記識別子と前記組み合わせとの対応関係が登録された対応情報を参照し、前記コンピュータで実行されるスレッドのうち、前記データに付加された前記情報に基づき前記対応関係から特定される前記組み合わせに含まれるスレッドに、前記データを受け渡す受信完了処理と、
を実行する情報処理方法。
【請求項７】
コンピュータに、
他のコンピュータから、前記コンピュータで実行される複数のスレッドと、前記他のコンピュータで実行される複数のスレッドとの間でコネクションが確立されたスレッドの組み合わせごとに別々に規定される識別子のいずれかに対応する情報が付加されたデータを受信し、受信が完了したことを示す完了通知を、前記組み合わせごとに確立される前記コネクションにおける各々の完了通知の登録のために前記複数のスレッドで共用されるキューに登録する受信処理と、
前記キューに登録される１以上の完了通知の周期的な確認において、前記データに対応する完了通知が確認されて前記キューから前記データに対応する完了通知が取り出された場合に、前記識別子と前記組み合わせとの対応関係が登録された対応情報を参照し、前記コンピュータで実行されるスレッドのうち、前記データに付加された前記情報に基づき前記対応関係から特定される前記組み合わせに含まれるスレッドに、前記データを受け渡す受信完了処理と、
を含む処理を実行させる情報処理プログラム。
【手続補正書】
【提出日】平成30年8月16日(2018.8.16)
【手続補正１】
【補正対象書類名】明細書
【補正対象項目名】００１０
【補正方法】変更
【補正の内容】
【００１０】
１つの案では、記憶部と制御部とを有する次のような情報処理装置が提供される。記憶部は、情報処理装置で実行される複数のスレッドと、他の情報処理装置で実行される複数のスレッドとの間でコネクションが確立されたスレッドの組み合わせごとに別々に規定される識別子と、組み合わせとの対応関係が登録された対応情報を記憶する。制御部は、他の情報処理装置から、識別子のいずれかに対応する情報が付加されたデータを受信し、受信が完了したことを示す完了通知を、組み合わせごとに確立されるコネクションにおける各々の完了通知の登録のために、情報処理装置で実行される複数のスレッドで共用されるキューに登録する受信処理を実行する。また、制御部は、キューに登録される１以上の完了通知の周期的な確認において、受信したデータに対応する完了通知が確認されてキューから受信したデータに対応する完了通知が取り出された場合に、情報処理装置で実行されるスレッドのうち、受信したデータに付加された情報に基づき対応関係から特定される組み合わせに含まれるスレッドに、受信したデータを受け渡す受信完了処理を実行する。
【手続補正２】
【補正対象書類名】特許請求の範囲
【補正対象項目名】請求項１
【補正方法】変更
【補正の内容】
【請求項１】
情報処理装置において、
前記情報処理装置で実行される複数のスレッドと、他の情報処理装置で実行される複数のスレッドとの間でコネクションが確立されたスレッドの組み合わせごとに別々に規定される識別子と、前記組み合わせとの対応関係が登録された対応情報を記憶する記憶部と、
前記他の情報処理装置から、前記識別子のいずれかに対応する情報が付加されたデータを受信し、受信が完了したことを示す完了通知を、前記組み合わせごとに確立される前記コネクションにおける各々の完了通知の登録のために、前記情報処理装置で実行される複数のスレッドで共用されるキューに登録する受信処理と、
前記キューに登録される１以上の完了通知の周期的な確認において、前記受信したデータに対応する完了通知が確認されて前記キューから前記受信したデータに対応する完了通知が取り出された場合に、前記情報処理装置で実行されるスレッドのうち、前記受信したデータに付加された前記情報に基づき前記対応関係から特定される前記組み合わせに含まれるスレッドに、前記受信したデータを受け渡す受信完了処理と、
を実行する制御部と、
を有する情報処理装置。
【手続補正３】
【補正対象書類名】特許請求の範囲
【補正対象項目名】請求項６
【補正方法】変更
【補正の内容】
【請求項６】
コンピュータが、
他のコンピュータから、前記コンピュータで実行される複数のスレッドと、前記他のコンピュータで実行される複数のスレッドとの間でコネクションが確立されたスレッドの組み合わせごとに別々に規定される識別子のいずれかに対応する情報が付加されたデータを受信し、受信が完了したことを示す完了通知を、前記組み合わせごとに確立される前記コネクションにおける各々の完了通知の登録のために、前記コンピュータで実行される複数のスレッドで共用されるキューに登録する受信処理と、
前記キューに登録される１以上の完了通知の周期的な確認において、前記データに対応する完了通知が確認されて前記キューから前記データに対応する完了通知が取り出された場合に、前記識別子と前記組み合わせとの対応関係が登録された対応情報を参照し、前記コンピュータで実行されるスレッドのうち、前記データに付加された前記情報に基づき前記対応関係から特定される前記組み合わせに含まれるスレッドに、前記データを受け渡す受信完了処理と、
を実行する情報処理方法。
【手続補正４】
【補正対象書類名】特許請求の範囲
【補正対象項目名】請求項７
【補正方法】変更
【補正の内容】
【請求項７】
コンピュータに、
他のコンピュータから、前記コンピュータで実行される複数のスレッドと、前記他のコンピュータで実行される複数のスレッドとの間でコネクションが確立されたスレッドの組み合わせごとに別々に規定される識別子のいずれかに対応する情報が付加されたデータを受信し、受信が完了したことを示す完了通知を、前記組み合わせごとに確立される前記コネクションにおける各々の完了通知の登録のために、前記コンピュータで実行される複数のスレッドで共用されるキューに登録する受信処理と、
前記キューに登録される１以上の完了通知の周期的な確認において、前記データに対応する完了通知が確認されて前記キューから前記データに対応する完了通知が取り出された場合に、前記識別子と前記組み合わせとの対応関係が登録された対応情報を参照し、前記コンピュータで実行されるスレッドのうち、前記データに付加された前記情報に基づき前記対応関係から特定される前記組み合わせに含まれるスレッドに、前記データを受け渡す受信完了処理と、
を含む処理を実行させる情報処理プログラム。