(57)【要約】【解決手段】ワーキングセットおよびスレッドの関連付けが開示されている。ストールイベントの示唆が受信される。ストールイベントの示唆を受信したことに応答して、ストールイベントに関連するプロセッサの状態が保存される。プロセッサ内で動作するゲストスレッドの識別子およびプロセッサによって参照されたゲスト物理アドレスの内の少なくとも一方が、保存されたプロセッサ状態から取得される。【選択図】図１３Ｅ
2019528539.tif 000002
【特許請求の範囲】
【請求項１】
コンピュータシステムであって、
複数の物理ノードを備え、各ノードは複数のプロセッサを備え、
ストールイベントの示唆を受信したことに応答して、前記ストールイベントに関連付けられているプロセッサの状態が保存され、
前記プロセッサで実行中のゲストスレッドの識別子および前記プロセッサによって参照されたゲスト物理アドレスの内の少なくとも一方が、前記ストールイベントの前記示唆を受信したことに応答して保存された前記プロセッサ状態から取得される、コンピュータシステム。
【請求項２】
請求項１に記載のコンピュータシステムであって、前記プロセッサで実行中の前記ゲストスレッドの前記識別子は、前記保存されたプロセッサ状態の中のＦＳ−Ｂａｓｅ０レジスタから取得される、コンピュータシステム。
【請求項３】
請求項１に記載のコンピュータシステムであって、前記ゲスト物理アドレスは前記保存されたプロセッサ状態の中のＣＲ３レジスタから取得される、コンピュータシステム。
【請求項４】
請求項１に記載のコンピュータシステムであって、前記ストールイベントは非ローカルページのアクセスに関連付けられている、コンピュータシステム。
【請求項５】
請求項１に記載のコンピュータシステムであって、前記ストールイベントはスレッドコンテキスト切り替えに関連付けられている、コンピュータシステム。
【請求項６】
請求項１に記載のコンピュータシステムであって、前記識別されたゲストスレッドによる前記識別されたゲスト物理アドレスへのアクセスは、前記識別されたゲストスレッドによってページアクセス履歴に記録される、コンピュータシステム。
【請求項７】
請求項６に記載のコンピュータシステムであって、前記識別されたゲストスレッドによるページアクセスの前記記録された履歴は、ブルームフィルタに格納される、コンピュータシステム。
【請求項８】
請求項６に記載のコンピュータシステムであって、前記識別されたゲストスレッドの温かさの程度が、前記記録された履歴に少なくとも部分的に基づいて決定され、前記温かさの程度は前記記録された履歴内でノードにローカルなページの数を示す、コンピュータシステム。
【請求項９】
請求項６に記載のコンピュータシステムであって、前記識別されたゲストスレッドの利用の程度が、前記記録された履歴に少なくとも部分的に基づいて決定され、前記利用の程度は２つの期間の間での前記識別されたゲストスレッドのページアクセス動作の重複の量を示す、コンピュータシステム。
【請求項１０】
請求項１に記載のコンピュータシステムであって、前記複数の物理ノードの内のノード上で実行する時の前記特定されたゲストスレッドの効率の程度が決定される、コンピュータシステム。
【請求項１１】
方法であって、
ストールイベントの示唆を受信し、
前記ストールイベントの前記示唆を受信したことに応答して、前記ストールイベントに関連するプロセッサの状態を保存し、前記プロセッサは、複数の物理ノードの内の１つのノードに備えられており、
前記ストールイベントの前記示唆を受信したことに応答して保存された前記プロセッサ状態から、前記プロセッサで実行中のゲストスレッドの識別子および前記プロセッサによって参照されるゲスト物理アドレスの内の少なくともいずれか一方を取得すること、
を備える、方法。
【請求項１２】
請求項１１に記載の方法であって、前記プロセッサで実行中の前記ゲストスレッドの前記識別子は、前記保存されたプロセッサ状態の中のＦＳ−Ｂａｓｅ０レジスタから取得される、方法。
【請求項１３】
請求項１１に記載の方法であって、前記ゲスト物理アドレスは、前記保存されたプロセッサ状態の中のＣＲ３レジスタから取得される、方法。
【請求項１４】
請求項１１に記載の方法であって、前記ストールイベントは、非ローカルページのアクセスに関連付けられている、方法。
【請求項１５】
請求項１１に記載の方法であって、前記ストールイベントは、スレッドコンテキスト切り替えに関連付けられている、方法。
【請求項１６】
請求項１１に記載の方法であって、さらに、前記識別されたゲストスレッドによる前記識別されたゲスト物理アドレスへのアクセスを、前記識別されたゲストスレッドによってページアクセス履歴に記録することを備える、方法。
【請求項１７】
請求項１６に記載の方法であって、前記識別されたゲストスレッドによるページアクセスの前記記録された履歴は、ブルームフィルタに格納される、方法。
【請求項１８】
請求項１６に記載の方法であって、前記記録された履歴に少なくとも部分的に基づいて、前記識別されたゲストスレッドの温かさの程度を決定することを更に備え、前記温かさの程度は、前記記録された履歴内でノードにローカルなページの数を示す、方法。
【請求項１９】
請求項１６に記載の方法であって、前記記録された履歴に少なくとも部分的に基づいて、前記識別されたゲストスレッドの利用の程度を決定することを更に備え、前記利用の程度は、２つの期間の間での前記識別されたゲストスレッドのページアクセス動作の重複の量を示す、方法。
【請求項２０】
請求項１１に記載の方法であって、さらに、前記ノード上で実行する時の前記特定されたゲストスレッドの効率の程度を決定することを備える、方法。
【請求項２１】
コンピュータシステムであって、
複数の物理ノードを備え、各ノードは複数のプロセッサを備え、
前記プロセッサの各々は、複数のハイパースレッドを備え、
イベントが発生した旨の示唆を受信したことに応答して、前記イベントを待機中の仮想プロセッサを配置するためのキューの検索がキューのセットにおいて実行され、前記キューのセットの中のキューは、前記複数の物理ノードの中の物理ノード内のハイパースレッドに対応し、前記キューのセットの中の前記キューは、所定のトラバース順序に従って訪問される、コンピュータシステム。
【請求項２２】
請求項２１に記載のコンピュータシステムであって、前記仮想プロセッサは、前記物理ノード内のハイパースレッドに対応する前記キューのセットの中のキューに配置される、コンピュータシステム。
【請求項２３】
請求項２１に記載のコンピュータシステムであって、前記物理ノード内の前記ハイパースレッドに対応する前記キューのセットの中の前記キューが満杯である場合に、前記検索の前にキューされた仮想プロセッサが前記キューのセットからエビクトされる、コンピュータシステム。
【請求項２４】
請求項２３に記載のコンピュータシステムであって、前記エビクトされた仮想プロセッサは、仮想プロセッサのグローバルアクセス可能なキューに配置される、コンピュータシステム。
【請求項２５】
請求項２３に記載のコンピュータシステムであって、前記エビクトされた仮想プロセッサは、前記キューのセットの中の前記キュー上で最もパフォーマンスの低い仮想プロセッサを含む、コンピュータシステム。
【請求項２６】
請求項２３に記載のコンピュータシステムであって、前記エビクトされる仮想プロセッサは、前記エビクトされる仮想プロセッサで実行中のゲストスレッドに関連付けられている効率の程度に少なくとも部分的に基づいてエビクトされる、コンピュータシステム。
【請求項２７】
請求項２３に記載のコンピュータシステムであって、前記仮想プロセッサは、前記エビクトされた仮想プロセッサがエビクトされたキューに配置される、コンピュータシステム。
【請求項２８】
請求項２１に記載のコンピュータシステムであって、前記物理ノード内の前記ハイパースレッドに対応する前記キューのセットの中の前記キューが満杯である場合に、前記仮想プロセッサは仮想プロセッサのグローバルアクセス可能なキューに配置される、コンピュータシステム。
【請求項２９】
請求項２１に記載のコンピュータシステムであって、前記所定のトラバース順序はツリーウォークを模倣する、コンピュータシステム。
【請求項３０】
請求項２１に記載のコンピュータシステムであって、前記検索は前記仮想プロセッサが最後に動作していたハーパースレッドに対応するキューから始まる、コンピュータシステム。
【請求項３１】
方法であって、
イベントが発生した旨の示唆を受信し、
前記イベントが発生した旨の前記示唆を受信したことに応答して、前記イベントを待機中の仮想プロセッサを配置するキューをキューのセット内で検索すること、
を備え、
前記キューのセットの中のキューは複数の物理ノードに含まれる物理ノード内のハイパースレッドに対応し、前記キューのセットの中の前記キューは所定のトラバース順序に従って訪問される、方法。
【請求項３２】
請求項３１に記載の方法であって、前記仮想プロセッサは、前記物理ノード内のハイパースレッドに対応する前記キューのセットの中のキューに配置される、方法。
【請求項３３】
請求項３１に記載の方法であって、前記物理ノード内の前記ハイパースレッドに対応する前記キューのセットの中の前記キューが満杯である場合に、前記検索の前にキューされた仮想プロセッサが、前記キューのセットからエビクトされる、方法。
【請求項３４】
請求項３３に記載の方法であって、前記エビクトされた仮想プロセッサは、仮想プロセッサのグローバルアクセス可能なキューに配置される、方法。
【請求項３５】
請求項３３に記載の方法であって、前記エビクトされた仮想プロセッサは、前記キューのセットの中の前記キュー上で最もパフォーマンスの低い仮想プロセッサを含む、方法。
【請求項３６】
請求項３３に記載の方法であって、前記エビクトされる仮想プロセッサは、前記エビクトされる仮想プロセッサで実行中のゲストスレッドに関連付けられている効率の程度に少なくとも部分的に基づいてエビクトされる、方法。
【請求項３７】
請求項３３に記載の方法であって、前記仮想プロセッサは、前記エビクトされた仮想プロセッサがエビクトされたキューに配置される、方法。
【請求項３８】
請求項３１に記載の方法であって、前記物理ノード内の前記ハイパースレッドに対応する前記キューのセットの中の前記キューが満杯である場合に、前記仮想プロセッサは、仮想プロセッサのグローバルアクセス可能なキューに配置される、方法。
【請求項３９】
請求項３１に記載の方法であって、前記所定のトラバース順序は、ツリーウォークを模倣する、方法。
【請求項４０】
請求項３１に記載の方法であって、前記検索は、前記仮想プロセッサが最後に動作していたハーパースレッドに対応するキューから始まる、方法。
【請求項４１】
コンピュータシステムであって、
複数の物理ノードを備え、オペレーティングシステムが前記複数の物理ノードにわたって集合的に実行され、
前記複数の物理ノードの内のリモート物理ノードからリソースの要求が受信され、
前記要求は、前記リモート物理ノード上で実行中のゲストスレッドに関する情報を含み、
前記要求されたリソースを送信するかまたは前記要求を拒否するかが、前記要求に含まれる前記情報の少なくとも一部に少なくとも部分的に基づいて決定され、
前記決定に少なくとも部分的に基づいて、応答が提供される、コンピュータシステム。
【請求項４２】
請求項４１に記載のコンピュータシステムであって、前記決定は、前記複数の物理ノードの内で前記要求を受信したノードにローカルな前記要求されたリソースに関する情報に少なくとも部分的に基づく、コンピュータシステム。
【請求項４３】
請求項４２に記載のコンピュータシステムであって、前記決定は、前記要求に含まれる前記情報の少なくとも一部および前記要求を受信した前記ノードにローカルな前記情報の少なくとも一部の比較に少なくとも部分的に基づく、コンピュータシステム。
【請求項４４】
請求項４１に記載のコンピュータシステムであって、前記リモート物理ノード上で実行中の前記ゲストスレッドに関する前記情報は、スレッド効率、アフィニティ、デューティ、ページ競合の示唆、前記ゲストスレッドによるページアクセスの記録された履歴、温かさ、利用度、および、前記リモート物理ノード上の１セットのスレッドに関する共通関心のサイズ、の内の少なくとも１つを含む、コンピュータシステム。
【請求項４５】
請求項４１に記載のコンピュータシステムであって、前記要求がページ競合の示唆を含む場合に、前記ゲストスレッドと前記リモート物理ノード上の１セットのゲストスレッドとの間の共通関心のサイズが、前記ゲストスレッドと前記複数の物理ノードの内で前記要求を受信したノード上の１セットのゲストスレッドとの間の共通関心のサイズと比較される、コンピュータシステム。
【請求項４６】
請求項４５に記載のコンピュータシステムであって、前記リモート物理ノード上で実行中の前記ゲストスレッドと前記要求を受信した前記ノード上の前記１セットのゲストスレッドとの間の共通関心の前記サイズは、前記ゲストスレッドによるページアクセスの記録された履歴に少なくとも部分的に基づいて決定され、前記記録された履歴は、前記要求に含まれる、コンピュータシステム。
【請求項４７】
請求項４６に記載のコンピュータシステムであって、前記ゲストスレッドと前記要求を受信した前記ノード上の前記１セットのゲストスレッドに含まれる個々のゲストスレッドとの間の共通関心のサイズが、ハミング重みに少なくとも部分的に基づいて決定され、前記ゲストスレッドと前記要求を受信した前記ノード上の前記１セットのゲストスレッドとの間の共通関心の前記サイズが、少なくとも部分的に、個々のハミング重みを合計することによって決定される、コンピュータシステム。
【請求項４８】
請求項４７に記載のコンピュータシステムであって、個々のハミング重みは、閾値未満である場合に合計から除外される、コンピュータシステム。
【請求項４９】
請求項４１に記載のコンピュータシステムであって、前記応答は前記要求の拒否を含み、前記ゲストスレッドを実行する仮想プロセッサをマイグレートするか、または前記リソースの次の要求を送信するかの決定が、前記リモート物理ノードでなされる、コンピュータシステム。
【請求項５０】
請求項４１に記載のコンピュータシステムであって、前記ゲストスレッドを実行する仮想プロセッサをマイグレートするか、または前記リソースの次の要求を送信するかの前記決定は、前記リモート物理ノードによる前記要求の前記拒否の受信に少なくとも部分的に基づく、コンピュータシステム。
【請求項５１】
方法であって、
複数の物理ノードの内のリモート物理ノードからリソースの要求を受信し、オペレーティングシステムが前記複数の物理ノードにわたって集合的に実行され、前記要求は前記リモート物理ノード上で実行中のゲストスレッドに関する情報を含み、
前記要求に含まれる前記情報の少なくとも一部に少なくとも部分的に基づいて、前記要求されたリソースを送信するか、または前記要求を拒否するかを決定し、
前記決定に少なくとも部分的に基づいて、応答を提供すること、
を備える、方法。
【請求項５２】
請求項５１に記載の方法であって、前記決定は、前記複数の物理ノードの内で前記要求を受信したノードにローカルな前記要求されたリソースに関する情報に少なくとも部分的に基づく、方法。
【請求項５３】
請求項５２に記載の方法であって、前記決定は、前記要求に含まれる前記情報の少なくとも一部および前記要求を受信した前記ノードにローカルな前記情報の少なくとも一部の比較に少なくとも部分的に基づく、方法。
【請求項５４】
請求項５１に記載の方法であって、前記リモート物理ノード上で実行中の前記ゲストスレッドに関する前記情報は、スレッド効率、アフィニティ、デューティ、ページ競合の示唆、前記ゲストスレッドによるページアクセスの記録された履歴、温かさ、利用度、および、前記リモート物理ノード上の１セットのスレッドに関する共通関心のサイズ、の内の少なくとも１つを含む、方法。
【請求項５５】
請求項５１に記載の方法であって、前記要求がページ競合の示唆を含む場合に、前記ゲストスレッドと前記リモート物理ノード上の１セットのゲストスレッドとの間の共通関心のサイズが、前記ゲストスレッドと前記複数の物理ノードの内で前記要求を受信したノード上の１セットのゲストスレッドとの間の共通関心のサイズと比較される、方法。
【請求項５６】
請求項５５に記載の方法であって、前記リモート物理ノード上で実行中の前記ゲストスレッドと前記要求を受信した前記ノード上の前記１セットのゲストスレッドとの間の共通関心の前記サイズは、前記ゲストスレッドによるページアクセスの記録された履歴に少なくとも部分的に基づいて決定され、前記記録された履歴は、前記要求に含まれる、方法。
【請求項５７】
請求項５６に記載の方法であって、前記ゲストスレッドと前記要求を受信した前記ノード上の前記１セットのゲストスレッドに含まれる個々のゲストスレッドとの間の共通関心のサイズが、ハミング重みに少なくとも部分的に基づいて決定され、前記ゲストスレッドと前記要求を受信した前記ノード上の前記１セットのゲストスレッドとの間の共通関心の前記サイズが、少なくとも部分的に、個々のハミング重みを合計することによって決定される、方法。
【請求項５８】
請求項５７に記載の方法であって、個々のハミング重みは、閾値未満である場合に、合計から除外される、方法。
【請求項５９】
請求項５１に記載の方法であって、前記応答は前記要求の拒否を含み、前記ゲストスレッドを実行する仮想プロセッサをマイグレートするかまたは前記リソースの次の要求を送信するかの決定が、前記リモート物理ノードでなされる、方法。
【請求項６０】
請求項５１に記載の方法であって、前記ゲストスレッドを実行する仮想プロセッサをマイグレートするかまたは前記リソースの次の要求を送信するかの前記決定は、前記リモート物理ノードによる前記要求の前記拒否の受信に少なくとも部分的に基づく、方法。
【発明の詳細な説明】
【技術分野】
【０００１】
他の出願の相互参照
本願は、２０１７年２月１０日出願の「ＡＳＳＯＣＩＡＴＩＮＧ  ＷＯＲＫＩＮＧ  ＳＥＴＳ  ＡＮＤ  ＴＨＲＥＡＤＳ」と題する米国仮特許出願第６２／４５７，６０９号、２０１６年８月２９日出願の「ＤＹＮＡＭＩＣ  ＳＣＨＥＤＵＬＩＮＧ」と題する米国仮特許出願第６２／３８０，８９６号、２０１７年３月８日出願の「ＤＹＮＡＭＩＣ  ＳＣＨＥＤＵＬＩＮＧ」と題する米国仮特許出願第６２／４６８，８５６号、２０１７年６月２７日出願の「ＲＥＳＯＵＲＣＥ  ＭＩＧＲＡＴＩＯＮ  ＮＥＧＯＴＩＡＴＩＯＮ」と題する米国仮特許出願第６２／５２５，５４４号、および、２０１７年６月２７日出願の「ＭＥＭＯＲＹ  ＴＨＲＥＡＤ  ＬＯＣＡＬＩＴＹ」と題する米国仮特許出願第６２／５２５，５５２号に基づく優先権を主張し、これらの出願はすべて、あらゆる目的のために参照により本明細書に組み込まれる。
【背景技術】
【０００２】
ソフトウェアアプリケーションは、ますます大量のデータセットに対して動作しており、それら自体がますます複雑になっている。一部の例では、分散型コンピュータシステムが、このようなアプリケーションをサポートするために用いられる（例えば、大型データベースシステムがデータの部分を異なるサーバノードのランドスケープに分散し、ランドスケープにわたって分配されたサブクエリにクエリを最適化する）。残念ながら、ネットワーク構築の複雑さなど、データ配置方法およびデータアクセス分散方法の両方の観点でその分配の管理に著しい努力を費やす必要がある。ランドスケープが変化した場合、データ編成が変化した場合、または、作業負荷が変化した場合、著しい作業が必要になる。より一般的には、複雑なコンピュータシステムの挙動が、時と共に、例えば、アプリケーションの新たなリリース、新たな中間ソフトウェア層の追加、新たなオペレーティングシステムのリリース、新たなプロセッサモデル、データの構造的特徴の変化、データ量の増加、および、異なるデータアクセスパターンと供に変化する。
【図面の簡単な説明】
【０００３】
以下の詳細な説明と添付の図面において、本発明の様々な実施形態を開示する。
【０００４】
以下の詳細な説明と添付の図面において、本発明の様々な実施形態を開示する。
【０００５】
【図１】コンピュータシステムの一実施形態を示す図。
【０００６】
【図２】コンピュータシステムの物理構造を階層として示す図。
【０００７】
【図３Ａ】複数の仮想マシン（それぞれの複数のゲストオペレーティングシステムを備える）が単一の物理マシン上で動作する仮想コンピュータ環境を示す図。
【０００８】
【図３Ｂ】複数の物理マシンが単一の仮想オペレーティングシステムを集合的に実行する仮想コンピュータ環境を示す図。
【０００９】
【図４Ａ】ソフトウェアスタックの一例を示す図。
【００１０】
【図４Ｂ】ソフトウェアスタックの一例を示す図。
【００１１】
【図５】一例のシステム上のハードウェアに対するオペレーティングシステムの視点の一例を示す図。
【００１２】
【図６Ａ】単一のノード上のハードウェアに対するハイパースレッドの視点の一例を示す図。
【００１３】
【図６Ｂ】一例のシステム上のハードウェアに対するハイパーカーネルの視点の一例を示す図。
【００１４】
【図７】一例の企業向けスーパーコンピュータシステム上のハードウェアに対するオペレーティングシステムの視点の一例を示す図。
【００１５】
【図８】リソースを選択的にマイグレートするための処理の一実施形態を示す図。
【００１６】
【図９】階層的な動的スケジューリングを実行するための処理の一実施形態を示す図。
【００１７】
【図１０】初期のメモリ割り当ておよびプロセッサ割り当ての一例を示す図。
【００１８】
【図１１】更新後のメモリ割り当てと、未変更のプロセッサ割り当てとを示す図。
【００１９】
【図１２】メモリ割り当てと、更新後のプロセッサ割り当てとを示す図。
【００２０】
【図１３Ａ】スレッドおよびワーキングセットが関連付けられた環境の実施形態の一例を示す図。
【００２１】
【図１３Ｂ】仮想環境における動的アドレス変換の一例を示す図。
【００２２】
【図１３Ｃ】第２レベルアドレス変換の実行の実施形態の一例を示す図。
【００２３】
【図１３Ｄ】ゲストスレッドに関する情報を格納するために用いられるテーブルの実施形態の一例を示す図。
【００２４】
【図１３Ｅ】ワーキングセットおよびスレッドを関連付けるための処理の一実施形態を示すフローチャート。
【００２５】
【図１４Ａ】ゲスト仮想マシンの初期構成の一例を示す図。
【００２６】
【図１４Ｂ】ページを要求するためのトランザクションの第１段階の一例を示す図。
【００２７】
【図１４Ｃ】ページを要求するためのトランザクションの第２段階の一例を示す図。
【００２８】
【図１４Ｄ】ページを要求するためのトランザクションの第３段階の一例を示す図。
【００２９】
【図１４Ｅ】ページを要求するためのトランザクションの最終結果の一例を示す図。
【００３０】
【図１４Ｆ】リソースマイグレーショングレーションネゴシエーションのための処理の一実施形態を示すフローチャート。
【００３１】
【図１５Ａ】タイダルツリーの実施形態の一例を示す図。
【００３２】
【図１５Ｂ】実行準備のできたｖｃｐｕをエンキューするｐｃｐｕキューの検索の一実施形態を示す図。
【００３３】
【図１５Ｃ】ストールイベントに対処するための処理の一実施形態を示すフローチャート。
【００３４】
【図１５Ｄ】実行準備のできたｖｃｐｕを検索する処理の一実施形態を示すフローチャート。
【００３５】
【図１５Ｅ】実行準備のできたｖｃｐｕをタイダルツリーに配置するための処理の一実施形態を示すフローチャート。
【発明を実施するための形態】
【００３６】
本発明は、処理、装置、システム、物質の組成、コンピュータ読み取り可能な格納媒体上に具現化されたコンピュータプログラム製品、および／または、プロセッサ（プロセッサに接続されたメモリに格納および／またはそのメモリによって提供される命令を実行するよう構成されたプロセッサ）を含め、様々な形態で実装されうる。本明細書では、これらの実装または本発明が取りうる任意の他の形態を、技術と呼ぶ。一般に、開示された処理の工程の順序は、本発明の範囲内で変更されてもよい。特に言及しない限り、タスクを実行するよう構成されるものとして記載されたプロセッサまたはメモリなどの構成要素は、ある時間にタスクを実行するよう一時的に構成された一般的な構成要素として、または、タスクを実行するよう製造された特定の構成要素として実装されてよい。本明細書では、「プロセッサ」という用語は、１または複数のデバイス、回路、および／または、コンピュータプログラム命令などのデータを処理するよう構成された処理コアを指すものとする。
【００３７】
以下では、本発明の原理を示す図面を参照しつつ、本発明の１または複数の実施形態の詳細な説明を行う。本発明は、かかる実施形態に関連して説明されているが、どの実施形態にも限定されない。本発明の範囲は、特許請求の範囲によってのみ限定されるものであり、本発明は、多くの代替物、変形物、および、等価物を含む。以下の説明では、本発明の完全な理解を提供するために、多くの具体的な詳細事項が記載されている。これらの詳細事項は、例示を目的としたものであり、本発明は、これらの具体的な詳細事項の一部または全てがなくとも特許請求の範囲に従って実施可能である。簡単のために、本発明に関連する技術分野で周知の技術要素については、本発明が必要以上にわかりにくくならないように、詳細には説明していない。
【００３８】
図１は、コンピュータシステムの一実施形態を示す。システム１００は、本明細書では「企業向けスーパーコンピュータ」および「メインフレーム」とも呼ばれる。図の例において、システム１００は、近接して位置する（例えば、同じラック内に位置する）複数のノード（例えば、ノード１０２〜１０８）を含む。別の実施形態において、（例えば、同じ施設内に位置する）複数のラックのノードが、システムで用いられてもよい。さらに、本明細書に記載の技術は、分散型システムと併せて利用されてもよい。
【００３９】
ノードは、１０ギガビットＥｔｈｅｒｎｅｔ、ダイレクトＰＣＩ−ｔｏ−ＰＣＩ、および／または、ＩｎｆｉｎｉＢａｎｄなど、高速相互接続（１１０）と相互接続されている。各ノードは、コモディティサーバクラスのハードウェア構成要素（例えば、取り付けられた周辺機器または包含された周辺機器を備えるラック内のブレード）を備える。図１に示す例において、各ノードは、複数の物理プロセッサチップを備える。各物理プロセッサチップ（「ソケット」とも呼ぶ）は、複数のコアを備えており、各コアは、複数のハイパースレッドを有する。
【００４０】
図２に示すように、システム１００の物理構造は、（下から）ハイパースレッド（２３０）、コア（２１０〜２２４）、物理プロセッサチップ（２０２〜２０８）、および、ノード（１０２〜１０８（図から省略され省略記号で表されたノード１０４、１０６などを含む））の階層を形成する。図２に示すツリーは、ハードウェア構成によって規定された固定サイズである。
【００４１】
後に詳述するように、各企業向けスーパーコンピュータ（例えば、システム１００）は、単一のオペレーティングシステムを実行する。オペレーティングシステムおよび任意のアプリケーションの両方が、標準的な市販のソフトウェアであってよく、システム１００上で動作しうる。本明細書に記載の例において、オペレーティングシステムはＬｉｎｕｘ（登録商標、以下同じ）であるが、Ｍｉｃｒｏｓｏｆｔ  Ｗｉｎｄｏｗｓ、Ｍａｃ  ＯＳ  Ｘ、または、ＦｒｅｅＢＳＤなど、その他のオペレーティングシステムが用いられてもよい。
【００４２】
従来の仮想コンピュータ環境では、複数の仮想マシンが、単一の物理マシン上で動作しうる。このシナリオは、図３Ａに図示されている。具体的には、３つの仮想マシン（３０２〜３０６）が、単一の物理マシン（３０８）上で３つのゲストオペレーティングシステムを実行しており、物理マシンは、独自のホストオペレーティングシステムを有する。対照的に、本明細書に記載の技術を用いると、複数の物理マシン（３５４〜３５８）が、図３Ｂに示すように、単一の仮想オペレーティングシステム（３５２）を集合的に実行する。
【００４３】
ソフトウェアスタックの一例が、図４Ａに示されている。かかるスタックは、通例、従来のコンピュータ環境で用いられてよい。図４Ａに示すスタック内では、アプリケーション（４０２）が、データベースエンジン（４０４）上にあり、次いで、データベースエンジン（４０４）は、オペレーティングシステム（４０６）上にあり、その下に、ハードウェア（４０８）がある。図４Ｂは、いくつかの実施形態において用いられるソフトウェアスタックを示している。図４Ａに示したスタックと同様に、アプリケーション（４５２）が、データベースエンジン（４５４）上にあり、次いで、データベースエンジン（４５４）は、オペレーティングシステム（４５６）上にある。しかしながら、オペレーティングシステムの下かつハードウェアの上には、システムの動作をリアルタイムで観察し、システムの動作時にシステムの要求に一致するようにシステムリソースを最適化するソフトウェアの層（本明細書ではハイパーカーネルと呼ぶ）がある。ハイパーカーネルは、概念的には、一群のコモディティサーバのＲＡＭ、プロセッサ、および、Ｉ／Ｏ（例えば、ストレージ、ネットワーキングリソースのための入力出力リソース）を統合し、その統合したセットをオペレーティングシステムに提示する。この抽象化のため、オペレーティングシステムからは、プロセッサ、メモリ、および、Ｉ／Ｏの集合的なセットを含む単一の大型コンピュータが見える。後に詳述するように、ハイパーカーネルは、リソースの利用を最適化する。ハイパーカーネルは、ネットワークおよびストレージなど、他のＩ／Ｏシステムリソースの最適化も助けうる。いくつかの実施形態において、実行中のソフトウェアの観察およびプロファイルに基づいて、パフォーマンス指標（ヒント）が、システムパフォーマンス全体をさらに改善しうるシステムの動的パフォーマンスについて、上層（例えば、データベース管理システム）に提供される。
【００４４】
ハイパーカーネルは、すべての主要なマイクロプロセッサ、メモリ、相互接続、永続記憶装置、および、ネットワーキングアーキテクチャに移植されうる。さらに、ハードウェア技術が（例えば、新たなプロセッサ、新たなメモリ技術、新たな相互接続などで）進化するにつれ、ハイパーカーネルは、産業の進化を活用する必要に応じて修正されうる。
【００４５】
図４Ｂに示すように、オペレーティングシステム４５６は、一連のノード（４５８〜４６２）にわたって集合的に動作しており、各ノードは、サーバハードウェア上で動作するハイパーカーネルを有する。具体的には、オペレーティングシステムは、一群のハイパーカーネルによって定義された仮想環境上で動作している。後に詳述するように、オペレーティングシステム４５６の視点では、オペレーティングシステムは、個々のノード４５８〜４６２のハードウェアリソースすべてを含む単一のハードウェアプラットフォーム上で動作している。したがって、各ノードが１ＴＢのＲＡＭを備える場合、オペレーティングシステムからは、自身が、３ＴＢのＲＡＭを備えたハードウェアプラットフォーム上で動作しているように見える。その他のリソース（処理能力およびＩ／Ｏリソースなど）も、同様に、オペレーティングシステムの視点で集合的に利用可能になりうる。
【００４６】
図５は、一例のシステム上のハードウェアに対するオペレーティングシステムの視点の一例を示す図である。具体的には、オペレーティングシステム（５０２）は、プロセッサ５０４〜５０８および物理共有メモリ５１０の上で動作する。既述のように、オペレーティングシステムは、従来のコンピュータシステム上または図１に示すような企業向けスーパーコンピュータ上のいずれかで動作できる。いずれにしても、オペレーティングシステムから見ると、自身は、プロセッサ５０４〜５０８および物理共有メモリ５１０にアクセスできることになる。
【００４７】
図６Ａは、単一のノード上のハードウェアに対するハイパースレッドの視点の一例を示す図である。この例において、ノードは、Ｈ１（６０２）〜Ｈ４（６０８）で示された４つのハイパースレッドを有する。各ハイパースレッドは、物理共有メモリ６１２のすべての部分にアクセスできる。物理共有メモリ６１２は、線形メモリであり、位置０から最大量「ｍａｘ」までラベル付けされている。ノードは、３つのレベルのキャッシュ（６１０）も備える。
【００４８】
図６Ｂは、一例のシステム上のハードウェアに対するハイパーカーネルの視点の一例を示す図である。この例では、３つのノード（６５２〜６５６）が、企業向けスーパーコンピュータに含まれる。３つのノードの各々が、４つのハイパースレッド、物理共有メモリ、および、キャッシュを有する（すなわち、各ノードは、図６Ａに示したノード６００の一実施形態である）。所与のノード（例えば、ノード６５２）上のハイパースレッドは、図６Ａに示す視点と同じ視点を有する。しかしながら、ハイパーカーネルは、すべてのノード上のすべてのリソースを認識している（すなわち、ハイパーカーネルには、１２のハイパースレッドおよびすべての物理共有メモリが見える）。図６Ｂに示した例において、所与のハイパースレッド（例えば、ハイパースレッド６５８、「Ｈ１−４」）は、ノード番号（例えば、「１」）の後にハイパースレッド番号（例えば、「４」）を続けてラベル付けされる。
【００４９】
図７は、一例の企業向けスーパーコンピュータシステム上のハードウェアに対するオペレーティングシステムの視点の一例を示す図である。オペレーティングシステムには、Ｐ１〜Ｐｍａｘ（７０２）として図７に示された複数の「仮想化プロセッサ」が見える。仮想化プロセッサは、企業スーパーコンピュータに含まれるすべてのノードにわたるハイパースレッドの総数に対応する。したがって、図６Ｂの例を用いると、合計１２のハイパースレッドが３つのノードにわたって存在する場合、企業向けスーパーコンピュータ上で動作するオペレーティングシステムにとっては、合計１２の仮想化プロセッサが見えることになる。オペレーティングシステムには、すべてのノードにわたる物理メモリの総量に等しいサイズの大型の物理的な線形メモリのように見える「仮想物理メモリ」（７０４）も見える。
【００５０】
後に詳述するように、ハイパーカーネルは、実行中のシステムの観察に基づいて、キャッシュメモリの利用および仮想プロセッサの配置を動的に最適化する。「仮想プロセッサ」は、そのゲストオペレーティングシステムに知られている計算エンジン（すなわち、何らかのオペレーティングシステムコンテキストまたは状態を有するもの）である。後に詳述するように、「シャドープロセッサ」は、匿名の仮想プロセッサ（すなわち、仮想プロセッサであったが、現在は、そのオペレーティングシステムコンテキストを放棄しており、ハイパーカーネルにのみ知られるコンテキストを有するもの）である。
【００５１】
リソースの仮想化
【００５２】
メモリの仮想化
【００５３】
上述のように、物理構成において、各ノードは、メモリ内での位置を表す一連のメモリアドレスを有する。このように、（例えば、図６Ｂに示したように）３つのノードを有する物理構成においては、各々がアドレス０ｘ１２３４５６を有する３つのメモリ位置がある。対照的に、仮想構成においては、すべてのメモリアドレスが一意的であり、それらの３つのノードに含まれるすべてのメモリの総計を表す。仮想構成では、すべてのメモリが共有され、すべてのメモリキャッシュがコヒーレントである。いくつかの実施形態において、メモリは、単調増加するメモリアドレスで、一連の連続的なブロックにさらに分割される。本明細書に記載される例において、各ページは、４Ｋバイトのメモリを有するが、適用できる場合、その他の分割が用いられてもよい。「ブロック」という用語は、本明細書では、メモリ位置の連続的な配列を記述するのに用いられる。いくつかの実施形態において、「ブロック」は「ページ」である。
【００５４】
プロセッサの仮想化
【００５５】
オペレーティングシステムから見られる仮想プロセッサ（例えば、図７の仮想プロセッサ７０６）は、物理構成内のハイパースレッド上に実装されるが、位置独立でありうる。したがって、オペレーティングシステムは、単一の物理サーバ上で動作する５００のプロセッサを有すると考えるが、実際には、各々１００プロセッサの５ノードを有しうる。（つまり、図６Ｂに示したように、オペレーティングシステムは、単一の物理サーバ上で動作する１２のプロセッサを有すると考える）。仮想プロセッサ上で実行される計算は、計算が実行されている場合にハイパースレッド上の物理構成によって、または、仮想プロセッサが動作中ではない場合（すなわち、計算の中断またはストールの状態）に「継続（ｃｏｎｔｉｎｕａｔｉｏｎ）」で記述される。
【００５６】
本明細書で用いられているように、「継続」は、仮想プロセッサの状態を表す。各継続は：
【００５７】
・プロセッサ状態（すなわち、退避レジスタなど）を有する  。
【００５８】
・実行に向けてリーフノードに継続をインテリジェントに割り当てる方法に関する情報でスケジューラオブジェクトを導く１セットのパフォーマンスインジケータを有する。
【００５９】
・オペレーティングシステムの考えるプロセッサがこの継続の割り当てられる物理プロセッサであることを示す仮想プロセッサ識別子を有する。
【００６０】
・この継続が待っている（おそらくは、エンプティである）イベントを有する。
【００６１】
・以下を含む状態を有する。「イベント待機」または「レディ」。
【００６２】
Ｉ／Ｏの仮想化
【００６３】
Ｉ／Ｏシステムは、プロセッサおよびメモリと同様のパラダイムに従う。デバイスは、物理構成における物理アドレスおよび仮想構成における仮想アドレスを有する。（後に詳述する）計算を移動させる時に、例えば、Ｉ／Ｏ動作に関連するメモリバッファがある場合、利用されるＩ／Ｏデバイスは、それらが関連するメモリと同じ場所に配置されれば、より性能が高くなる可能性があり、状況に応じて移動可能である。
【００６４】
リソースマップ
【００６５】
リソースマップは、仮想構成と物理構成との間の翻訳に用いられる。以下は、様々な実施形態において企業向けスーパーコンピュータによって用いられる３つのタイプのリソースマップである。
【００６６】
「物理リソースマップ」は、各ノードで利用可能な物理リソースを記述するテーブルである。それは、例えば、各ノード上のプロセッサ、デバイスの数およびタイプ、利用可能なメモリおよびその物理アドレスの範囲、などを含む。いくつかの実施形態において、このテーブルは、読み出し専用であり、起動時に固定される。
【００６７】
「初期仮想リソースマップ」が、オペレーティングシステムの起動の前に固定され、オペレーティングシステムの観点から利用可能な仮想リソースを記述する。構成は、オペレーティングシステムによって読み取り可能である。一部の例において、下層のハードウェアリソースと、一対一で一致しない（オペレーティングシステムの視点からの）システムを構成することが望ましい場合がある。一例として、オペレーティングシステムにとっては、より多くのメモリおよびより少ないコアを有することが望ましい場合がある。これは、メモリ対コアの比を変更することによって（すなわち、初期仮想リソースマップを修正することによって）達成できる。
【００６８】
「現行のリソースマップ」が、各ハイパーカーネルインスタンスによって作成および維持される。このマップは、各ノードの視点からの仮想リソースマップと物理リソースマップとの間の現行のマッピングを記述する。仮想リソースマップ内の各エントリに対して、仮想リソースへ現在割り当てられている物理リソースの定義が維持される。最初（例えば、起動時に）、現行のリソースマップは、初期仮想リソースマップのコピーである。ハイパーカーネルは、リソース負荷の特性を観察しながら、時間と共に現行のリソースマップを修正し、仮想リソースに対する物理リソースのマッピングを動的に変更する（および逆も行う）。例えば、仮想化マシンにおけるイーサネットコントローラｅｔｈ２７の位置の定義は、異なるハードウェアコントローラを、異なる時間に参照しうる。現行のリソースマップは、必要に応じて、仮想ハードウェアリソースマッピングを動的に修正するためにハイパーカーネル（仮想メモリサブシステムなど）によって用いられる。
【００６９】
リソースマイグレーション（移動）の概要
【００７０】
本明細書に記載の技術を用いれば、仮想リソースを物理位置の間で移動できる。上述のように、オペレーティングシステムは、仮想システムに関する情報を提供されるが、その情報は、物理システムと一致する必要はない。
【００７１】
以下の例において、企業のスーパーコンピュータが、単一のノードに収まりうるよりも大きい大型のインメモリデータベースを保持すると仮定する。データベースの一部は、第１ノード「ノード１」にある。異なるノード「ノード２」上のコアの１つが、ノード１によって所有されノード２上のキャッシュにローカルに存在しないデータにアクセスを試みていると仮定する。ノード２上のコアは、アクセスできると思われる（ただし、アクセスできない）データへのアクセスを試みているので、メモリアクセス違反を受信する。後に詳述するように、例外は、ハイパーカーネルにおいて処理される。
【００７２】
その状況を解決できる一方法は、必要なメモリ領域をノード２に移した後に、制御をオペレーティングシステムに戻す（オペレーティングシステムは、次に、制御をデータベースシステムに戻す）ことによる方法である。次いで、ソフトウェアは、意図されたように進むことができる（すなわち、アクセス違反が起こらなかったかのように）。
【００７３】
多くの場合、上記のノード２が必要とするメモリの同じ領域ブロックにアクセスを試みている他のノード（例えば、「ノード３」）内の１または複数の他のコアが存在しうる。ノード３は、同じデータにアクセスを試みている場合もあるし、移されたメモリに含まれる別のデータにアクセスしている場合もある（「偽共有」とも呼ぶ）。データは、ノード３に移動されることができるが、ノード２上のコアが、二回目にデータを要求した場合、データは、ノード２に戻される必要があり（すなわち、潜在的にデータの往復を繰り返す）、これは、遅くて無駄が多い場合がある。コア間のデータの往復移動を避けるための一方法は、両方のコアと、データに関連するブロックが、同じ場所にあることを認識することである。本明細書に記載の技術を用いれば、メモリおよび計算が、同じノードに存在するように移行されうる。そうすることにより、データへのより高速なアクセスの可能性が高くなり、ローカルキャッシュに格納されたデータを共有する可能性が高くなる。
【００７４】
アクセス違反が起きると、イベントが（システム依存の方法で）トリガされ、それにハイパーカーネルが応答する。かかるイベントに対処する方法の一例は、パニックルーチンの呼び出しによる方法である。適切であれば、その他のアプローチが用いられてもよい。後に詳述するように、ハイパーカーネルは、イベントの原因を分析し、イベントに対処するために適切な戦略（例えば、低レベルトランザクション）を決定する。上述のように、イベントに対処する一方法は、ハイパーカーネル仮想化メモリの１または複数のブロックが、或るノードのメモリから別のノードのメモリへ転送される方法である。次いで、転送が開始され、対応するリソースマップが更新される。継続は、再開された時に行う次のことが、転送の完了後にオペレーティングシステムに制御を戻すことになるように、イベントテーブル（後述する）と呼ばれる共有メモリ内のローカルテーブルに配置される準備が整うように構築される。要求されているメモリを含むノードに仮想プロセッサを移動させる決定、または、或るノードから別のノードへ仮想メモリ（およびその仮想メモリアドレス）を移動させる決定もなされうる。様々な実施形態において、ハイパーカーネルは、イベントに対処する時に、どの（仮想）リソースが移動すべきか、いつ移動させるべきか、および、（物理位置に関して）どこへ移動すべきか、の３つの決定を行う。
【００７５】
タイダルツリー（ＴＩＤＡＬＴＲＥＥ）
【００７６】
図２に示した物理階層構造は、１セットの「スケジューラオブジェクト」（すなわち、データ構造）を含む類似のソフトウェア階層を有し、各スケジューラオブジェクトは、後述の１セットの特徴を有する。スケジューラオブジェクトは、「タイダルツリー」を形成し、これは、ツリーの各ノードがスケジューラオブジェクトであるインメモリツリーデータ構造である。各スケジューラオブジェクトは、スーパーコンピュータの物理構造の要素に対応する（ただし、必ずしも逆は成り立たない）ので、マシン全体に対して１つのノード（例えば、図２に示すノード１００）、システムの各物理ノードに対して１つのノード（図２に示すノード１０２）、マシン全体を含む物理ノード上の各マルチコアソケットに対して１つのノード（例えば、図２に示したノード２０２）、各ソケットの各コアに対して１つのノード（例えば、図２に示すノード２１０）、そのコア上の各ハイパースレッドに対して１つのノード（例えば、図２に示すノード２３２）が存在する。
【００７７】
各スケジューラオブジェクトｓは、
【００７８】
・物理的構成要素（例えば、ラック、ブレード、ソケット、コア、ハイパースレッド）に関連する。
【００７９】
・ツリーのルートを除いて、（後に詳述するように）その動作を方向付けることに部分的に関与する親スケジューラオブジェクトを有する。
【００８０】
・各々がスケジューラオブジェクトである１セットの子オブジェクトを有する。これは、リーフ（例えば、ハイパースレッド）ノードについては空のセットである。後に詳述するように、作業を管理して、その子オブジェクトに、そして、間接的に孫オブジェクトなどに、作業を割り当てる（または、割り当て直す）のが、スケジューラオブジェクトｓの役割である（すなわち、ｓは、ｓをルートとするサブツリー内のすべてのノードを管理する）。
【００８１】
・（上述のように）１セットの継続である作業キューを有する。
【００８２】
・作業を管理して割り当てる（または割り当て直す）ことに同じく関与する（おそらくはエンプティの）セットのＩ／Ｏデバイスを有する。
【００８３】
各ノードは、何らかのキャッシュメモリの形態の層と潜在的に関連付けられうる。キャッシュ階層は、スケジューラオブジェクトが高くなるほど、通常は、計算が階層の対応するレベルのキャッシュを効率的に利用することが遅くなるという意味では、ツリーの階層に従う。物理ノードに対応するスケジューラオブジェクトのキャッシュは、そのノードに対応するメモリのキャッシュでありうる。物理ノード上のメモリは、仮想マシンのメモリのキャッシュと考えることができる。
【００８４】
リソースマイグレーション−追加情報
【００８５】
ハイパーカーネルは、仮想構成が存在する仮想ハードウェアの一部をシミュレートする。それは、イベント駆動型アーキテクチャであり、翻訳された物理ハードウェアイベントだけでなく、他のノード上で動作するハイパーカーネルコードによって生成されたノード間ハイパーカーネルメッセージの受信など、ソフトイベントも処理する。
【００８６】
上述のように、ハイパーカーネルにとって重要な割り込みイベントが発生すると、ハイパーカーネルは、割り込みに応答する方法を決定する。制御がオペレーティングシステムに戻される前に、任意のより高い優先順位の割り込みが認識され、適切な動作が取られる。また、上述のように、ハイパーカーネルは、（１）特定のイベント後にどのリソースが移動すべきか、（２）いつそれらを移動させるか、および、（３）それらのリソースはどこに移動すべきか、といった３つの別個の決定を行い得る。
【００８７】
以下の例において、仮想マシン内のスケジューラオブジェクト「ｓ」が、定常状態であると仮定する。物理ノードに対応する各スケジューラオブジェクトは、それに割り当てられた１セットの物理プロセッサソケットを有する。これらのソケット内のハイパースレッドは、ビジーであってもそうでなくてもよい。物理ノードは、さらに、いくらかの固定量のメインメモリと、いくつかのネットワークデバイスなど、１セットのＩ／Ｏデバイスと、を有する。スケジューラオブジェクトｓは、ノードに対応する場合、ネットワークと、ｓをルートとするサブツリー内のノードに割り当てられた他のＩ／Ｏデバイスとの管理にも関与する。以下では、リソースが同期または非同期的イベントのいずれかの後にどのように移動しうるのかを説明する。
【００８８】
同期イベントによってトリガされるマイグレーション
【００８９】
以下の例では、リーフノードスケジューラオブジェクトｓと、ｓに割り当てられた仮想プロセッサｐが存在すると仮定する。リーフノードスケジューラオブジェクトｓは、アプリケーションの代わりに、アプリケーションまたはオペレーティングシステムコードを実行しているとする。リーフノードが無限ループに入っていないと仮定すると、ｐは、最終的に、何らかの理由（例えば、Ｉ／Ｏ動作、ページフォールトなどの完了の待機）で、実行すべき作業がなくなる（すなわち、ストールする）。ｐが実際にストールすることを許容する代わりに、ハイパーカーネルは、ストールされた計算に関する情報を或る他のノードに移して、他のノードのプロセッサの１つに、ストールした継続の「責任」を持たせるのか、または、ストールした計算に対するノードの「責任」を維持し、その代わりに現行のノードに関連リソースを移すのかを決定する。
【００９０】
したがって、ストールは、以下の２つの方法のいずれかで処理される：計算が、現在リソースを有する物理ノードに移されるか、あるいは、リソースが、リソースを要求した物理ノードに移される。ストールの処理のための擬似コードの例は、後の「ルーチンの例」セクションで（「ＯｎＳｔａｌｌ」ルーチンとして）提供される。
【００９１】
ストールを処理する方法などの決定は、イベントの到着順、仮想マシン上で実行中の計算の状態、キャッシュの状態、システムまたはノードへの負荷、ならびに、多くのその他のことなど、多くのことに依存しうる。決定は、動的になされる、すなわち、時間の所与の時点に利用可能な最良の情報に基づいてなされる。
【００９２】
ストールした計算の記録
【００９３】
ストールした計算は、「継続」と呼ばれるデータ構造に記録される。継続は、例えば、「イベント待機」または「レディ」でありうる状態を有する。ストールした計算は、状態「イベント待機」を持つ新たに作成された継続として記録される。（例えば、イベントの検出により）ストールの理由が満たされると、対応する継続の状態は、「レディ」に変更される。「レディ」状態を持つ各継続は、最終的に実行に向けてスケジューリングされるように、スケジューラオブジェクトの「待機キュー」に格納される。対照的に、「イベント待機」状態を持つ任意の継続は、どのスケジューラオブジェクトの待機キューにも格納されない。その代わり、見つからないリソースの受信など、対応する計算をストールさせたハードウェアイベントの発生が予測される物理ノードのローカル共有メモリに格納される。
【００９４】
さらに、新たに作成された継続は、その作成の原因となったストールイベントに関連付けられる。（ストール）イベントと、これらのイベントを待つ継続との間のこのマッピングは、非同期イベントの迅速なディスパッチを可能にする（後述の「ｈａｎｄｌｅＥｖｅｎｔ」を参照）。継続とイベントとの間のマッピングは、「イベントテーブル」と呼ばれるテーブルに格納され、対応する物理ノードの共有メモリ内に保持される。各物理ノードは、独自のイベントテーブルを有し、物理ノードのイベントテーブルは、物理ノード上のすべてのコアによって直接的にアドレス可能である。物理ノードのイベントテーブルに記録されたすべての予定されたイベントは、物理ノード上で発生しうるハードウェアイベントに対応する。物理ノードｎにマッピングされたスケジューラオブジェクトｓは、ｎを表し、ｎのイベントテーブルは、ｓと関連付けられる。一部の例において、いくつかの継続が、同じイベントを待っている場合があり、イベントがトリガされた時に、何らかの曖昧性の除去が求められうる。
【００９５】
継続は、「ＩｎｉｔＣｏｎｔｉｎｕａｔｉｏｎ」ルーチンを用いて構築される。計算を移動させる決定がなされた場合、リソースを保持するリモート物理ノードが、ストールされた計算に対応する継続を構築し、リモート物理ノードのイベントテーブルにそれを格納する。その継続が再開すると、リソースは利用可能になる。実際には、ハイパーカーネルは、異なるノードに仮想プロセッサを移している。
【００９６】
リソースを移動させる決定がなされた場合、ストールを経験したノードは、リソースの移送を要求し、ＩｎｉｔＣｏｎｔｉｎｕａｔｉｏｎを用いて継続を構築し、ローカルイベントテーブルにそれを格納する。リソースの受信後、継続は、タイダルツリー内の適切なノードにアタッチされ、その継続が再開されると、リソースは、一般に、利用可能かつ可視になる。実際には、仮想リソースは、それを要求したノードに移送されている。
【００９７】
イベントテーブル内に継続を配置することにより、イベントを受信するプロセッサが、ローカルイベントテーブル内で関連する継続を迅速に見つけることが保証されることに注意されたい。計算のストールの理由は、満たされることになる。
【００９８】
ストールに対処すると、仮想プロセッサｐは、実際には一時停止される。ストールを処理して、再開すべき新たな継続を見つけるまでの合間に、ｐは、「匿名のシャドープロセッサ」になる、すなわち、オペレーティングシステムに知られているＩＤのないプロセッサになる。次いで、このシャドープロセッサは、再開すべき新たな継続を探す。これの一例が、後に詳述する「ａｓｓｉｇｎＰｒｏｃｅｓｓｏｒ」ルーチンに見られる。
【００９９】
表記
【０１００】
仮想プロセッサｐをストールしたイベントをｅとする。ｅは、ある物理ノードｎのローカルハードウェアによってトリガされると仮定する。特に、ｒが、ストールイベントの発生の原因となったリソースであると仮定する。リソースｒは、メモリのブロック、Ｉ／Ｏ動作、または、ネットワーク動作でありうる。ｐは、スケジューラオブジェクトｓに割り当てられると仮定し、スケジューラオブジェクトｓは、物理ノードｎを表すスケジューラオブジェクトをルートとするサブツリーに属する。
【０１０１】
Ｏｎ−Ｓｔａｌｌ
【０１０２】
ｏｎ−ｓｔａｌｌルーチンの一例に対する擬似コードを、以下の「ルーチンの例」セクションで提供する。ｍｉｇｒａｔｉｏｎ−ｃｏｎｔｉｎｕａｔｉｏｎ関数は、リソースが移動すべきではない、すなわち、計算が移動すべきであると、ノードｎ内のプロセッサｐが決定した場合かつその場合に限り、ｔｒｕｅを返す。これは、ノード間でのｒの移動の履歴および頻度、ｒのタイプ、移動のコスト、ｒを待つｎのローカルイベントテーブル内のイベントの数、システム負荷など、多くの要因によって決定されうる。例えば、リソースを待つｎのローカルイベントテーブルに格納された継続がある場合、そのリソースを移動することが望ましくない場合がある。
【０１０３】
マイグレーションの恩恵を受ける様々なパターンのイベントが存在する。アクセス違反のようなこれらのパターンのイベントを記述する１つのアプローチは、形式言語理論である。正規（すなわち、チョムスキーのタイプ３）言語は、有限状態オートマトンによって認識することができる。さらに、コンパクトで柔軟な表記を用いて、観察されるイベントの記述は、正規言語の文（またはチョムスキー配列（Ｃｈｏｍｓｋｙ  ｓｅｑｕｅｎｃｅ））としてなされることができ、認識は、対応する有限状態オートマトンにおける状態遷移としてモデル化されうる。イベントの完全なチョムスキー配列が見られる場合、ｍｉｇｒａｔｉｏｎ−ｃｏｎｔｉｎｕａｔｉｏｎは、それに応じて評価される：有限状態オートマトンがチョムスキー配列を受け入れる場合、条件は満たされ、そうでない場合には満たされない。最小化された有限状態マシンの長さは、保持する必要のある履歴の量を規定する。
【０１０４】
様々な実施形態において、すべてのイベントがローカルに起こり、イベントを受信する物理ノード上のハイパーカーネルが、それを処理しなければならない−真の同期イベントは、物理ノード間で発生しないと仮定される。ノード間でのマイグレーション戦略を調整するために、「メッセージ」が用いられる。プロセッサまたはシャドープロセッサが、一般に、メッセージの受信を待たない点で、メッセージ「送信」は、ノードの視点からは同期的であるが、メッセージ「受信」は、非同期的である。メッセージが到着すると、仮想割り込みとしてハイパーカーネルによって処理される。一実施形態において、ハイパーカーネルは、処理を待つメッセージがある間は、プロセッサが継続を再開することを許容しない。したがって、制御がオペレーティングシステムに戻される前に、キューがチェックされ、オペレーティングシステムに制御を戻す前に、あらゆるメッセージが処理される。
【０１０５】
スケジューラオブジェクトｓおよび継続ｃについて、ツリーの検索を導くために、コスト関数ｃｏｓｔ（ｓ，ｃ）を利用できる。ｐの複数の先祖がエンプティではないキューを有する場合に、ｐは、エンプティではない待機キューで見つかった第１先祖でその検索の停止を望まない場合がある。最適化戦略で用いられるメトリックに応じて、ｐの選択は、ｐとその選択された先祖との間の距離にだけでなく、その他のパラメータ（待機キューの長さなど）にも依存してよい。
【０１０６】
スケジューラオブジェクトの（空でない）待機キューにおける「最良適合」継続を返すために、関数ｆｉｎｄ−ｂｅｓｔ−ｗｉｔｈｉｎ（ｓ）を利用できる。考慮できるパラメータの例は以下を含む。
【０１０７】
１．キューにおける位置
【０１０８】
２．ｐと、継続に記録された最後の位置との間の関係性（それらの位置が近いほど、キャッシュエントリの再利用にとって良くなる）
【０１０９】
３．キューに内の継続に記録されたパフォーマンスインジケータ
【０１１０】
ｃｏｓｔ関数およびｆｉｎｄ−ｂｅｓｔ−ｗｉｔｈｉｎ関数は、所与のシステム内で適用可能なようにカスタマイズできる。
【０１１１】
非同期イベントによってトリガされるマイグレーション
【０１１２】
非同期イベントの例は以下を含む。パケットの受信、Ｉ／Ｏ転送の完了、リソースの受信、リソースを要求するメッセージの受信、など。一般に、オペレーティングシステムによって管理されるハードウェアデバイスに対応するイベントを受信するハイパーカーネルは、そのイベントに関連する継続をスケジューラオブジェクトｓに供給する必要がある。そうすることにより、ｓは、適切なスケジューラオブジェクトに、そして最終的には、その継続によって表されたオペレーティングシステムによって管理される計算に、この継続を利用可能にする。他方で、イベントが、別の物理ノード上のハイパーカーネルからのメッセージの受信である場合、ハイパーカーネルは、それを直接処理できる。
【０１１３】
説明を簡単にするために、本明細書に記載の例においては、イベントに関連する継続が１つだけであると仮定する。本明細書に記載の手順は、必要に応じて、複数の継続が同じイベントに関連する例に一般化できる。
【０１１４】
いくつかの実施形態において、継続を配置すべきスケジューラオブジェクトの検索は、その継続を構築したツリーのリーフで始まり、その後、（計算がこのノードで以前に実行された場合には）上方に進む。そうすることにより、キャッシュエントリの再利用の可能性が高くなる。
【０１１５】
Ｈａｎｄｌｅ−Ｅｖｅｎｔ
【０１１６】
ｈａｎｄｌｅ−ｅｖｅｎｔルーチンの一例に対する擬似コードを、以下の「ルーチンの例」セクションで提供する。コスト関数ｃｏｓｔ（ｓ，ｃ）は、スケジューリングオブジェクトｓにｃを割り当てる適合性を決定するのに役立つ関数である。コスト関数は、待機キューのサイズ、（キャッシュエントリが再利用される可能性を高めるための）ｓとｃの元々のスケジューリングノードとの間のノードトラバース距離、ならびに、仮想プロセッサ、物理プロセッサ、および、継続の履歴など、様々なパラメータに依存しうる。ｓに近いスケジューラオブジェクトの待機キューの含む継続がすでに多すぎる場合、すべての新たに追加された継続が実行に向けてスケジューリングされるまでに比較的長い時間が掛かりうる。ｃｏｓｔ（ｓ，ｃ）に寄与する条件の例を以下に記載しており、それらの状態は、適用可能なようにカスタマイズできる。
【０１１７】
コスト
【０１１８】
コスト関数は、継続を選択してオブジェクトをスケジューリングする時にオプションを評価するために用いられる。コスト関数は、重み付き因子の総和として表現できる：
【０１１９】
ｃｏｓｔ＝ｗ１ｆ１ｘ１＋ｗ２ｆ２ｘ２＋．．．＋ｗｎｆｎｘｎ
【０１２０】
ここで、ｗｉは、対応する因子の重要度を示し、ｘｉは、指数を示す。
【０１２１】
因子ｆｉの例を、以下のコストの各々について記載する。重みｗｉおよび指数ｘｉは、様々な方法で決定できる（経験的に決定する、シミュレーションによって決定する、など）。初期の重みおよび指数は、様々な応用のニーズに合わせることが可能であり、パフォーマンスを改善するために、管理者によって調整されうる。重みは、システムがアクティブである間に調整可能であり、重みの変更は、ハイパーカーネルのセマンティクスを変更せず、動作パフォーマンス特徴だけを変更する。
【０１２２】
考慮できる因子の例は以下を含む。
【０１２３】
・最後のプロセッサがこのスケジューラオブジェクトを評価してからの時間の長さ
【０１２４】
・タイダルツリー内でのスケジューラオブジェクトの高さ
【０１２５】
・作業キューの長さ
【０１２６】
・保留状態（すなわち、或るアプリケーションが特定の理由でこのリソースを保存した場合でありうる）
【０１２７】
・ノード仕様（すなわち、ノード自体が、非稼働状態にされた可能性がある、または、問題がある、何らかの形で特殊な機能を有する、など）
【０１２８】
・キュー内の継続の齢
【０１２９】
・この継続を最も実行しそうにない物理プロセッサ
【０１３０】
・この継続を最も実行しそうにない仮想プロセッサ
【０１３１】
・この継続を最後に実行していたノード
【０１３２】
・キャッシュの「温度」（キャッシュは、再利用される可能性のあるエントリを有する場合に「温かい」。キャッシュは、再利用可能なキャッシュエントリを有する可能性が低い場合に「冷たい」）
【０１３３】
・継続のグループメンバーシップ（すなわち、継続は、計算グループの一部であってよく、グループの各要素は、グループのその他のメンバに対する何らかのアフィニティを有する）
【０１３４】
・パフォーマンスインジケータ（ヒント）および特別な要件
【０１３５】
例
【０１３６】
「ＯｎＳｔａｌｌ」および「ａｓｓｉｇｎＰｒｏｃｅｓｓｏｒ」
【０１３７】
図８は、リソースを選択的に移動させるための処理の一実施形態を示す。いくつかの実施形態において、処理８００は、ＯｎＳｔａｌｌルーチンと共に実行されるなど、ハイパーカーネルによって実行される。処理は、コア（または、プロセッサチップがハイパースレッドを支持するか否かに応じて、コアに含まれるハイパーカーネル）がブロックされている旨の示唆が受信される工程８０２で始まる。一例として、ハイパースレッドがアクセスできないリソース（例えば、ハイパースレッドを保持するノードとは異なるノードに配置されたＲＡＭ）の要求を、そのハイパースレッドが直接的または間接的に受信すると仮定する。ハイパースレッドがリソースにアクセスできない（すなわち、アクセス違反が発生する）場合、割り込みが起こり、それは、工程８０２でハイパーカーネルによって、インターセプト、キャッチ、または、その他の方法で受信される。特に、ハイパーカーネルは、（提供するよう指示されたリソースへアクセスできないので）ハイパースレッドがブロックされている旨の示唆を工程８０２で受信する。ブロック状態を報告することに加えて、ハイパーカーネルは、アクセスするよう指示されたメモリアドレスおよび試みられたアクセスのタイプ（例えば、読み出し、書き込み、または、修正）などの情報を提供する。
【０１３８】
工程８０４において、ハイパーカーネルは、必要とされるメモリが（例えば、ブロックされたハイパースレッドが位置するノードへ）移動されるべきか、要求処理が再マッピングされる（すなわち、仮想プロセッサが別のノードに移される）べきか、を決定する。決定は、必要とされるメモリが位置する場所、キャッシュの温度、ハイパースレッドを保持するノードへの作業負荷、および、必要とされるメモリを保持するノードへの作業負荷（例えば、過負荷または低負荷）など、様々な因子に基づきうる。いくつかの実施形態において、ノードの作業負荷は、タイダルツリーにおける平均キュー長に少なくとも部分的に基づいて決定される。
【０１３９】
ハイパーカーネルは、メモリが移動されるべきであると決定した場合、その現行のリソースマップを用いて、どのノードが必要とされるメモリを保持する可能性があるかを判定し、そのノードへメッセージを送信して、リソースを要求する。ハイパーカーネルは、さらに、継続を作成し、そのイベントテーブルにその継続を配置する。したがって、工程８０２においてブロックされたハイパースレッドは、他の作業を引き受けるために解放され、ａｓｓｉｇｎＰｒｏｃｅｓｓｏｒルーチンを用いて別の仮想プロセッサに割り当てられうる。
【０１４０】
ハイパーカーネルは、優先度の高さに基づいて、そのメッセージキューをチェックする。ハイパーカーネルが、自身の接触したノード（すなわち、「第１接触ノード」）からメッセージを受信すると、いくつかの実施形態において、２つの応答の内の１つが受信される。応答は、第１接触ノードが、必要とされるリソースを有することを示唆してよい（そして、リソースを提供してよい）あるいは、メッセージは、接触ノードが（例えば、そのノードがリソースを別のノードに提供したために）リソースをもはや持たないことを示唆してもよい。後者の状況において、第１接触ノードは、それがリソースを送信する送信先のノード（すなわち、「第２ノード」）のＩＤを提供し、ハイパーカーネルは、リソースを要求する第２メッセージを、この例では第２ノードに送信できる。様々な実施形態において、第２ノードが、自身もリソースを持たないこと（例えば、第３ノードに提供したこと）をハイパーカーネルに報告した場合、ハイパーカーネルは、リソースを要求し続けるのではなく、第３ノードに継続を送信することを選んでよい。継続を送信するか、リソースを継続するかを決定する際に、他の閾値を用いてもよい（例えば、４回の試行）。さらに、リソースを要求するか、継続を送信するかを決定する際に、様々な基準を用いてよい（例えば、コスト関数に従う）。
【０１４１】
ハイパーカーネルは、継続が転送されるべきである（すなわち、ローカルにリソースを受信するのではなく、計算が別のノードに送信されるべきである）と決定した場合、リモートノード（すなわち、必要とされるリソースを持つノード）に、リモートノードがそれ自身の物理アドレス空間内に継続を構築するために利用できる情報を提供する。リモートノード（すなわち、継続を受信するノード）が、自身の必要とするリソースすべてを有する（すなわち、最初のアクセス違反を引き起こしたリソースを保有する）場合、継続は、遠隔ノードのイベントテーブルに配置される必要はなく、その代わりにタイダルツリーに配置されてよい。リモートノードが、継続を処理するためにさらなるリソースを必要とする場合、受信された継続は、遠隔ノードのイベントテーブル内に配置される。
【０１４２】
図９は、階層的な動的スケジューリングを実行するための処理の一実施形態を示す。いくつかの実施形態において、処理９００は、ａｓｓｉｇｎＰｒｏｃｅｓｓｏｒルーチンと共に実行されるなど、ハイパーカーネルによって実行される。処理は、ハイパースレッドが割り当てられるべきである旨の示唆が受信される工程９０２で始まる。処理９００は、複数の方法で呼び出されうる。一例として、処理９００は、ハイパースレッドが利用可能である（すなわち、実行すべき現在の作業を持たない）時に呼び出されうる。これは、例えば、継続がなされるべきであるとハイパーカーネルが（例えば、工程８０４において）決定した時に、起こりうる。以前にブロックされたハイパースレッドは、ブロックの対象となった計算を処理する責任がもはやない（すなわち、ハイパースレッドが「匿名のシャドープロセッサ」になる）ので、利用可能になる。第２の例として、処理９００は、以前には利用不可能であったリソースが現在は利用可能である旨のメッセージが（例えば、ハイパーカーネルによって）受信された時に呼び出されうる。ハイパーカーネルは、リソースを必要としていた計算を再開するために、ハイパースレッドをロケートする必要がある。もともとリソースの不足によってブロックされていたハイパースレッドが、リソースの受信後に計算を再開するハイパースレッドである必要はないことに注意されたい。
【０１４３】
工程９０４では、タイダルツリーにおいて、実行の準備が整っている継続が検索され、ハイパースレッドが再開すべきものとして、１つの継続が選択される。様々な実施形態において、タイダルツリーは、リーフレベルから上向きに検索され、コスト関数が、ハイパースレッドにどの継続を割り当てるのかを決定するために用いられる。一例として、ハイパースレッドが利用可能になった時に、最も長い時間にわたってキューに入れられていた継続が、割り当てられうる。リーフレベルに待機中の継続がない場合、または、コスト関数によって指定された閾値外にある場合、ハイパースレッドに割り当てるべき適切な継続が、タイダルツリーで検索される（例えば、コアレベル、次に、ソケットレベル、次に、ノードレベルで）。ハイパースレッドがノードレベルで再開するのに適切な継続が見つからなかった場合、そのノードのハイパーカーネルは、ルートに接触する。ノードレベルで継続が見つからない１つの典型的な理由は、そのノードが完全に利用されるのに十分な作業がないことである。いくつかの実施形態において、ノードまたはノードの一部は、エネルギ節約状態に入りうる。
【０１４４】
時系列
【０１４５】
説明のために、例においては、「スワップ」動作が、継続およびメモリの移動に用いられるが、実際には、これは、すべての実施形態で必要なことでない。
【０１４６】
図１０は、初期のメモリ割り当ておよびプロセッサ割り当ての一例を示す。具体的には、図１０の領域１００２は、メモリの物理ブロック（左側）と、メモリの現在のオーナー（中央列）との間のハイパーカーネルのマッピングを示す。右の列は、メモリの以前のオーナーを示す。これは初期のメモリ割り当てであるため、現在および直前のオーナー列は、同じ値を保持する。図１０の領域１００４は、システム仮想プロセッサ（左側）と、物理ノード（中央列）／コア番号（右列）との間のハイパーカーネルのマッピングを示す。
【０１４７】
仮想プロセッサＰ００が位置８ＦＦＦＦを読み出すためにメモリ要求し、ハイパーカーネルがＰ００と同じノード（すなわち、ノード０）へ８ＦＦＦＦを含む１または複数のメモリブロックを移動することを決定すると仮定する。ブロック８ＦＦＦは、ノード２に位置する。したがって、図１１に示すように、８ＦＦＦＦを含むブロックは、ノード０に移され、別のブロックが、（排除が必要であり、ブロックが有効である場合には）スワップアウトされる。
【０１４８】
次に、仮想プロセッサＰ０６が位置８１ＦＦＦを読み出すためにメモリ要求をすると仮定する。このブロックのコンテンツは、ノード０に（図１１に示すように）移動されている。ハイパーカーネルは、メモリを再び移動させるのではなく、計算が移動されるべきであると決定してよい。したがって、図１２に示すように、仮想プロセッサＰ０６は、ノード０に移動され、仮想プロセッサＰ０１とスワップされてよい。
【０１４９】
パフォーマンス情報
【０１５０】
ロックおよびその他の同期装置
【０１５１】
様々な実施形態において、ロックのような同期メカニズムの利用が最小限である。例えば、ロックは、スケジューラオブジェクト上でキューの挿入およびキュー継続の除去を行うため、および、イベントテーブルを維持するために用いられる。
【０１５２】
コードパス長
【０１５３】
いくつかの実施形態において、すべてのコードパスの（最大）長は、静的コード解析を通して決定され、その結果、ハイパーカーネル自体で費やされる評価可能な有界の時間が得られる。すべてのデータ構造が、例えば、インデックス付きの配列として、事前に割り当てられうる。タイダルツリーのノードは、起動時に決定され、それらのトラバースの際のステップ数と同様に、不変である。１つの可変長計算が、作業キューの長さと関連があるが、それすら有界でありえ、最悪ケース推定値が計算されうる。別の実施形態では、その他の可変長計算が用いられる。
【０１５４】
スタティックストレージ
【０１５５】
様々な実施形態において、ハイパーカーネルで必要とされるすべてのデータ構造が静的であり、起動時に決定されるので、動的メモリ割り当てまたはガベージコレクションの必要性はない。
【０１５６】
物理メモリ
【０１５７】
ハイパーカーネルによって用いられるすべてのメモリが物理メモリであるので、内部動作に必要なページテーブルも仮想メモリもなく（例えば、それが管理している仮想リソースの管理を除く）、さらに、ハイパーカーネルがオペレーティングシステムと共存するのを助ける。
【０１５８】
データの共有と整合性の維持
【０１５９】
一部の例において、例えば、オペレーティングシステムに提示される仮想マシンの概念的統合性を保つために、あるノードのデータ構造の変化が、別のノードの対応する変化と協調される。本明細書に記載のデータ構造の多くは、「ノードローカル」であり、移動する必要がないか、または、不変であり複製される。ノードローカルであるデータ構造は、ノード上のすべてのハイパースレッドに可視であり、それらによってアドレス可能である。ノードローカルではない（したがって、協調を必要とする）データ構造の例は、現在のリソースマップ（またはその一部）と、タイダルツリーのルートと、移動する継続（すなわち、或るノードから別のノードへ論理的に移動する必要がありうる継続）と、を含む。
【０１６０】
様々な技術が、十分な程度の整合性を維持するために用いられてよい。一部の技術は同期的であり、すべての変化がすべてのノードにとって同時に可視的になること（すなわち、「即時整合性」）を仮定する。他の技術は、より緩和されたソリューションを可能にし、「結果整合性」を追求する。上述のように、企業のスーパーコンピュータの物理ノードは、１または複数の高速相互接続を介して接続されている。ハイパーカーネルの複数のインスタンスが、物理ノード間でメッセージおよびリソースをやり取りするために相互接続される。
【０１６１】
現行のリソースマップの更新
【０１６２】
各物理ノードｎは、物理リソースマップの同じコピー、初期の仮想リソースマップ、および、現行のリソースマップから（例えば、起動時に）開始する。各ノードは、現行のリソースマップの独自のコピーを維持する。
【０１６３】
いくつかの実施形態において、現行のリソースマップ内のリソースｒの各エントリは、以下を有する。
【０１６４】
１．ローカルロック。その結果、物理ノード上の複数のハイパースレッドが同時にｒを修正できなくなる
【０１６５】
２．現在リソースを所有するノードを特定するノード番号
【０１６６】
３．最後にｒを所有していた時から要求された回数ｎのカウントｋ
【０１６７】
４．設定された場合に、このノードｎがｒを求めることを示すブーリアン
【０１６８】
５．設定された場合に、このノードがｒを有するが移送の途中であることを示すブールであり、この場合、ノード番号が新しいオーナーを特定する
【０１６９】
いくつかの実施形態において、カウントｋは、限りないリソースの追求に対処するために用いられる。ｋが閾値を超えた場合、システム周囲のリソースを追求するのではなく、新たに構築された継続を移動させる方がよいという決定がなされる。
【０１７０】
以下は、リソースのマイグレーションを開始してリソースを受信するためのメカニズムの一例である。重要なトランザクションは以下を含む。
【０１７１】
１．ノードｎが、リソースｒの要求をｎ’に送信する。
【０１７２】
２．ノードｎ’は、リソースｒの要求をｎから受信する。
【０１７３】
３．ノードｎ’は、特定の状況下でｎに「拒否」メッセージを送信してよく、そうでなければ、「受け入れ」ることができ、リソースｒを送信する。
【０１７４】
４．ノードｎは、リソースｒがこの時点でｎ’によって送信不能である場合、ｎ’から「拒否」メッセージを受信する。ｒがｎ’によって必要とされているか、または、要求の到着時にｒがどこか他の場所に移送されている場合がありうる。要求が拒否された場合、ｎ’は、リソースを移送する先のノードの「移送先」アドレスを送信できる。移送先アドレスがｎ’自体である場合があり、これは、「後に再試行する」ことと等価である。ノードｎは、拒否メッセージを受信すると、ｎ’によって示唆されたノード（しばしば、リソースの新しいオーナー）へ要求を再送信できる。ｎがシステム周囲のリソースを追求することを避けるために、ｎは、リソースを得るための試行の回数を記録することができ、試行の回数が閾値を超えると戦略を切り替える。
【０１７５】
５．ノードｎは、ｎ’がリソースを送信できる場合、リソースｒを受信する。この場合、ｎは、ｃが再開されうるように、ｒを待っていた継続ｃをスケジューリングする必要がある。
【０１７６】
タイダルツリーのルート
【０１７７】
いくつかの実施形態において、システム内のノードセットの内の１つの物理ノードが、「マスタノード」に指定される。このノードは、起動時に、初期仮想リソースマップおよびその他のデータ構造を構築し、他のノードにそれらを複製し、オペレーティングシステム（例えば、Ｌｉｎｕｘ）を起動する責任を有する。マスタノードは、１つの例外を除いて、システムが起動された後には任意の他のノードと同様でありうる。少なくとも１つの物理ノードが、タイダルツリーのルートを格納する必要がある。マスタノードは、ルートが配置されうる場所の一例である。タイダルツリールートスケジューリングオブジェクトのイベントキューの更新が、更新を実行するためにマスタノードへメッセージを送信することによって、各ノードにおいて処理される。
【０１７８】
時間と共に、オペレーティングシステムおよびアプリケーションのリソースアクセスパターンが許す場合には、ハイパーカーネルが適合され、ローカル性が連続的に改善する。
【０１７９】
継続
【０１８０】
上述のように、全ノードにわたる物理メモリアドレスは一意的ではない。いくつかの実施形態において、継続内に物理メモリアドレスを含めることは、パーティション整数インデックスを用いてハイパーカーネル内の重要なデータ構造を指定することによって避けることができる。アドレスが継続内に入れられる必要がある場合、そのアドレスは、ソースの物理アドレスであり、宛先における物理アドレスとの関係性がないので、移動に注意が払われる。継続の移動は、上述のように宛先ノードにそのコンテンツをコピーして、ソースからターゲットへ任意の物理アドレスを再マッピングすることを意味する。
【０１８１】
タイムスタンプ
【０１８２】
いくつかの実施形態では、フリーランニングカウンタへのアクセスが、すべてのノードに可視である。これがない場合、各ノード上のフリーランニングカウンタも利用できる。継続内のカウンタが、ソースと宛先との間でマッピングされる。
【０１８３】
ディスクおよび永続性フラッシュの取り扱い
【０１８４】
必要とされるリソースがディスク（または永続性フラッシュ）上にある場合、いくつかの実施形態において、かかるリソースは、ＲＡＭなどのリソースよりも重い重力場を有するものとして扱われる。したがって、ディスク／フラッシュリソースは、あまり頻繁には移行しない傾向にある。その代わり、継続が、需要に基づいて、必要とされる永続性ストレージを含む物理ノードへ、または、永続性ストレージに関連するバッファへ、より頻繁に移行する。
【０１８５】
オペレーティングシステム構成
【０１８６】
オペレーティングシステムを構成する多くの方法がある。サーバについて、そのオペレーティングシステムが、ハイパーカーネルによって実装された仮想マシンから小さいセットのリソースタイプ、線形ブロック配列、ネットワーク、プロセッサ、メモリ、および、ノード間相互接続を含むストレージ、のみを必要とするよう構成されていると仮定できる。結果として、オペレーティングシステムのインストールの複雑さを軽減できる。
【０１８７】
データ構造および関数の例
【０１８８】
以下のセクションは、様々な実施形態で用いられるデータ構造および関数の例のリストを提供する。
【０１８９】
ｉｎｉｔ−ｃｏｎｔｉｎｕａｔｉｏｎ：計算がストールした時に、継続を開始する。
【０１９０】
ａｓｓｉｇｎＰｒｏｃｅｓｓｏｒ：（可能であれば）シャドープロセッサに新たな継続を割り当てるルーチン。
【０１９１】
ｏｎ−ｓｔａｌｌ（ｒ）：リソースｒについてストールイベントが起きる。
【０１９２】
ｍｉｇｒａｔｅ−ｃｏｍｐｕｔａｔｉｏｎ（ｃｏｍｐｕｔａｔｉｏｎａｌ−ｓｔａｔｅ，ｒ，ｎ）：リソースｒを有すると期待する別のノードｎへの計算状態の移動を要求するためのメッセージ。
【０１９３】
ｏｎ−ｉｎｔｅｒｒｕｐｔ（ｉ）：ソフトウェア割り込みｉが起きる。
【０１９４】
ｈａｎｄｌｅ−ｅｖｅｎｔ（ｅ）：ハイパーカーネルが非同期的イベントを処理するよう要求された時に実行されるルーチン。
【０１９５】
ｒｅｑｕｅｓｔ−ｒｅｓｏｕｒｃｅ（ｒ，ｎ）：ノードｎからのリソースｒの移送を要求する。
【０１９６】
ｉｎｉｔｉａｔｅ−ｓｅｎｄ−ｒｅｓｏｕｒｃｅ（ｒ，ｎ）：ノードｎへのリソースｒの送信を開始する。
【０１９７】
ｏｎ−ｒｅｑｕｅｓｔ−ｔｒａｎｓｆｅｒ−ｒｅｓｐｏｎｓｅ（ｒ，ｎ，ｂ）：ｎからのｒの移送要求が受け入れられたか拒否されたか。拒否された場合、ｂはｔｒｕｅである。
【０１９８】
ｏｎ−ｔｒａｎｓｆｅｒ−ｒｅｑｕｅｓｔｅｄ（ｒ，ｍ）：ｍからのリソースｒに対する要求を受信する。
【０１９９】
ｏｎ−ｒｅｓｏｕｒｃｅ−ｔｒａｎｓｆｅｒｒｅｄ（ｒ，ｎ）：リソースｒの肯定応答がｎから受信された。
【０２００】
ｏｎ−ｒｅｃｅｉｖｅ−ｒｅｓｏｕｒｃｅ（ｒ，ｎ）：リソースｒがｎから受信された。
【０２０１】
ｍｉｇｒａｔｉｏｎ−ｃｏｎｔｉｎｕａｔｉｏｎ（ｒ）：リソースの移動よりも継続の移動の方が良い場合かつその場合に限り、ｔｒｕｅになる。
【０２０２】
ｐａｒｅｎｔ（ｓ）：スケジューラオブジェクトｓの親スケジューラオブジェクトを返す。
【０２０３】
ｃｏｓｔ（ｓ，ｃ）：スケジューラオブジェクトｓの待機キュー内の継続ｃの配置を評価するために用いられる。
【０２０４】
ｆｉｎｄ−ｂｅｓｔ−ｗｉｔｈｉｎ（ｓ）：スケジューラオブジェクトｓの待機キューに格納された継続を返すコスト関数。
【０２０５】
ｃｏｎｓｅｒｖｅ−ｅｎｅｒｇｙ：低電力モードに入る。
【０２０６】
ｒｅｓｕｍｅ−ｃｏｎｔｉｎｕａｔｉｏｎ（ｃ）：その時点でこの関数を実行しているプロセッサ内のｃによって表された計算を再開する。
【０２０７】
ｖａｌｉｄ（ｉ）：割り込みｉがまだ有効である場合かつその場合に限り、ｔｒｕｅを戻すブール関数。
【０２０８】
ｉｎｉｔｉａｌｉｚｅ（ｂｅｓｔ−ｇｕｅｓｓ）：コスト変数の最良推定を開始する。
【０２０９】
ｉｎｓｅｒｔ−ｑｕｅｕｅ（ｓ，ｃ）：スケジューラオブジェクトｓの待機キューに継続ｃを挿入する。
【０２１０】
ｒｅｔｕｒｎ−ｆｒｏｍ−ｖｉｒｔｕａｌ−ｉｎｔｅｒｒｕｐｔ：割り込みにより一時的に停止された実行を再開する。
【０２１１】
ｒ．ｏｗｎｅｒ：リソースｒがローカルであるノードを返す。
【０２１２】
ｒ．ｅ：リソースｒがこのイベントを待っている。
【０２１３】
ｅ．ｒ：このイベントはリソースｒのためのものである。
【０２１４】
ｅ．ｃｏｎｔｉｎｕａｔｉｏｎ：このイベントが起きると、継続を再開する必要がある。
【０２１５】
ｇｅｔ−ｓｔａｔｅ（）：プロセッサの状態を返す。
【０２１６】
ｓｃｈｅｄｕｌｅｒ−ｏｂｊｅｃｔ（ｐ）：プロセッサｐと現在関連しているスケジューラオブジェクトを返す。
【０２１７】
ｏｎ-ｒｅｑｕｅｓｔ−ｔｒａｎｓｆｅｒ−ｒｅｓｐｏｎｓｅ（ｒ，ｍ，  ｒｅｓｐｏｎｓｅ）：リソースｒをノードｍから移送する要求への応答。応答は、「拒否される」場合のｔｒｕｅ、または、「受け入れられる」場合のｆａｌｓｅのいずれかでありうる。
【０２１８】
ルーチンの例
【０２１９】
以下は、様々な実施形態で用いられるルーチンの擬似コードの例である。以下では、「ｏｎ−」で始まる関数は、非同期的イベントまたは入ってくるメッセージである。
【０２２０】
＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝
【０２２１】
ｉｎｉｔ−ｃｏｎｔｉｎｕａｔｉｏｎ（ｃｏｍｐｕｔａｔｉｏｎａｌ−ｓｔａｔｅ）
【０２２２】
＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝
【０２２３】
／＊ヒントｈを持つリソースｒを待っているプロセッサｐによるＩｎｉｔＣｏｎｔｉｎｕａｔｉｏｎ＊／
【０２２４】
ｃ＝ａｌｌｏｃａｔｅ  ｃｏｎｔｉｎｕａｔｉｏｎ
【０２２５】
ｃ．ｓｔａｔｅ＝ｃｏｍｐｕｔａｔｉｏｎａｌ−ｓｔａｔｅ
【０２２６】
ｃ．ｌａｓｔ＝ｓｃｈｅｄｕｌｅｒ−ｏｂｊｅｃｔ（ｐ）
【０２２７】
ｃ．ｓｔａｔｅ＝ｗａｉｔｉｎｇ−ｆｏｒ−ｅｖｅｎｔ
【０２２８】
ｃ．ｈｉｎｔｓ＝ｈ
【０２２９】
ｅ＝ａｌｌｏｃａｔｅ  ｅｖｅｎｔ  ｉｎ  ｅｖｅｎｔ−ｔａｂｌｅ
【０２３０】
ｅ．ｒｅｓｏｕｒｃｅ＝ｒ
【０２３１】
ｅ．ｃｏｎｔｉｎｕａｔｉｏｎ＝ｃ
【０２３２】
ｒｅｔｕｒｎ  ｃ
【０２３３】
ｅｎｄ  ＩｎｉｔＣｏｎｔｉｎｕａｔｉｏｎ
【０２３４】
＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝
【０２３５】
ａｓｓｉｇｎＰｒｏｃｅｓｓｏｒ
【０２３６】
＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝
【０２３７】
／＊物理ノードｎ内のプロセッサｐがシャドープロセッサになると、そのＯ／Ｓのアイデンティティを放棄し、実行を再開するための継続を探し始める。ｐは、以下のように待機キューでかかる継続を探す：＊／
【０２３８】
ｓ＝ｓｃｈｅｄｕｌｅｒ−ｏｂｊｅｃｔ（ｐ）
【０２３９】
ｉｎｉｔｉａｌｉｚｅ（ｂｅｓｔ−ｇｕｅｓｓ）
【０２４０】
ｂｅｓｔ−ｓ＝ｎｉｌ
【０２４１】
／＊上方へトラバースして、最良の候補を追跡する＊／
【０２４２】
／＊ルートのローカルにキャッシュされたコピーがあると仮定する＊／
【０２４３】
ｒｅｐｅａｔ
【０２４４】
ｇｕｅｓｓ＝ｃｏｓｔ（ｓ）
【０２４５】
ｉｆ  ｇｕｅｓｓ＞ｂｅｓｔ−ｇｕｅｓｓ
【０２４６】
ｔｈｅｎ
【０２４７】
ｂｅｓｔ−ｇｕｅｓｓ＝ｇｕｅｓｓ
【０２４８】
ｂｅｓｔ−ｓ＝ｓ
【０２４９】
ｓ＝ｐａｒｅｎｔ（ｓ）
【０２５０】
ｕｎｔｉｌ  ｓ＝ｎｉｌ
【０２５１】
ｉｆ  ｂｅｓｔ−ｓ＜＞ｎｉｌ
【０２５２】
ｔｈｅｎ
【０２５３】
ｃ＝ｆｉｎｄ−ｂｅｓｔ−ｗｉｔｈｉｎ（ｂｅｓｔ−ｓ）
【０２５４】
ｒｅｓｕｍｅ−ｃｏｎｔｉｎｕａｔｉｏｎ（ｃ）
【０２５５】
ｅｌｓｅ  ｃｏｎｓｅｒｖｅ−ｅｎｅｒｇｙ
【０２５６】
ｅｎｄ  ａｓｓｉｇｎＰｒｏｃｅｓｓｏｒ
【０２５７】
＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝
【０２５８】
ｏｎ−ｓｔａｌｌ（ｒ）
【０２５９】
＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝
【０２６０】
／＊ＯｎＳｔａｌｌは、ハードウェアが仮想構成と物理構成との間の不一致を検出した時に呼び出される。より具体的には、ハードウェアがノードｎ上で見つけることができないリソースｒを、ノードｎが要求する。＊／
【０２６１】
ｉｆ  ｍｉｇｒａｔｉｏｎ−ｃｏｎｔｉｎｕａｔｉｏｎ（ｒ）
【０２６２】
ｔｈｅｎ
【０２６３】
／＊ノードｎに計算を送信する＊／
【０２６４】
ｎｎ＝ｏｗｎｅｒ（ｒ）
【０２６５】
／＊ノードｎは、リソースがおそらくノードｎｎにあると考える＊／
【０２６６】
ｍｉｇｒａｔｅ−ｃｏｍｐｕｔａｔｉｏｎ（ｒ，ｎｎ）
【０２６７】
ｅｌｓｅ
【０２６８】
／＊リソースｒを要求する＊／
【０２６９】
ｃ＝ｉｎｉｔ−ｃｏｎｔｉｎｕａｔｉｏｎ（ｇｅｔ−ｓｔａｔｅ（））
【０２７０】
／＊ローカルイベントテーブルにｃを挿入するためのコードをここに挿入する＊／
【０２７１】
ｒｅｑｕｅｓｔ−ｒｅｓｏｕｒｃｅ（ｒ，ｏｗｎｅｒ（ｒ））
【０２７２】
ａｓｓｉｇｎＰｒｏｃｅｓｓｏｒ／＊この時点で、ｐは匿名のシャドープロセッサである＊／
【０２７３】
／＊ｐは、実行すべき何らかの作業を見つける必要がある＊／
【０２７４】
ｅｎｄ  ＯｎＳｔａｌｌ
【０２７５】
＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝
【０２７６】
ｏｎ−ｍｉｇｒａｔｅ−ｃｏｍｐｕｔａｔｉｏｎ（ｃｏｍｐｕｔａｔｉｏｎａｌ−ｓｔａｔｅ，ｒ，ｎ）
【０２７７】
＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝
【０２７８】
／＊  リモートノードは、継続を受信するためのメッセージをｎから得る。注：この場合のｃは、継続のコンテンツであり、継続自体ではない。＊／
【０２７９】
ｃ＝ＩｎｉｔＣｏｎｔｉｎｕａｔｉｏｎ／＊要求内の情報を用いる＊／
【０２８０】
ｃ．ｓｔａｔｅ＝ｃｏｍｐｕｔａｔｉｏｎａｌ−ｓｔａｔｅ
【０２８１】
ｅ＝ｉｎｓｅｒｔ  ｃ  ｉｎｔｏ  ｔｈｅ  ｌｏｃａｌ  ｅｖｅｎｔ−ｔａｂｌｅ
【０２８２】
ｈａｎｄｌｅ−ｅｖｅｎｔ（ｅ）
【０２８３】
ｅｎｄ  ｏｎ−ｍｉｇｒａｔｅ−ｃｏｍｐｕｔａｔｉｏｎ
【０２８４】
＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝
【０２８５】
ｏｎ−ｉｎｔｅｒｒｕｐｔ（ｉ）
【０２８６】
＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝
【０２８７】
／＊（物理ノードｎのサブツリー内の）プロセッサｐが（特定のハードウェア設計に特有の非常に低レベルのメカニズムを用いて）ｉによって割り込まれた時、ｐは、以下の通りにする：＊／
【０２８８】
ｗｈｉｌｅ  ｖａｌｉｄ（ｉ）
【０２８９】
ｅ＝ｅｖｅｎｔ−ｔａｂｌｅ（ｉ）／＊ｉに対応するイベントを見つける＊／
【０２９０】
ｈａｎｄｌｅ−ｅｖｅｎｔ（ｅ）
【０２９１】
ｉ＝ｎｅｘｔ−ｑｕｅｕｅｄ−ｉｎｔｅｒｒｕｐｔ
【０２９２】
ｅｎｄ  ｗｈｉｌｅ
【０２９３】
／＊前の実行を再開する＊／
【０２９４】
ｒｅｔｕｒｎ−ｆｒｏｍ−ｖｉｒｔｕａｌ−ｉｎｔｅｒｒｕｐｔ：
【０２９５】
ｅｎｄ  ｏｎ−ｉｎｔｅｒｒｕｐｔ
【０２９６】
＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝
【０２９７】
ｈａｎｄｌｅ−ｅｖｅｎｔ（ｅ）
【０２９８】
＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝
【０２９９】
／＊イベントが発生した。イベントテーブルから最良のスケジューラオブジェクトへそのイベントを移動させる。＊／
【０３００】
ｃ＝ｅ．ｃｏｎｔｉｎｕａｔｉｏｎ／＊イベントｅのための継続を見つける＊／
【０３０１】
ｅｖｅｎｔ−ｔａｂｌｅ（ｉ）．ｃｌｅａｒ＝ｔｒｕｅ／＊テーブルからイベントを除去する＊／
【０３０２】
ｅ．ｃｏｍｐｌｅｔｅ＝ｔｒｕｅ／＊ｅを完了としてマークする＊／
【０３０３】
ｃ．ｓｔａｔｅ＝ｒｅａｄｙ
【０３０４】
／＊ここで、ｃを置くのに最良の場所を見つける＊／
【０３０５】
ｓ＝ｃ．ｌａｓｔ
【０３０６】
ｉｎｉｔｉａｌｉｚｅ（ｂｅｓｔ−ｇｕｅｓｓ）
【０３０７】
／＊最良の選択を探す＊／
【０３０８】
／＊ルートのローカルにキャッシュされたコピーがあると仮定する＊／
【０３０９】
ｒｅｐｅａｔ
【０３１０】
ｇｕｅｓｓ＝ｃｏｓｔ（ｓ，ｃ）
【０３１１】
ｉｆ  ｇｕｅｓｓ＞ｂｅｓｔ−ｇｕｅｓｓ
【０３１２】
ｔｈｅｎ
【０３１３】
ｂｅｓｔ−ｇｕｅｓｓ＝ｇｕｅｓｓ
【０３１４】
ｂｅｓｔ−ｓ＝ｓ
【０３１５】
ｓ＝ｐａｒｅｎｔ（ｓ）
【０３１６】
ｕｎｔｉｌ  ｓ＝ｎｉｌ
【０３１７】
ｉｎｓｅｒｔ−ｑｕｅｕｅ（ｂｅｓｔ−ｓ，ｃ）／＊最良のｓの待機キューにｃを入れる＊／
【０３１８】
ｅｎｄ  ｈａｎｄｌｅ−ｅｖｅｎｔ
【０３１９】
＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝
【０３２０】
ｒｅｑｕｅｓｔ−ｒｅｓｏｕｒｃｅ（ｒ，ｎ）
【０３２１】
＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝
【０３２２】
／＊ノードｎが、ノードｎ’によって所有されるリソースｒを必要とする場合、そのリソースは要求されるが、他の誰かが先を越して要求した可能性があるか、または、ｎ’が現在それを利用しているために、その要求は満たされない場合がある。＊／
【０３２３】
ｃｕｒｒｅｎｔ−ｒｅｓｏｕｒｃｅ−ｍａｐ（ｒ）．ｗａｎｔｅｄ＝ｔｒｕｅ
【０３２４】
ｒｅｑｕｅｓｔ−ｔｒａｎｓｆｅｒ（ｏｗｎｅｒ（ｒ），ｒ）／＊ｒのオーナーに要求を送信する＊／
【０３２５】
／＊ｒの移送を要求する＊／
【０３２６】
ｒｅｔｕｒｎ
【０３２７】
＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝
【０３２８】
ｏｎ−ｒｅｑｕｅｓｔ−ｔｒａｎｓｆｅｒ−ｒｅｓｐｏｎｓｅ（ｒ，ｍ，ｉｓ−ｒｅｊｅｃｔｅｄ）
【０３２９】
＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝
【０３３０】
／＊ここで、あなたがリソースｒについてのノードへの以前の要求からの応答を得るノードであることを考慮する。この要求への応答が来ると、それは、受け入れられるかまたは拒否されうる。＊／
【０３３１】
ｉｆ  ｉｓ−ｒｅｊｅｃｔｅｄ
【０３３２】
ｔｈｅｎ／＊リソースがｍに移送された＊／
【０３３３】
ｉｎｃｒｅｍｅｎｔ  ｋ
【０３３４】
ｉｆ  ｋ＞ｔｈｒｅｓｈｏｌｄ
【０３３５】
ｔｈｅｎ
【０３３６】
／＊  あなたは永久に追求したいとは思わない＊／
【０３３７】
／＊  リソースを得ようとする。諦める＊／
【０３３８】
ｍｉｇｒａｔｅ−ｃｏｍｐｕｔａｔｉｏｎ（ｒ，ｍ）
【０３３９】
ｒｅｔｕｒｎ
【０３４０】
ｅｌｓｅ
【０３４１】
ｒｅｑｕｅｓｔ−ｔｒａｎｓｆｅｒ（ｒ，ｍ）／＊再試行する＊／
【０３４２】
ｒｅｔｕｒｎ
【０３４３】
ｅｌｓｅ
【０３４４】
／＊要求が拒否されなかった。ｒはリソースである  ＊／
【０３４５】
ｒ．ｋ＝０
【０３４６】
ｒ．ｗａｎｔｅｄ＝ｆａｌｓｅ／＊リソースが移動された＊／
【０３４７】
ｒ．ｏｗｎｅｒ＝ｍｅ／＊オーナーをｎ（すなわち、「私」）に設定する＊／
【０３４８】
ｉｆ  ｔｈｅ  ｒｅｓｏｕｒｃｅ  ｉｓ  ｍｅｍｏｒｙ，
【０３４９】
ｕｐｄａｔｅ  ｔｈｅ  ｈａｒｄｗａｒｅ  ｍｅｍｏｒｙ  ｍａｐ  ｗｉｔｈ  ｔｈｅ  ｎｅｗ  ｍｅｍｏｒｙ
【０３５０】
ｒｅｔｕｒｎ
【０３５１】
＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝
【０３５２】
ｏｎ−ｔｒａｎｓｆｅｒ−ｒｅｑｕｅｓｔｅｄ（ｒ，ｎ）
【０３５３】
＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝
【０３５４】
／＊ｒへのリソース要求がノードｎから来た時、オーナー（ｒ）にとって移送が進行中であれば、要求を拒否する＊／
【０３５５】
ｉｆ  ｒ．ｂｅｉｎｇ−ｔｒａｎｓｆｅｒｒｅｄ
【０３５６】
ｔｈｅｎ
【０３５７】
ｓｅｎｄ−ｒｅｑｕｅｓｔ−ｒｅｓｐｏｎｓｅ（ｒ，ｏｗｎｅｒ（ｒ），ｔｒｕｅ）
【０３５８】
ｅｌｓｅ
【０３５９】
／＊リソースの移送が受け入れられる＊／
【０３６０】
ｒ．ｔｒａｎｓｆｅｒｒｉｎｇ＝ｔｒｕｅ
【０３６１】
ｉｎｉｔｉａｔｅ−ｓｅｎｄ−ｒｅｓｏｕｒｃｅ（ｒ）
【０３６２】
ｉｆ  ｔｙｐｅ（ｒ）＝ｍｅｍｏｒｙ
【０３６３】
ｔｈｅｎ  ｕｐｄａｔｅ  ｌｏｃａｌ  ｍｅｍｏｒｙ  ｍａｐ
【０３６４】
ｓｅｎｄ−ｒｅｑｕｅｓｔ−ｒｅｓｐｏｎｓｅ（ｒ，ｏｗｎｅｒ（ｒ），ｆａｌｓｅ）
【０３６５】
ｒｅｔｕｒｎ
【０３６６】
＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝
【０３６７】
ｏｎ−ｒｅｓｏｕｒｃｅ−ｔｒａｎｓｆｅｒｒｅｄ（ｒ，ｎ）
【０３６８】
＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝
【０３６９】
／＊移送が完了した旨の肯定応答が来た時＊／
【０３７０】
ｒ．ｏｗｎｅｒ＝ｎ
【０３７１】
ｒ．ｔｒａｎｓｆｅｒｒｉｎｇ＝ｆａｌｓｅ
【０３７２】
ｒｅｔｕｒｎ
【０３７３】
＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝
【０３７４】
ｏｎ−ｒｅｃｅｉｖｅ−ｒｅｓｏｕｒｃｅ（ｒ，ｎ）
【０３７５】
＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝
【０３７６】
／＊ここで、要求されたリソースｒを伴うメッセージをｎから受信する＊／
【０３７７】
ｒ．ｋ＝０
【０３７８】
ｒ．ｗａｎｔｅｄ＝ｆａｌｓｅ／＊それが求められていることを示すビットをクリアする＊／
【０３７９】
ｒ．ｏｗｎｅｒ＝ｍｅ／＊オーナーをｎ（すなわち、「私」）に設定する＊／
【０３８０】
ｉｆ  ｔｈｅ  ｒｅｓｏｕｒｃｅ  ｉｓ  ｍｅｍｏｒｙ，
【０３８１】
ｕｐｄａｔｅ  ｔｈｅ  ｍｅｍｏｒｙ  ｍａｐ  ｗｉｔｈ  ｔｈｅ  ｎｅｗ  ｍｅｍｏｒｙ
【０３８２】
ｓｅｎｄ−ｒｅｓｏｕｒｃｅ−ｔｒａｎｓｆｅｒｒｅｄ（ｒ，ｎ）
【０３８３】
ｈａｎｄｌｅ−ｅｖｅｎｔ（ｒ．ｅ）／＊待っていたイベントが発生した＊／
【０３８４】
ｒｅｔｕｒｎ
【０３８５】
ワーキングセットおよびスレッドの関連付け
【０３８６】
ここまで、様々な実施形態が、緊密に相互接続された１セットの物理サーバ（またはコンピュータ）にわたって分散された仮想サーバ（またはコンピュータ）のインスタンスを生成、管理、および、最適化する方法が示された様々な実施形態について説明した。
【０３８７】
かかるシステムを効率的に動作させるために、ゲスト物理プロセッサ（ｖｃｐｕ）のセットが、メモリの仮想ページ（ゲストオペレーティングシステムが物理ページであると考えるメモリのゲスト物理ページ）のセットに関連付けられ、その結果、それらは、１セットのコンピュータ（例えば、クラスタ内のノード）にわたって同じ場所に配置されうる。同じ場所に配置されると、マイクロプロセッサ内の仮想化ハードウェアを用いて、ハードウェアベースの非仮想サーバと一致したパフォーマンスレベルを達成することができる。
【０３８８】
ｖｃｐｕによるゲスト物理メモリページのセットへのページアクセスのパターンは、アプリケーションプログラム、オペレーティングシステム、ネットワーク、リアルタイムイベント、Ｉ／Ｏデバイス、などの組みあわせによって規定され、真の仮想サーバが構築された場合には変化しない。
【０３８９】
現代のオペレーティングシステム（Ｌｉｎｕｘ、ＦｒｅｅＢＳＤ、Ｗｉｎｄｏｗｓ、および、ＭａｃＯＳなど）は、「スレッド」と呼ばれる非同期的な制御構造を実施するための１セットの機能を提供する。スレッドは、オペレーティングシステム内のソフトウェア構造およびメカニズムもしくは非同期的かつ並行なプログラムの動作を可能にするランタイムライブラリ（もしくは両方）であり、しばしば、非同期割り込みへの応答を含む。スレッドは、サブプログラムが、異なる時刻に異なるデータアクセスパターンを持つ異なる命令ストリームを実行することを可能にする。本明細書に記載の例において、スレッドは、ゲストオペレーティングシステムにおいて動作するスケジューラの制御下で、１セットの仮想プロセッサにバインドされてよい。任意の所与の時点に、スレッド（例えば、ゲストオペレーティングシステム上で動作するアプリケーションに関連付けられているゲストスレッド）が、ｖｃｐｕ上で動作しているか、または、全く動作していない。その後に、スケジューラは、異なる物理プロセッサ上でそのスレッドを実行すると決定してよい。
【０３９０】
上述のように、仮想環境内のｖｃｐｕが、仮想マシンおよび仮想マシンのスケジューラ（ゲストオペレーティングシステムスケジューラとは異なりうる）の実施中ずっと、真の（「ホスト」とも呼ばれる）物理プロセッサにバインドされてよい。
【０３９１】
現代のオペレーティングシステムは、しばしば、所与の時点にどのスレッドがどのｖｃｐｕで動作しているかに関してハードウェアまたは仮想化システムに情報を提供しうる。
【０３９２】
オペレーティングシステムがシステムのすべてのリソース（例えば、メモリ、Ｉ／Ｏ、ネットワークなど）への直接かつ高速なアクセスを有するという仮定が、オペレーティングシステムによってなされる。本明細書に記載の技術を用いて構築された１セットのノードにわたる単一の仮想マシンにおいて、この仮定はセマンティック的には維持されるが、物理的現実は当てはまらない場合がある。例えば、非ローカルリソースにアクセスする仮想プロセッサ（またはスレッド）が存在する場合があり、ここで、この非ローカルアクセスは、直接アクセスでも高速アクセスでもない。上述のように、仮想化システムが物理的に実現可能ではないゲストからのイベントを観察すると、ストールが引き起こされる。仮想化システムは、ストールを引き起こした状況を修正するかまたは他の方法で対処することで、ゲスト（オペレーティングシステム）によって予測されたセマンティック動作（ｓｅｍａｎｔｉｃ  ｂｅｈａｖｉｏｒ）とその状況を一致させるように動作する。仮想システムのパフォーマンスは、ゲストオペレーティングシステムのベースパフォーマンスによって支配されるが、ストールの数、および、ストールをセマンティック的に正確にするのに掛かる合計時間によって低下しうる。以下に述べる技術を用いると、ストールの数およびストールあたりの平均時間が、仮想化システムにおいて削減されうる。
【０３９３】
ここまでに、仮想プロセッサおよび仮想ページセットの利用パターンを追跡するため、ならびに、仮想プロセッサおよび仮想ページを分散仮想環境を通して移動させることについて決定するための技術の例を記載した。上述の技術は、メモリのページセットにアクセスするスレッドセットのアクセスパターンを追跡するために、改良および拡張もしくは他の方法で適合されてよい。
【０３９４】
スレッドと、メモリの関連ページセットとの追跡は、仮想プロセッサおよびメモリページセットのアクセスのパターンが、実際には、ゲストオペレーティングシステムスケジューラの制御下で仮想プロセッサ内で動作するゲストスレッドによって決定されるという観察に基づきうる。ゲストスレッドは、異なる仮想プロセッサ、したがってホスト物理プロセッサで、異なる時に動作しうる。ｖｃｐｕ、したがってホスト物理プロセッサは、異なる時点に同じゲストスレッドを実行してよい。
【０３９５】
ホスト物理プロセッサへのスレッドのバインディングは、様々な要因に依存し、要因は、ゲストスケジューラのプログラムされた動作、スレッドによって実行される計算、外部の非同期イベントのパターン（ネットワークパケットの到着など）、Ｉ／Ｏ割り込みの完了、などを含みうる。これらのイベント、したがってイベント到着のパターンおよびゲスト物理プロセッサへのゲストスレッドのバインディングは、事前に予測可能ではない場合がある。したがって、システムの動作は、プログラムの実行が決定論的である場合でも、非決定論的でありうる。
【０３９６】
スレッドの検査によって、どのスレッドがどのｖｃｐｕにおいて動作しているのかは知りえない。なぜなら、これは、ゲストオペレーティングシステムまたはゲストランタイムライブラリの制御下にあるからである。しかしながら、後に詳述するように、オペレーティングシステムは、任意の所与の時点にどのスレッドが各仮想プロセッサで実行しているのかを決定するための様々なメカニズム（またはヒント）を提供する。かかる情報は、仮想プロセッサ（ｖｃｐｕ）のための基本的なスケジューリングおよびマイグレーションの決定に用いられてよい。後に詳述するように、本明細書に記載の技術を用いると、（ゲストスレッドを実行する）仮想プロセッサは、できる限り、同じノード上の仮想メモリ（ゲスト物理メモリ）の適切なページセットと共に一緒に維持されうる。そうすることにより、非ローカルアクセスによるストールを削減すると共に、実際の物理コンピュータに匹敵するパフォーマンスレベルを達成できる。さらに、オーバーヘッド（例えば、ストールの回数およびストールあたりの平均時間の積）も小さくなりうる。これは、最もストールしそうにない場所にページおよびスレッドをインテリジェントに配置することによって達成されうる。ページ転送およびページマイグレーションの回数も、最小化されうる。
【０３９７】
読み出される必要があったために、ページがノード上に存在する場合がある。そのページは、書き込まれる必要があったために、ノード上に存在する場合もある。いくつかの実施形態において、複数のノードがすべて、ページを読み出している限りは、それらのノードは、ページのローカルコピーを有しうる。ページが書き込まれる必要がある時、更新／書き込みを行うノード以外のノード上のそのページの全コピーに無効化が実行される。いくつかの実施形態において、更新が完了すると、他のノードは、ページが再び読み込まれる必要があった場合にページのコピーを求めてよい／要求してよい。
【０３９８】
スレッドと参照ページのセットとの間の関係性を管理するための技術について、以下で詳述する。ページｐを所与として、本明細書に記載の技術を用いると、どのスレッドがｐに対する強い必要性を有するのかが決定される。さらに、スレッドｔを所与として、どのページがｔによって強く必要とされるのかが決定される。一例として、スレッドがｖｃｐｕで実行している時、スレッドが実行しているノードに存在しないページを参照しているために、スレッドがストールした場合、ページが到着するまでストールが実行される。ストールは、このスレッドがこのページを必要としていることを示唆するものである。かかる情報は、スレッドが動作しているノードがどれであっても、例えば、ページへのアクセスを得るために所与のスレッドストールの回数の頻度をカウントすることによって記録され、そして、管理されてよい。スレッドによって必要とされると決定されたページは、スレッドに関連するページのワーキングセットに含められる。任意の所与の時点にどのスレッドが各仮想プロセッサを実行しているのかを決定するためのメカニズムまたはヒントをオペレーティングシステムが提供しうるので、スレッドは、スレッドレベルに基づいて追跡または識別されうる。
【０３９９】
図１３Ａは、スレッドおよびワーキングセットが関連付けられた環境の実施形態の一例を示す。以下に記載の技術を用いて、所与のゲストスレッドにとって最も関心のあるページが決定されてよい。仮想システム内の各ゲスト物理ページについて、所与のページに最も関心を持つスレッドが決定されてもよい。以下に記載する実施形態の例は、Ｉｎｔｅｌ仮想化ハードウェア（例えば、Ｉｎｔｅｌ  ＶＴ−ｘ）を含むが、本明細書に記載の技術は、任意のタイプの仮想化ハードウェア（例えば、ＡＭＤ  ＡＭＤ−Ｖ）に対応するよう様々に適合されてよい。
【０４００】
図１３Ａの例では、ゲストアプリケーション１３０２が、ゲストオペレーティングシステム１３０４の上で動作しており、ゲストオペレーティングシステム１３０４は、企業向けスーパーコンピュータ（例えば、システム１００）を形成する一連の個々の物理ノード１３０６にわたって集合的に動作している。より具体的には、ゲストオペレーティングシステムは、図４Ｂに関して説明するように、一群のハイパーカーネルによって定義された仮想環境上で動作している。
【０４０１】
図７に関して上述したように、ゲストオペレーティングシステムの視点から、ゲストオペレーティングシステムには、複数の「仮想化プロセッサ」（本明細書では「仮想プロセッサ」または「ｖｃｐｕ」とも呼ぶ）が見えており、複数の仮想化プロセッサは、企業向けスーパーコンピュータに含まれるすべてのノードにわたるハイパースレッドの総数に対応する。オペレーティングシステムには、すべてのノードにわたる物理メモリの総量に等しいサイズの大型の物理的な線形メモリのように見える「仮想化物理メモリ」（本明細書では「ゲスト物理メモリ」とも呼ぶ）も見える。かかる仮想構成において、ゲストの視点からのすべてのメモリアドレス（本明細書では「ｇｐａ」の「ゲスト物理メモリ」とも呼ぶ）は、（グローバルに）一意的であり、企業向けスーパーコンピュータを形成するノードに含まれるすべてのメモリの合計を表す。ｇｐａは、（ノードに関わらず）クラスタ全体にわたって一意的であり、ここで、ゲスト物理アドレス空間は、ゲストオペレーティングシステム（ゲストＯＳ）によって定義された広いフラットアドレス空間である。
【０４０２】
図１３Ａの例において、ゲストアプリケーション１３０２は、仮想アドレス空間に関連付けられている。例えば、ゲストオペレーティングシステム１３０４がゲストアプリケーション１３０２を立ち上げると、ゲストＯＳは、そのアプリケーションのための仮想アドレス空間を生成（例えば、ページテーブルを設定）する。ゲストアプリケーションが実行されるごとに、新たなページテーブルが生成される。ゲストアプリケーション１３０２は、１セットのスレッドも有する。この例において、ゲストアプリケーション１３０２は、シングルスレッドであり、シングルスレッド１３０８（本明細書では「ゲストスレッド」とも呼ぶ）を有する。他のアプリケーションが、複数のスレッドを有してもよい（すなわち、アプリケーションは、マルチスレッドであってもよい）。この例において、ゲストスレッドは、ｖｃｐｕ上で実行中である。ｖｃｐｕは、企業向けスーパーコンピュータの物理構成におけるハイパースレッドなど、物理ノード上の物理プロセッサ（本明細書では「ｐｃｐｕ」とも呼ぶ）上で動作する。ゲストスレッドは（ｖｃｐｕと同様に）、クラスタにわたってグローバルに一意的である。
【０４０３】
ゲストアプリケーション１３０２が動作している時、ゲストスレッドは、アプリケーションの仮想アドレス空間内の仮想ページへの参照を行う。ゲストアプリケーションによって参照される（そして、計算を継続するためにゲストスレッドによって必要とされる）メモリの物理ページを取得するために、動的アドレス変換の２つのレベルが仮想環境内で実行される。動的変換の２つのレベルは、仮想化をサポートするプロセッサのために仮想化を有効にすることによって自動的に実行される（すなわち、仮想化が有効にされると、アドレスが参照される度に、２段階のアドレス変換が実行される−仮想化システムが実行されていない場合、アドレス変換の第２レベルは実行されない）。
【０４０４】
図１３Ｂは、仮想環境における動的アドレス変換の一例を示す。この例において、アプリケーションレベルでは、ページアドレス変換の第１レベルが、（ゲストオペレーティングシステムによって管理される）第１レベルページテーブル１３１０を用いて内部ｖｃｐｕ状態によって実行され、第１レベルページテーブル１３１０は、（メモリのページのための）仮想メモリアドレス１３１２をゲスト物理アドレス１３１４に変換する。いくつかの実施形態において、第１レベルページテーブルは、様々なエントリを含むメモリのブロックであり、ここで、第１レベルページテーブルは、ゲストオペレーティングシステムによって書き込まれ、ハードウェアによって読み出される。異なるアプリケーションが、２つの異なる仮想アドレス空間内で動作する（そして、ゲストレベルで、各アプリケーションは、それぞれの仮想アドレス空間の各々をゲスト物理メモリ／アドレス空間に対応付ける独自の第１レベルページテーブルを有する）。例えば、仮想メモリアドレスは、対応するゲスト物理アドレスを取得するために、第１レベルページテーブルへのインデックスとして用いられる。したがって、仮想アドレスは、ゲストオペレーティングシステムが「物理アドレス」であると考えるもの（ただし、実際には、ハイパーカーネルの視点からはゲスト物理アドレスである）に変換されている。
【０４０５】
次いで、第１レベルページテーブルのルックアップに応答して返されたゲスト物理アドレス（または、例えば、６４ビット値であってよいｇｐａのブロック）は、メモリの対応する物理ページ（例えば、４Ｋ物理メモリアドレス）を取得するために、物理プロセッサの仮想化ハードウェアによって、第２レベルページテーブル１３１６へのインデックスとして用いられる。第２レベル変換テーブルは、ゲスト物理アドレスを「実」物理アドレス１３１８（クラスタのノードに存在するメモリの実物理ページ）に対応付けるために、ハードウェア内に設定されてよい。ゲストＯＳ上で動作する各アプリケーションは、独自の第１レベルページテーブルを有するが、第２レベルページテーブルは、ゲストオペレーティングシステムが物理メモリであると考えるもののメモリの同じプールの外で動作する。
【０４０６】
第２レベルページテーブルは、各ノードに固有であり、ここで、企業向けスーパーコンピュータ内の各ノードは、対応する第２レベルページテーブルに関連付けられている。各ノードは、その独自の対応する第２レベルページテーブルに関連付けられているが、ページテーブルはすべて、ゲスト物理アドレスを用いて同様にインデックス化されてよく、ゲスト物理アドレスは、上述のように、スーパーコンピュータクラスタにわたってグローバルに一意的である。ゲスト物理アドレスに対応するメモリのページがノード上に存在する場合、ノードの第２レベルページテーブル内に対応するエントリがあることになる。
【０４０７】
図１３Ｃは、第２レベルアドレス変換の実行の実施形態の一例を示す。この例では、第２レベルページテーブル１３１６をインデックス化して、対応する４Ｋ物理メモリアドレス１３１８を取得するために、（後に詳述する）ｖｃｐｕ状態のＣＲ３レジスタに格納されたゲスト物理アドレス（１３１４）が用いられ、アドレス１３１８は、ｖｃｐｕのアイデンティティを担ったｐｃｐｕが存在するノード上の物理メモリ１３２０の実ページを指し示す。この例において、要求されたページは、ノードにローカルであるので、ゲスト物理アドレスに対応する第２レベルページテーブル内に有効なエントリが存在し、その後、実物理メモリのページが、ゲストスレッドによって取得および利用されうる。
【０４０８】
ゲスト物理アドレスに対応するメモリのページがノードにローカルではない場合、ノードの第２レベルページテーブルは、ゲスト物理アドレスのためのエントリを含まない（ここで、例えば、エントリは、ゼロアウトされるか、または、無効化されている）。したがって、参照されたゲスト物理アドレスに対応する実物理ページがノードでローカルに利用可能ではないと判定されうる。ページは、ある時点でノードにあり、ハイパーカーネルによって別のノードにマイグレートされたか（この場合、ページの位置が追跡される）、または、ノード上には全く見られなかったか（例えば、仮想化システムが新たに起動される場合がある）、のいずれかである。ページがノードからマイグレートされた場合、プロセッサが、そのノード上の物理ページをルックアップしない（そのページは、どこか他へ移動しているため）ように、第２レベルページテーブル内のエントリは、ゼロアウトまたは無効化されている。
【０４０９】
上述のように、メモリのページがアクセス可能ではないためにストールイベントが発生すると、必要とされたページが、そのメモリの必要とされるノードへマイグレートされてもよいし、ｖｃｐｕがマイグレートされてもよい。ページが移動される場合、そのコンテンツが移動され、これは、宛先ノードで物理ページを割り当て、新しいノードにページのコンテンツをコピーすることを含む。宛先上の第２レベルページテーブルも、ｇｐａに対応するエントリが新たにマイグレートされた物理ページで埋められるように更新されている。したがって、次にページが参照された時、障害は引き起こされない。ｖｃｐｕがマイグレートされる場合、それは、参照されたメモリのページを有するノード上に再構築される。ゲスト物理アドレスは仮想化システムにわたってグローバルに一意的であるので、マイグレートされたプロセッサがその新たなノードの第２レベルページテーブルにアクセスすると、有効なエントリが、参照されたｇｐａに対応して見いだされる（すなわち、ノード上のすべての第２レベルページテーブルへのインデックスが、グローバルに一意的なｇｐａによってインデックス化されるので、同一または一定である）。
【０４１０】
したがって、アドレス変換の２つのレベルを実行することにより、ゲストスレッドによって参照された仮想アドレスは、ゲスト物理アドレスに変換され、次に、ゲスト物理アドレスは、実物理アドレスに変換される（メモリの参照されたページが、メモリのページにアクセスしたゲストスレッドを実行中のｖｃｐｕを実行しているｐｃｐｕと同じノード上にある場合）。要求された実ページがそのノード上にある場合、それは、第２レベルページテーブル内にあり、ストールは発生しない。メモリの実ページはアクセスされ、ゲストスレッドは、その処理を継続してよい。
【０４１１】
しかしながら、ゲストスレッドによって必要とされるゲスト物理アドレスに対応するメモリの実物理ページが、ゲストスレッドの現在実行しているノードにローカルではないと仮定する。ここで、ゲスト物理アドレスに対応するエントリは、第２レベルページテーブル内に存在しないか、もしくは、無効であるかゼロアウトされている。
【０４１２】
この例では、マシン障害が生じる、すなわち、ストールイベントが発生する。ストールの時点で、ゲストスレッドを実行中のｖｃｐｕは、ｐｃｐｕで実行していた。したがって、ｐｃｐｕはストールすることになる。この結果、割り込みが生じる。この割り込みは、ハイパーカーネルを指し示す割り込みベクトルを経由する。割り込みは、ハイパーカーネルによってキャプチャされ、ハイパーカーネルは、１セットのルーチンを実行する。この例では、ルーチンの実行により、ｐｃｐｕの状態が保存される。一例として、ストールが発生すると、物理プロセッサ状態のブロックを取得する命令が実行される。物理プロセッサ状態の状態は、物理プロセッサがそのアイデンティティを担ったｖｃｐｕの状態に対応する（ここで、ハイパーカーネルは、仮想プロセッサに対する物理プロセッサの対応付けを維持しており、したがって、特定のｖｃｐｕの識別子に物理プロセッサの状態を対応付けてよい）。プロセッサの状態のブロックは、メモリの領域に保存される。物理プロセッサブロック状態を保存する機能は、マイクロプロセッサハードウェアアーキテクチャによって（例えば、ハードウェアによって提供されるマクロによって）提供されてよい。この例において、状態情報の保存は、ハードウェアアーキテクチャによって提供されたハイパーバイザによって提供されるソフトウェア命令であり、これは、物理プロセッサ上での多重化を維持／追跡する。
【０４１３】
一実施形態において、保存されたプロセッサ状態は、上述のように、継続が作成された時に保存されたｖｃｐｕの状態である。プロセッサ状態は、様々なレジスタ、プログラムカウンタなどを含んでよい。ストール中、呼び出された１セットのルーチンは、ｖｃｐｕで動作しているゲストスレッドのアイデンティティおよび／またはゲストスレッドによって参照されたゲスト物理アドレスのアイデンティティを決定するためにも用いられる。例えば、後に詳述するように、識別は、ストール中に保存されたプロセッサ状態内の特定のレジスタにアクセスすることによって実行されてよい。したがって、物理プロセッサが何を実行していたのか（これは、ゲストスレッドだったであろう）、および、プロセッサがメモリにアクセスを試みていた時にどのページテーブルを利用していたのかが、決定され記録されてよい。かかるアイデンティティ情報を取得することにより、スレッドとメモリのページとの間の関連が決定されてよい。
【０４１４】
スレッドアイデンティティの決定
【０４１５】
上述のように、（ｐｃｐｕ上で動作している）ｖｃｐｕのプロセッサ状態が保存される。この例において、（物理プロセッサがそのアイデンティティを担った）ｖｃｐｕで実行しているゲストスレッドのアイデンティティが、以下のように決定される。ＦＳ−Ｂａｓｅ０レジスタ内の値が取得される。
【０４１６】
ゲストオペレーティングシステムにおいて、各スレッドは、（スレッディングライブラリによって導入されうる）所与のスレッドに固有のスレッドローカルストレージを備えるメモリまたはデータ構造の領域を確保させる。ＦＳ−Ｂａｓｅ０レジスタ値は、特定のスレッドのためのスレッドローカルストレージへのポインタを含む。スレッドローカルストレージは、カーネル情報に関連付けられてもよい。ＦＳ−Ｂａｓｅ０レジスタは、ゲストオペレーティングシステムによって管理される。
【０４１７】
ＦＳ−Ｂａｓｅ０レジスタ値は、２つの異なるスレッドが異なるＦＳ−Ｂａｓｅ０値を有するように設定される（すなわち、スレッドＴ２と等しくないスレッドＴ１について、スレッドＴ１のＦＳ−Ｂａｓｅ０は、スレッドＴ２のＦＳ−Ｂａｓｅ０と等しくない）。したがって、ｆｓｂａｓｅレジスタ内の値は、ｖｃｐｕで実行中のゲストスレッドを一意的に識別するために用いられてよい。
【０４１８】
ゲスト物理アドレスの決定
【０４１９】
ゲストスレッドによって参照されるゲスト物理アドレス空間は、保存されたプロセッサ状態の中のレジスタから取得されてよい。この例において、スレッドがストールしたページのｇｐａのアイデンティティは、プロセッサ状態の保存されたブロックの内部ＣＲ３レジスタ内の値にアクセスすることによって取得される。ＣＲ３レジスタ値は、アドレスをマッピングするためにゲストオペレーティングシステムによってどのテーブルが用いられていたのかを示しており、ここで、ＣＲ３レジスタ内の値は、アドレス空間（ゲスト物理アドレス空間）をゲストオペレーティングシステムによって見られる通りに定義する。例えば、ＣＲ３レジスタは、ノード上のゲスト物理アドレスすべてのための第２レベルページテーブルへのポインタを含んでおり、ここで、ＣＲ３は、特定のアドレス空間を参照する（新しいゲストアプリケーションまたはプロセスが実行されると、新しいＣＲ３アドレス空間が生成される）。上述のように、第２レベルページテーブルは、ｇｐａを実物理アドレスに変換するために用いられる。例えば、アドレス変換は、ＣＲ３レジスタ内のｇｐａ値を用いて第２レベルページテーブルをインデックス化することによって、（特定のｖｃｐｕとしてのアイデンティティで）物理プロセッサによって実行される。一例として、ＣＲ３レジスタから取得されたゲスト物理アドレスの上位数ビットは、第２レベルページテーブルへのインデックスとして用いられる（例えば、ＣＲ３レジスタの上位２０ビットは、第１ページディレクトリエントリの物理アドレスを格納するページディレクトリベースレジスタであり、ここで、ＣＲ３は、プロセッサが、仮想アドレス指定が有効である時に適切なページディレクトリおよびページテーブルをロケートすることによって、線形アドレス（ｇｐａ）を物理アドレスに変換することを可能にする）。上位数ビットは、より低位のビットをマスクして、より高位のビットを得ることによって取得されてよい。これら高位のビットは、ゲスト物理アドレスがどの４Ｋページを参照するのかを示す（必ずしもすべてのビットが必要とされうるわけではない）。第２レベルページテーブルは、ノードによって異なるが、ｇｐａｓは、すべてのノードにわたって一意的であり、任意の第２レベルページテーブルへのグローバルインデックスとして利用できる。
【０４２０】
上述のように、ページがノード上にある場合、要求されたページの実物理アドレスが返される（すなわち、ＣＲ３レジスタ値が第２レベルページテーブルをインデックス化するために用いられる時に、第２レベルページテーブル内に実物理アドレスに対応するエントリが存在する）。メモリのページがノード上に存在しない場合、ストールが発生する（ＣＲ３レジスタのインデックスにおけるエントリがゼロ化または無効化される）。
【０４２１】
スレッドコンテキスト切り替え
【０４２２】
上述の例では、メモリの要求されたページがノード上でローカルに利用可能である場合に、ストールが起こった。ｖｃｐｕにおいて動作するゲストスレッドおよび／またはｖｃｐｕによって参照されたゲスト物理アドレス空間のアイデンティティが、ストールに応答して、保存されたプロセッサ状態のブロックから決定される。スレッド／ページの識別は、他のイベントに起因するストールが発生した時にも実行されてよい。例えば、ストールは、スレッドコンテキスト切り替えが起こった時にも呼び出されてよい。ゲストオペレーティングシステムが、スレッドコンテキスト切り替えを実行してよく、ここで、そのオペレーティングシステムは、ゲストスレッドを他のｖｃｐｕへ切り替え、移動、または、多重化する。ｖｃｐｕ内のスレッドが切り替えられると、これは、ｖｃｐｕのＦＳ−Ｂａｓｅ０レジスタ値の対応する変更を引き起こす（例えば、スレッドコンテキスト切り替えが発生すると、ＦＳ−Ｂａｓｅ０レジスタは、新たなスレッドに対応する新たな値に切り替えまたは更新される）。
【０４２３】
ハイパーバイザは、ｖｃｐｕコンテナ内で動作するスレッドのアイデンティティを決定するために、ゲストオペレーティングシステムで起こっていることをイントロスペクトしてよい。ハイパーバイザの一部が、ｐｃｐｕ上で実行された多重化を追跡するため、および、プロセッサ状態のブロックを維持するために、利用されてよい。例えば、スレッドの追跡は、上述のようなスレッドコンテキスト切り替えによるＦＳ−Ｂａｓｅ０レジスタ値の変化など、内部レジスタの変化が起こった時に、ハイパーバイザにおいてキャプチャされてよい。いくつかの実施形態において、ＦＳ−Ｂａｓｅ０レジスタの変化が検出されると、ストールが呼び出され、その結果、ハイパーカーネルは、今や、ｖｃｐｕが異なるスレッドを実行していることに気がついている。
【０４２４】
例えば、ゲストオペレーティングシステムが特定のｖｃｐｕにおいて処理を実行していたと仮定する。ゲストＯＳは、その処理を別のｖｃｐｕへ切り替え、そのため、ＦＳ−Ｂａｓｅ０レジスタを更新する。ＦＳ−Ｂａｓｅ０レジスタの更新は、ストールをトリガし、ストールは、ハイパーカーネルをウェイクアップさせる。ハイパーカーネルは、ＦＳ−Ｂａｓｅ０レジスタの以前の値が何であったかを決定する、および／または、新しいＦＳ−Ｂａｓｅ０レジスタ値を観察するよう構成される。かかる観察に基づいて、スレッドコンテキスト切り替えが特定されてよい。スレッドコンテキスト切り替えによって呼び出されたまたはトリガされたストールの間に、ｖｃｐｕ内の／ｖｃｐｕによって参照されたスレッドおよび／またはメモリのページのアイデンティティが、上述のように決定されてよい。
【０４２５】
カーネル／ユーザ空間
【０４２６】
ゲストオペレーティングシステムが、ストールの時点でユーザ空間コードまたはカーネル空間コードのいずれかを実行していた場合がある。ゲストＯＳがユーザ空間コードを実行していた場合、ＦＳ−Ｂａｓｅ０レジスタは、上述のように、実行中であったゲストスレッドを指し示すように書き込まれる。
【０４２７】
カーネルコードが実行されていた場合、特定の値（例えば、ゼロ）が、ＦＳ−Ｂａｓｅ０レジスタ内に入り、これは、（ゲストスレッド／ゲストオペレーティングシステムコードではなく）カーネル空間コードが実行されていたことを示す。例えば、ゲストオペレーティングシステムが、ユーザ空間内での動作からカーネル空間へ切り替わると仮定する。２つの空間の間の変化は、ＦＳ−Ｂａｓｅ０レジスタの変化につながり、これは、上述のように検出されうる。ＣＲ３レジスタも同様に変化し、カーネルアドレス空間を指し示しうる。
【０４２８】
カーネル空間にある間にストールが発生した時に、スレッド／ワーキングセットのインサイト（洞察）が得られてもよい。一例として、カーネル空間への変化が、ＦＳ−Ｂａｓｅ０レジスタ値のゼロへの変化によって検出されると仮定する。ＣＲ３値が変化していない場合、物理プロセッサによって行われる作業は、一致するＣＲ３値を有するスレッドに関連または起因しうる。したがって、（ユーザ空間内で動作する）ゲストスレッドによって行われる作業は、カーネル空間への切り替えが起きた時に決定されうる。したがって、ワーキングセットのインサイトは、カーネル空間内でもユーザ空間内でも、任意のストールで起こりうる。
【０４２９】
（上述のように識別されてもよい）スレッドによってアクセスされたゲスト物理アドレスを決定することにより、スレッド間の関係性が決定されてよい。例えば、ＣＲ３レジスタ内のアドレスは、グローバルに一意的なゲスト物理アドレスであるので、２つのスレッドが同じＣＲ３値を有する場合、それらのスレッドは同じゲスト物理アドレス空間内で実行している（例えば、２つのスレッドは、同じアドレス空間を共有している）と判定される。これは、２つのスレッドが密接に関連していること（例えば、同じページテーブルを共有する可能性があること）を示すものである。
【０４３０】
したがって、上述の技術を用いると、どの特定のスレッドがどの特定のゲスト物理アドレス空間で動作していたのかが決定される。時間と共にストールイベントが起きると、スレッドによって参照されたメモリのゲスト物理ページのパターンまたはセット（すなわち「ワーキングセット」）が識別または他の方法で決定されてよい（ここで、メモリアクセスのパターンは、スレッド依存か、ｖｃｐｕ依存かである）。したがって、各スレッドについて、所与のスレッドにとって関心のあるページが決定されてよい。さらに、各ページについて、所与のページに関心のあるスレッドが決定されてもよい。
【０４３１】
履歴の記録
【０４３２】
ストールされたｖｃｐｕに関連するゲストスレッドおよび／またはゲスト物理アドレスの識別後、識別された情報は、履歴に記録されてよい。所与のスレッドについて、スレッドによってアクセスされたページが記録される。所与のページについて、ページにアクセスするスレッドが記録される。いくつかの実施形態において、ゲスト物理ページがゲストスレッドによってアクセスされた各時刻が記録される。アクセスは、ヒット（ページがローカルに利用可能であった場合）またはミス（ページが非ローカルであった場合）のいずれかの結果になりえた。ページアクセスがヒットであったかミスであったかにかかわらず、ゲストスレッドによってアクセスされたページの識別子が記録される（すなわち、ヒットおよびミスの両方が記録される）。アクセスに関連付けられているタイムスタンプが、履歴情報の一部として記録されてもよい。履歴は、時間と共に更新されてよい。例えば、仮想化マシンによって実行される処理が進むにつれて、計算の状態ならびにスレッドおよびメモリのメモリアクセスパターンの状態が変化し、経時的に進展する。したがって、スレッドとワーキングセットとの間の関連付けは、経時的に動的に変化しうる。
【０４３３】
メモリとスレッドとの間の関係性を特徴付ける情報は、後に詳述するように、メモリハウスキーピング、タイダルツリー意思決定、コスト関数決定、リモートノードからのリソース要求の受信など、ハイパーカーネル内のいくつかの場所で用いられてよい。
【０４３４】
いくつかの実施形態において、スレッドとページとの間の関係性が、評価および維持され、これらの関係性を意思決定で最大限に利用するハイパーカーネル動作を導くことを可能にする動作を有するＡＰＩが設計される。
【０４３５】
以下では、本明細書に記載の仮想化システムの処理において決定するために利用できるコスト項およびメトリックの例のリストである。コスト項がどこでどのように（例えば、ハウスキーピング、タイダルツリー決定、ペアワイズリソースマイグレーションネゴシエーションなどにおいて）利用されるのかについてのさらなる詳細については後述する。
【０４３６】
メモリ状態
【０４３７】
いくつかの実施形態において、所与のスレッドＴ、ノードｎ、および、時刻ｔについて、Ｔが時刻ｔの前の或る期間中にそのノードで実行していたと仮定して、Ｔがその期間中にノードｎ上でアクセスしたページＨのセットが記録される。記録されたページのセットは、時刻ｔでのｎにおけるＴのページアクセスＨ，ｔ，Ｎの履歴と呼ばれる。実際には、Ｈ，ｔ，ｎは、Ｔが、ある持続時間δについて、期間［ｔ−δ，ｔ］中にｎ上でアクセスしたすべてのページの合理的なサブセット近似を表しうる。いくつかの実施形態において、ハードウェアのサポートがなければ、非常に大量のオーバーヘッドを起こすことなしにスレッドのアクセスを一つ一つ記録することは、計算的に困難でありうるので、この近似が利用される。ハードウェアのサポートが利用可能である場合、それは、スレッドアクセスを記録するために用いられてよい。いくつかの実施形態において、一定ではないデルタを参照するのではなく、上述の時間は、可変長の区間に関して表されてよい（例えば、［ｔ１・・・ｔ２］または［ｔ３・・・ｔ４］）。
【０４３８】
温かさ（ｗａｒｍｔｈ）および利用度
【０４３９】
各履歴Ｈ、ｔ、ｎについて、２つのメトリック（利用度および温かさ）が保持される。いくつかの実施形態において、利用度（適合度と呼んでもよい）は、過去の或る時点に記録された履歴Ｈ、ｔ、ｎを、より近い過去［ｔ’−δ’，ｔ’］（ここで、現在時刻ｔ’＞ｔであり、或るδ’の間の区間）で起きたゲストスレッドＴのページアクセスの最新パターン（すなわち、その新たな履歴Ｈ、ｔ’、ｎ）に関連付ける。ｔ’およびｔでの２つの履歴に記録されたアクセスが同様である（すなわち、先に時刻ｔで記録された履歴が繰り返されている）場合、ページＨ，ｔ，ｎのセットのＴによる利用度は高いと決定される。一実施形態において、利用度は、最近の重複におけるページの再利用度として、または、２つの履歴／期間の間でのページアクセス動作の重複の量として計算される。
【０４４０】
いくつかの実施形態において、温かさは、履歴Ｈ，ｔ，ｎ内のどれだけのページが現在時刻ｔ’＞ｔにおいてノード上でまだローカルであるのかを測る。そのため、この例において、スレッドの履歴の温かさは、ノード上でまだローカルであるページのセットに履歴を関連付ける。一実施形態において、温かさは、ノード上でまだローカルであるページのアクセスの割合または比率として計算される。これは、最近アクセスされたページの内、どれだけのページがノード上にまだ存在するすなわちローカルであるのかを示す。一例として、最近のある期間中にノード上のゲストスレッドによってアクセスされたページの内の８０％が現在ノード上からなくなっていると判定されたとする。その結果、現在時刻における温かさは、２０％と計算される。
【０４４１】
利用度は、Ｔがアクセスしていると共にその履歴Ｈ，ｔ，ｎにも存在するページの割合の推定に基づいて、スレッドＴが現在動作しているノードｎで更新される。しかしながら、本明細書に記載するように、温かさは、例えば、現在Ｔの履歴内にあるページが除去された場合に、（Ｔが現在動作しているノードとは無関係に）ノードｎで更新される。各スレッドＴについて、温かさおよび利用度は両方とも、Ｔの履歴Ｈ，ｔ，ｎが格納されるローカルノードｎに関して計算されるため、温かさおよび利用度を計算するために必要になりうるパラメータは、ゲストスレッドＩＤ（すなわち、ローカルノードは、以下のＡＰＩに内包される）およびタイムスタンプｔだけである。ノードごとスレッドごとに異なる期間に記録された２以上の履歴が格納されてよい。いくつかの実施形態において、タイムスタンプｔは、ゲストスレッド識別子に加えて用いられるＡＰＩの一部である。
【０４４２】
温かさと利用度との間の違いの一例は、以下の通りである。温かさは、スレッドの履歴を、履歴を含むノード上に現在あるページのセットに関連付けるが、利用度は、スレッドの履歴を、スレッドが動作しているノード上でのスレッドの現在のアクセスパターンに関連付ける。
【０４４３】
以下は、利用度および温かさのための関数の例である。
【０４４４】
（ｉｎｔ）ｕｔｉｌｉｚａｔｉｏｎ（ｇｕｅｓｔ＿ｔｈｒｅａｄ＿ｉｄ）
【０４４５】
（ｉｎｔ）ｗａｒｍｔｈ（ｇｕｅｓｔ＿ｔｈｒｅａｄ＿ｉｄ）
【０４４６】
一実施形態において、利用度は、以下のように追跡される。コード（本明細書では「バランサ」と呼ぶ）が、第２レベルページテーブルエントリを定期的に消去するが、メモリを解放することはない。例えば、実物理ページへの参照はページテーブル内でゼロアウトされるが、ページ自体は解放されない。次にページが要求された時、障害が発生する。しかしながら、参照は意図的または故意に除去されたので、ページアクセスが実際にはヒットであったであろうことがわかる（すなわち、参照が意図的にゼロアウトされたページでストールが起きた場合、そうでなければヒットがそのページに対して発生しただろうと判定される）。上記のサンプリングを実行することにより、参照は、利用度の近似を得るために、統計的にカウントされてよい。上述のように、そうでなければページに対するヒットが発生したのか否かを示すストールを引き起こすために、サンプリングが実行されてよい。引き起こされたストール中、ゲストスレッドおよびｇｐａのアイデンティティが、上述のように取得されてよい。
【０４４７】
ページのセットに関する情報の管理
【０４４８】
上述のように、ゲストスレッドは、ゲスト物理ページアドレスによって示されたゲスト物理ページと関連付けられている。いくつかの実施形態において、ゲスト物理ページは、それらのアドレスがポッドにわたって一意的であるという属性を有する。したがって、いくつかの実施形態において、消費および維持される管理データは、ゲスト物理アドレス（ｇｐａ）である。上述のように、ゲストスレッドは、（ＣＲ３およびＦＳ−Ｂａｓｅ０などのレジスタを用いた一意的なゲストスレッド識別子である）ゲストスレッド番号によって示されるため、これらも、ポッドにわたって一意的である。
【０４４９】
様々な目的（それらの例を後に詳述する）に対して、１セットのページを効率的に維持し、包括および排除について効率的にテストするデータ構造を有することが有用でありうる。利用できる時間および空間の両方において効率的なデータ構造の一例は、ブルームフィルタである（ここで、例えば、情報はビットマップにハッシュされる）。ブルームフィルタは、例えば、スレッドによるページアクセスの履歴をコンパクトに記録するために用いられてよく、ここで、スレッドアクセス履歴（ヒットであってもミスであっても）は、経時的に更新される。ブルームフィルタの長さが調整されてよい。
【０４５０】
いくつかの実施形態において、このページセットは、経時的に更新される。実施形態の一例では、これを可能にする或るバージョンの基本的なブルームフィルタ（エージングブルームフィルタなど）が利用される。実施形態の一例では、２つのアクティブバッファを備えたエージングブルームフィルタが用いられ、これは、２つのブルームフィルタを維持することによってＦＩＦＯ順序でデータをエージングし、ブルームフィルタの一方はフル稼働し、一方、他方のブルームフィルタは最新の履歴を保持する。
【０４５１】
いくつかの実施形態において、１セットのページを維持するためにブルームフィルタまたはその他のデータ構造のどの特定のバージョンが用いられるのかに関わらず、必要とされる動作を記述する（および、ブルームフィルタに関して実行されてよい）以下のＡＰＩの例が利用される。
【０４５２】
／／合計メモリサイズ（バイト）を取得する
【０４５３】
ｓｉｚｅ＿ｔ  ｔｓ＿ｂｆ＿ｓｉｚｅ（ｕｉｎｔ３２＿ｔ  ｎｕｍ＿ｂｆ，ｕｉｎｔ３２＿ｔ  ｎｕｍ＿ｈａｓｈ，ｕｉｎｔ６４＿ｔ  ｎｕｍ＿ｂｉｔｓ）；
【０４５４】
【０４５５】
／／ｂｆを初期化して破棄する
【０４５６】
ｖｏｉｄ  ｔｓ＿ｂｆ＿ｉｎｉｔ（ｓｔｒｕｃｔ  ｔｓ＿ｂｆ＊ｂｆ，ｕｉｎｔ３２＿ｔ  ｎｕｍ＿ｂｆ，ｕｉｎｔ３２＿ｔ  ｎｕｍ＿ｈａｓｈ，
【０４５７】
ｕｉｎｔ６４＿ｔ  ｎｕｍ＿ｂｉｔｓ，ｕｉｎｔ６４＿ｔ  ｃａｐａｃｉｔｙ）；
【０４５８】
ｖｏｉｄ  ｔｓ＿ｂｆ＿ｄｅｓｔｒｏｙ（ｓｔｒｕｃｔ  ｔｓ＿ｂｆ＊ｂｆ）；
【０４５９】
【０４６０】
／／ｂｆをリセットする
【０４６１】
ｖｏｉｄ  ｔｓ＿ｂｆ＿ｒｅｓｅｔ（ｓｔｒｕｃｔ  ｔｓ＿ｂｆ＊ｂｆ）；
【０４６２】
【０４６３】
／／１つの要素を追加する
【０４６４】
ｖｏｉｄ  ｔｓ＿ｂｆ＿ａｄｄ（ｓｔｒｕｃｔ  ｔｓ＿ｂｆ＊ｂｆ，ｖｍ＿ｐａｄｄｒ＿ｔ  ｇｐａ，ｂｏｏｌ＊ａｇｅｄ）；
【０４６５】
【０４６６】
／／要素のセットメンバーシップをクエリする
【０４６７】
ｂｏｏｌ  ｔｓ＿ｂｆ＿ｃｏｎｔａｉｎｓ（ｓｔｒｕｃｔ  ｔｓ＿ｂｆ＊ｂｆ，ｖｍ＿ｐａｄｄｒ＿ｔ  ｇｐａ）；
【０４６８】
ページのアフィニティ
【０４６９】
本明細書で用いるように、アフィニティは、現在動作しているノードに対するスレッドのアフィニティを示す尺度である。アフィニティは、上述のように、スレッドによるアクセスの履歴記録から決定されてよく、ここで、アクセスのセットの中で、特定のノードからのアクセスの回数が決定される。いくつかの実施形態において、比較的少数の最も最近アクセスされたページが追跡され、各かかるページについて、ページが最も最近そこから到着したノードｉｄ（識別子）（ページが移動した場合、または、そうでなければローカルノードＩＤ）が追跡される。ゲストスレッドについて、複数のかかるページが同じノードｎに由来する場合、そのスレッドは、ｎに対する「アフィニティ」を有すると断言される（すなわち、スレッドが特定のノードからページを引き出している場合、そのスレッドは、ノードに対するアフィニティを有する）。例えば、スレッドによる最近の１００アクセスが評価されると仮定する。例えば、それらの内の９０％（または必要に応じて任意のその他の閾値）が別のノードに由来する場合、アフィニティ関数は、そのノードの識別子を返す。そうでなければ、関数は、ローカルノードの識別子を返す。
【０４７０】
いくつかの実施形態において、上述の閾値の例（１００アクセスで、アクセスの９０％が特定のノードに由来する）は、（例えば、実験を通して）調節できる初期化パラメータである。トレードオフが存在しうる。トレードオフの一例は、この期間に保持されるページが多くなるほど、ノードに対するページのセットのアフィニティの程度が取得される前に、より多くのフラグメンテーションがシステム内で観察されうるというものである。例えば、所与のスレッドについて、１０００のページがノード０上にあり、スレッドがノード１上にある場合、ノード０に対するアフィニティがあると決定するために、１０００ページの待機がなされうるが、ページがノード１に移動した後に、残念ながら、スレッドがノード１からノード０へマイグレートすることがある。
【０４７１】
以下は、アフィニティ関数コールの一例であり、ゲストスレッドＩＤを入力として、ノードｉｄを返す。
【０４７２】
ｎｏｄｅ＿ｉｄ＝ａｆｆｉｎｉｔｙ（ｇｕｅｓｔ＿ｔｈｒｅａｄ＿ｉｄ）；
【０４７３】
デューティ
【０４７４】
ｖｃｐｕは、ストールすることなしにかなりの数のゲスト命令を実行する場合、生産的であると判定されうる。
【０４７５】
ｖｃｐｕがマイグレートした後、そのｖｃｐｕは、生産的になる常駐ページを或る最少セットだけ有する必要がありうる。例えば、ｖｃｐｕマイグレーション後に、通常は、ｖｃｐｕが生産的になることができる前に必要とする〜１５−３０のページが存在することが観察されうる（これは、例えば、経験的に観察されうる）。いくつかの実施形態において、ｖｃｐｕは、少なくとも閾値数のページアクセスを実行するまでノードにとどまるデューティを有する。（設定可能な）閾値は、スレッド用のワーキングセットの構築を開始するための初期メカニズムとして用いられる。本明細書の例において用いられるように、これらのページは、アクティブセットと呼ばれる。スレッドが計算を進めるために必要とするアクティブセット内のページの例は、スタックの最上部のページ、次を実行するためにスレッドが必要とするコードを有するページ、などを含む。この閾値は、例えば、スレッドがページにアクセスした後に別のノードにマイグレートするのを防ぐために設定される。ｖｃｐｕがあまりに頻繁にマイグレートする場合、十分なゲスト進捗をなすために必要なゲストページのセットを利用する機会がない場合があり、したがって、非生産的でありうるため、実際には進捗がないことがある。
【０４７６】
本明細書の例で用いられるように、グルーミングされたセットとは、或る期間にわたってゲストスレッドによって頻繁にアクセスされたページのセットのことであり、いくつかの実施形態において、その期間の持続時間が調整可能である。複数のグルーミングされたセットが、所与のゲストスレッドについて見られる場合がある。本明細書で用いるように、デューティという用語は、グルーミングされた（ワーキング）セットの形成の助けになるように、ゲストスレッドを或る期間中にノードにとどまらせる戦略要素を示すために用いられる。しかしながら、デューティ単独では、それが生成したグルームされたセットを維持するのに十分でない場合がある。
【０４７７】
いくつかの実施形態において、デューティ関数コールは、ゲストスレッド識別子を入力として、デューティを示すブール値を出力として返す。例えば、ブール値は、ゲストスレッドがノードでそのデューティを完了したか否かを示すために用いられてよい。デューティが利用されうる一方法は、要求側の決定およびコスト項においてである。例えば、ｖｃｐｕが、（例えば、非ローカルページアクセスに対するストールイベントに応答して）メモリのページの要求を送信するのかまたはマイグレートするのかを決定する時に、ゲストスレッドがノードでそのデューティをまだ完了していない場合、これは、ｖｃｐｕ（ひいてはゲストスレッド）をマイグレートするコストを高めることに寄与する。
【０４７８】
（ｂｏｏｌ）ｄｕｔｙ（ｇｕｅｓｔ＿ｔｈｒｅａｄ＿ｉｄ）
【０４７９】
デューティ状態は、スレッドがノードに到着して以来実行したアクセスの回数を計算またはカウントし、アクセス回数を閾値と比較することによって決定されてよい。閾値を満たすかまたは超えた場合、デューティは、完了しているかまたは他の方法で満たされている。閾値が満たされていない場合、デューティは完了していない。
【０４８０】
メモリ圧迫
【０４８１】
いくつかの実施形態において、メモリのニーズを満たすのに十分な空間がノード上に常にあることが保証される。しかしながら、いくつのｖｃｐｕがノード上で動作しているか、および、どれだけのＩ／Ｏが起きているのかによっては、ページを他のノードに移動することによって、ページをすぐにメモリからエビクトする必要がある場合がある。ページのエビクトが十分に迅速に起こりえない場合、そのノードへのメモリ圧迫は、危機的な状態にあるとみなされる。一部の例において、これは、すぐに対応すべき緊急状態である。エビクトに関するさらなる詳細については、ハウスキーピングと関連して後述する。
【０４８２】
／／ノード上の危機的なメモリが、その容量を所与としてノード上にあまりに多くのページが存在するか否かを報告している：
【０４８３】
（ｂｏｏｌ）ｍｅｍｏｒｙ＿ｃｒｉｔｉｃａｌ（ｎｏｄｅ＿ｉｄ）
【０４８４】
優良度メトリック（Ｇｏｏｄｎｅｓｓ  Ｍｅｔｒｉｃ）
【０４８５】
本明細書に記載の仮想化システムの効率は、（例えば、上述のように、ワーキングセットおよびスレッドの関連性の決定に基づいて）ゲストスレッドとそれらが必要とするページのセットとを調整することによって改善されうる。効率を決定する方法の一例は、本明細書で「優良度」メトリックと呼ぶものを定義することによる方法である。優良度メトリックは、スレッドの関数であり、ノードで動作している時のスレッドの効率を示す（ここで、スレッドは、異なるノード上では異なる効率を有しうる）。本明細書に記載されるように、スレッドは、実行時にめったにストールしない場合に「優良」とされる。後に詳述するように、優良度を追跡する様々な方法が利用されてよい。次いで、優良度メトリックは、より良くストールに対処する方法を決定するために用いられてよい。例えば、スレッドのマイグレーション、および、スレッドによって用いられるページのワーキングセットに対してそれらが有しうる効果が考慮されてよい。別の例として、優良度メトリックは、ページエビクト、転送要求への応答、および、（例えば、後述の「リソースマイグレーションネゴシエーション」に記載するように）それが、それらのページを用いるノード上のスレッドにどのように影響しうるか、に関する決定を行う時に用いられてよい。
【０４８６】
優良度メトリックの計算の例は、以下の通りである。通例、ゲストスレッドができるだけ少ないミスでゲスト内のランタイムを積み重ねるほど、そのゲストスレッドは、良好に実行する（すなわち、正味ゲストランタイムが高いほど、そして、ミスが少ないほど、良好である）。ハイパーカーネル内のサブシステムにわたって一様に利用できるメトリックの一例は、「正味ゲストスレッドランタイム／ミスカウント」であり、ここで、「正味」とは、いくつかの実施形態において、ハイパーカーネルに起因するあらゆるスレッドアイドル時間を取り除くことである。実施形態の一例において、この時間は、スレッドを実行するｖｃｐｕがゲストに返されるまで積算され、時間の積算はストール後に停止される。ｖｃｐｕがゲストに返された時に、タイムスタンプが記録されてよく、次にストールした時に、新しいタイムスタンプが記録される。次いで、２つのタイムスタンプの間の差が、積算された正味ゲストスレッドタイムに追加されてよい。これは、スレッドに対してスレッドごとに実行される。分子または分母が大きくなりすぎた場合、比率が同じままになるように、それらの値を割ってよい（例えば、両方２で割る）。
【０４８７】
いくつかの実施形態において、Ｉ／Ｏ待ちに費やされる正味スレッド時間が追跡される。ゲストスレッドがＩ／Ｏのためにストールされると、そのスレッドを実行するｖｃｐｕは、上述のように、イベントテーブル内に配置される。Ｉ／Ｏが完了すると、そのスレッドを実行するｖｃｐｕは、イベントテーブルから外されて、タイダルツリー内に配置され、ここで、最終的には実行される。スレッドは、ベアメタル上で動作しても、本明細書に記載のハイパーカーネル上で動作しても、Ｉ／Ｏを実行する。ベアメタル上でのＩ／Ｏ待ちは、ベアメタル上のゲストスレッドのランタイムの一部になりえ、いくつかの実施形態では、同じことがハイパーカーネルにおいて起こる。ハイパーカーネルにおいて、ゲストスレッドのランタイムの一部としてＩ／Ｏ待ちを組み込む方法の一例は、以下の通りである。スレッドがイベントテーブルに配置された時のタイムスタンプが記録される。Ｉ／Ｏが後に完了した時に、２つのタイムスタンプの差が取られ、ゲストスレッドランタイムに追加される。次いで、（ｖｃｐｕにおいて動作する）スレッドは、タイダルツリー内に配置される。
【０４８８】
後に詳述するように、優良度メトリックは、コスト関数（例えば、スレッドのマイグレートを考慮した時に、その優良度メトリックが高すぎる場合、スレッドをマイグレートしないという決定がなされうる）、ハウスキーピング（例えば、バランサに関して、メモリの危機的な状況のためにページがエンビクトされる時に、効率的ではないスレッドを有するページが選択されうる）、および、タイダルツリー（例えば、動作する準備をさせるためにスレッドを含むｖｃｐｕをキューアップしようと試み、すでにキューアップされて動作の準備ができたｖｃｐｕでノードがオーバーロード状態であるとわかった時に、必ずしも実行の準備をすべきスレッドではなく、最悪すなわち最も効率の低いスレッドが、ルート内に配置されるよう選択されうる）のためなど、本明細書に記載の仮想化システムの様々な部分で用いられてよい。
【０４８９】
以下は、優良度メトリックの２つの実施例であり、いずれの例も、以下の２つの内の一方に対する正味ゲストスレッドランタイムの比を計算する。
【０４９０】
１．ミスの数、および
【０４９１】
２．正味ホストランタイム（ゲストを除く）
【０４９２】
上記の例はいずれも、計算が容易であり、監視が安価である。１つの例外は、２つ目の例がＩ／Ｏの待ち時間を含みうるのに対して、１つ目の例は含まないことでありうる。いくつかの実施形態において、（Ｉ／Ｏを含む）ベアメタルとの比較がなされる場合に、同じＩ／Ｏ処理がどちらの場合にも実行される（両者ともＩ／Ｏ待ち時間を含むか、または、Ｉ／Ｏ待ち時間を除外する）。Ｉ／Ｏ待ち時間の組み込みに関する詳細の例については上述した。
【０４９３】
例示の目的で、以下の例の形態の関数を用いる。
【０４９４】
／／スレッドｔの優良度がｔよりも大きい場合にはｔｒｕｅを返し、そうでない場合にはｆａｌｓｅを返す。
【０４９５】
ｂｏｏｌｅａｎ  ｉｓＧｏｏｄ（ｇｕｅｓｔ＿ｔｈｒｅａｄ  ｔ，ｔｈｒｅｓｈｏｌｄ  ｔ）
【０４９６】
いくつかの実施形態において、２つ目の例を用いる場合、正味ホストランタイムは、優良度メトリックの分母として用いられる。
【０４９７】
【０４９８】
ページ競合
【０４９９】
本明細書の例に記載するように、ページ競合は、別個のノード上の２以上のゲストスレッドが同じ短期間に１または複数の同じページを必要とする時に起きる。ページ競合の１つの示唆は、同じページで頻繁にストールし続けるゲストスレッドがノード上に存在することである。これは、ページが別のスレッドによって常にプルされているからでありえ、別のスレッドは、２つのスレッドの間でｐｉｎｇをやり取りする。（高度に）競合されるページの一例は、システムコールが実行される度にアクセスされるページである。例えば、Ｌｉｎｕｘオペレーティングシステムにおいて、ゲストオペレーティングシステムは、タイマーを含むページを更新するためにシステムコールを頻繁に実行する。しかしながら、Ｌｉｎｕｘカーネルは、本明細書に記載の仮想環境内でクラスタにわたって分散的に動作しているので、すべてのスレッドがタイマーを備えたページを更新しようとしている場合、ページのスラッシングが起こりうる。これは、パフォーマンスに悪影響を及ぼしうる。
【０５００】
ページ競合の結果、共通で必要とされるページをノードの間で移動させるか、または、競合するゲストスレッドをそれらが必要とするページと同じ場所に位置させうる。後者は、これらの特定の競合するページでの再ストールを潜在的に低減しうるが、多くのゲストスレッド／ｖｃｐｕを同じ場所に位置させる、または、それらのスレッドによって必要とされる異なるページセットのストールを大幅に増加させるなど、副作用を有しうる。多くのｖｃｐｕを同じ場所に配置すると、ｖｃｐｕがマイグレートする先のノードに、効率的に動作するｐｃｐｕが十分にない場合、潜在的にシステムへストレスが掛かりうる。ページの競合は、競合するゲストスレッドが、何らかのまたは非常に小さい共通部分を持つ異なるノード上に、それらがアクセスする多数のページセットを有する場合、競合するゲストスレッドを同じ場所に配置することを正当化しえない。いくつかの実施形態において、ページ競合を解決する方法の決定は、かかる課題を考慮に入れる。
【０５０１】
以下は、ページ競合の問題を検出するために呼び出されうる関数の一例である。以下に記載するように、関数またはアルゴリズムは、特定のページについて、どのゲストスレッドが、どれだけの頻度で、特定のページを必要としているのかを決定する。例えば、関数は、ページを必要とするゲストスレッドについて、スレッドが短期間（例えば、最近）にページにアクセスした（例えば、そのページでストールした）回数のカウントを算出する。カウントが（設定可能な）閾値（例えば、５回）を超えた場合、ページは、競合されているとしてフラグを立てられる（例えば、ページに対するバイナリまたはブールフラグが設定されてよい）。これは、カウンタが閾値にある時に、ゲストスレッドがノード上の特定のページに対して競合していることを示す。
【０５０２】
／／関数ｐａｇｅ＿ｃｏｎｔｅｎｔｉｏｎは、ハッシュ関数データ構造を利用し、
【０５０３】
／／それは、ゲストスレッドが最近に所与の閾値よりも多く
【０５０４】
／／同じページを要求したか否かを特定する／／
【０５０５】
／／関数ｐａｇｅ＿ｃｏｎｔｅｎｔｉｏｎ＿ｌｉｓｔは、同じページ（ｇｐａ）で競合する
【０５０６】
／／他のゲストスレッドを返す
【０５０７】
（ｂｏｏｌ）ｐａｇｅ＿ｃｏｎｔｅｎｔｉｏｎ（ｇｐａ，ｇｕｅｓｔ＿ｔｈｒｅａｄ＿ｉｄ）
【０５０８】
ｌｉｓｔ  ｏｆ  ｇｕｅｓｔ  ｔｈｒｅａｄ  ｉｄｓ＝ｐａｇｅ＿ｃｏｎｔｅｎｔｉｏｎ＿ｌｉｓｔ（ｇｐａ）
【０５０９】
本明細書に記載のコスト項の中で、一部は、以下のようなページ競合に対して取るべき動作を決定するために用いられてよい。
【０５１０】
優良度メトリック：上述の優良度メトリックは、解決の必要がある問題があるか否かを特定するために、ページ競合の検出時に用いられてよい。例えば、競合するゲストスレッドが良好に実行中である場合、ページ競合の検出は、任意の特別な処理を必要としない。ページ競合は、無視することができ、例えば、任意のストールを扱う汎用コスト関数（優良度メトリックのためのＡＰＩの例が上述されている）を用いて、決定がなされ続ける。
【０５１１】
スレッドの頻度：いくつかの実施形態において、１つのスレッドが残りのスレッドよりも頻繁に動作する（すなわち、より頻繁にページにアクセスする）場合、これは、シングルスレッドのアプリケーション、または、シングルスレッド、おそらくメインスレッド）を例外的に利用するアプリケーションが存在する可能性があることを示すものである。これを、本明細書では、ポピュラースレッドと呼ぶこととする。
【０５１２】
いくつかの実施形態において、ポピュラースレッドは、移動がそのワーキングセットのメモリ配置と矛盾しない限りは、ページ競合に対処するためにマイグレートを強制されることがない。いくつかの実施形態において、ページ競合によるポピュラースレッドのマイグレートを強制しないことで、パフォーマンスが向上する。
【０５１３】
以下の関数の例は、アクセスの頻度に基づいて、ゲストスレッドの頻度を示す値を返す。
【０５１４】
／／アクセスの頻度に基づくゲストスレッドの頻度
【０５１５】
（ｉｎｔ）ｇｕｅｓｔ＿ｔｈｒｅａｄ＿ｆｒｅｑｕｅｎｃｙ（ｇｕｅｓｔ＿ｔｈｒｅａｄ＿ｉｄ）
【０５１６】
スレッドの間の共通関心（ｃｏｍｍｏｎ  ｉｎｔｅｒｅｓｔ）のサイズ：ページ競合は、１セットの協調するスレッドの中の複数のスレッドがアプリケーションにおいてメモリを共有する時に起こりうる。ページ競合は、いくつかのユーザ並列作業負荷において観察されうるものであり、アプリケーションプログラマが、より細かい粒度の並列アプリケーションを書き込んで、アプリケーションレベルでの並行性を扱うと、より多くのページ競合が起こりうる。例えば、ゲストアプリケーションが独自のマルチスレッディングを実行し、独自の共有メモリを有すると仮定する。かかるアプリケーションのゲストスレッドは、大量の共通関心を有する可能性がある（すなわち、スレッドがアクセスするページの重複）。これは、例えば、異なるアドレス空間で動作するために、限られた量の共通関心を有するＵｎｉｘでの一連の処理とは対照的である。高性能データベースが、広い共有アドレス空間を用いて独自のマルチタスキングおよびマルチスレッディングを実行してもよい。アプリケーションのゲストスレッドは、メモリの共通ページに従事している場合があるので、分離されるべきではない。または、例えば、アプリケーションは、或るスレッドの結果が別のスレッドによって利用されうるように、そのゲストスレッドの間に作業を分散していた。共通関心を決定するための本明細書に記載の技術は、アプリケーションレベルおよび／またはオペレーティングシステムレベルで実行されてよい。
【０５１７】
ゲストスレッドは、スレッドが多数の共有ページを共有する場合に、同じ場所になければ競合するスレッドと同じ場所に位置することによってパフォーマンス利益を享受しうる。しかしながら、ペアになったゲストスレッドの間の共通関心のサイズを評価することが十分ではない場合がある。以下のシナリオ例を仮定する：スレッドＡが、スレッドＢとの多くの共通関心を有し、スレッドＢが、スレッドＣとの多くの共通関心を有するが、スレッドＡおよびＣには共通関心がない。ＡおよびＣが別個のノード上に配置される場合、スレッドＢは、ノードの間で頻繁にマイグレートすることによって、または、多くの共通に必要とされているページを頻繁に移動させることによって、その共通関心をＡおよびＣと共有しなければならない。いずれにしても、パフォーマンスは、Ａ、Ｂ、および、Ｃが（それらが実行に十分なｐｃｐｕを有すると仮定して）同じ場所に位置するソリューションと比較して低下する。以下は、（スレッドがすべて、同じノード上でローカルに動作している限りにおいて）（複数の）ゲストスレッド間での共通関心のサイズを推定するＡＰＩの一例である。
【０５１８】
／／ゲストスレッドとセット内のすべての他のゲストスレッドとの共通関心の評価。
【０５１９】
／／このセットは、競合するゲストスレッド、頻繁なゲストスレッド、または、ローカルのゲストスレッドなど、多くの方法で与えられうる
【０５２０】
（ｉｎｔ）ｃｏｍｍｏｎ＿ｉｎｔｅｒｅｓｔ（ｇｕｅｓｔ＿ｔｈｒｅａｄ＿ｉｄ，ｓｅｔ  ｏｆ  ｇｕｅｓｔ  ｔｈｒｅａｄｓ）
【０５２１】
本明細書に記載するように、共通関心は、ノード上のゲストスレッドの間で共有されたページのセットのサイズを示す尺度（ページアクセスのパターンの類似性を示しうる）である。一例において、共通関心のサイズは、以下のように決定される。ゲストスレッドおよび１セットのスレッドのためのワーキングセットが取得される。スレッドのワーキングセットの重複／共通部分が決定される。
【０５２２】
例えば、第１スレッドＴ１および第２スレッドＴ２があるとする。各スレッドは、最近アクセスしたページのそれぞれのワーキングセットＷ１およびＷ２を有する。例えば、Ｗ１およびＷ２の両方に共通するページが１ページだけである場合、Ｔ１およびＴ２は、あまり共通関心を持たない。しかしながら、Ｗ１およびＷ２の共通部分が多数のページである場合、２つのスレッドは、大量の共通関心を有する。
【０５２３】
スレッドのためのワーキングセットは、共通関心が計算されているスレッドによって最近のアクセスの履歴（ヒットおよびミス）を記録するために用いられるデータ構造（例えば、ブルームフィルタ）にアクセスすることによって決定されてよい。上述のように、ミスは、ストール中に（例えば、ＣＲ３およびＦＳ−Ｂａｓｅ０レジスタを用いて）決定されうる。ヒットは、サンプリングを実行することによって決定されてよい。例えば、上述のように、ページテーブルのサンプリングを実行するコードが実行され、そのコードは、ページテーブルを無効化するが、メモリからページテーブルを削除しない。無効化されたページに対するヒットが削除されているが、まだノード上にあり、観察された場合、ページテーブルは再び有効化され、ヒットが記録される。したがって、ヒット数は、サンプリングを介して近似されうる。ヒットは、スレッドの（最近の）履歴に記録されてよい。物理プロセッサが、ヒットの起きた時を示すハードウェアを備える場合、この情報も、ヒットであるページアクセスを記録するために取得されてよい。決定されたヒットおよびミスは、スレッドの履歴内にページアクセスとして記録されてよい。
【０５２４】
Ｗ１およびＷ２は、スレッドＴ１およびＴ２による最近のアクセスであり、それぞれのスレッドに対応するそれぞれのビットアレイを用いて表されてよい。所与のビットアレイについて、「１」の数および位置は、サイズおよびアクセスされたページの両方に比例する。ビットアレイは、「ＡＮＤ演算される」。例えば、ＡＮＤ演算の結果がすべてゼロである場合、２つのスレッド間に共通関心はない。ＡＮＤ演算後の「１」のカウントが決定され、２つのスレッド間の共通関心のサイズを示す。「１」のカウントすなわち数は、例えば、ハミング重みとして計算される。このハミング重みは、Ｔ１とＴ２との間の共通関心の推定値である。
【０５２５】
したがって、この例に記載したように、スレッドの最近のアクセス履歴は、「ＡＮＤ演算」を実行することによって取得および比較される。ブルームフィルタが用いられる場合、フィルタを生成するために用いられるハッシュ関数は同じページがブルームフィルタ内の同じ位置にハッシュするように、一貫していることが好ましい。この一貫性は、ｇｐａがハッシュされることで提供されてよく、ｇｐａは、クラスタ内のすべてのノードにわたってグローバルに一意的である。次いで、ハミング重みが計算され、ここで、この値は、共通関心のレベルを示す。
【０５２６】
（同じまたは異なるノード上に存在しうる）複数のゲストスレッドに対する所与のゲストスレッドの共通関心が計算されてよい。一実施形態において、共通関心のサイズは、ゲストスレッドのセット内の各スレッドに関して所与のゲストスレッドについて決定された個々の共通関心（上述のように計算されたもの）の合計として計算される。例えば、Ｔ２、Ｔ３、および、Ｔ４に関するＴ１の共通関心が計算される場合、Ｔ２に対するＴ１、Ｔ３に対するＴ１、および、Ｔ４に対するＴ１、のペアごとの共通関心が決定および合計されることで、Ｔ２、Ｔ３、および、Ｔ４を含むセットに対するＴ１の全共通関心が決定される。
【０５２７】
他のスレッドのセットに対するゲストスレッドの全共通関心を推定または他の方法で決定する時に、特定の個々の共通関心サイズ値が、合計からフィルタリングまたは除外されてよい。例えば、２つのスレッド間の共通関心が閾値より低い（例えば、ハミング重みが小さい）場合、値はフィルタアウトされる。一例として、特定のゲストスレッドがノード上でローカルに動作する１００の他のスレッドに関して評価されており、１００のスレッドの各々について、共通関心が１であると仮定する。合計すると、共通関心は１００であり、これは、要求側のゲストスレッドとノード上のその他のスレッドとの間の高い共通関心を示唆しうる。しかしながら、実際には、各スレッドとの共通関心は少量だけである。したがって、閾値より小さい個々の共通関心サイズが、共通関心の全体サイズを推定する時にフィルタアウトされてよい。
【０５２８】
いくつかの実施形態において、共通関心は、例えば、競合ページに対してストールが発生した時に、オンデマンドで評価される。例えば、後に詳述するように、共通関心は、ペアワイズリソースマイグレーションで計算または利用されてよい。したがって、共通関心は、ストールイベント中に（例えば、ページ競合フラグが設定された時に）、必要に応じて計算されてよい。
【０５２９】
いくつかの実施形態において、計算された２つのゲストスレッド間の共通関心のペアごとの各計算結果が、（例えば、二次元アレイに）格納される。いくつかの実施形態において、共通関心の計算結果は、タイムスタンプに関連付けられる。例えば、ストールごとにページ競合が存在する場合、共通関心は、どのストールの後にも変化することがなく、ストールが発生する度に共通関心を計算する必要はない。タイムスタンプは、最後の共通関心が計算された時を決定するために用いられてよく、ここで、共通関心は、十分な量または閾値量の時間が経過した場合に再計算される（すなわち、２つのスレッド間の共通関心は、最近計算された場合には、ストールごとに計算される必要はない）。
【０５３０】
メモリ状態：ページ競合に対処するためのゲストスレッドの移動は、将来的に複数のページを移動させうる。したがって、グルームされたセットがそのスレッドに対して生成された場所を知ることが、この決定を行うのに有用でありうる。（例えば、上記の関連セクションにおけるＡＰＩを参照）。
【０５３１】
いくつかの実施形態において、ページ競合の問題は、例えば、それがパフォーマンス（優良度メトリックによって特徴付けられうる）を害する場合、特別なケースとして（すなわち、本明細書に記載のストール対処とは異なって）解決されるだけでよく、いくつかの実施形態においては、ページ競合問題を解決するために、メモリ状態および他のスレッドとの関係性がネゴシエートされる。一部の例において、ゲストスレッドを同じ場所に配置することによって、ローカリティの点からさらなる利益を得て、ｐｃｐｕの利用可能性の点でシステムにストレスを掛けない場合には、そうすることを拒否する理由がない場合がある。
【０５３２】
ＶＩＯＰ：ページ競合のサブケースの一例は、Ｉ／Ｏ動作中にゲストスレッドがｖｉｏｐ（仮想入力／出力動作：ｖｉｒｔｕａｌ  ｉｎｐｕｔ／ｏｕｔｐｕｔ  ｏｐｅｒａｔｉｏｎ）と競合している場合である。いくつかの実施形態において、物理デバイスを表すｖｉｏｐが移動できない場合、競合するゲストスレッドは、ｖｉｏｐを含むノードに移動され、Ｉ／Ｏ活動が続く限りはそこにとどまる。別の実施形態では、ｖｉｏｐと、異なるノード上のゲストスレッドとの間でページを行ったり来たりさせるよりもコスト効率がよくなりうるため、Ｉ／Ｏ動作はリモートされる。
【０５３３】
／／ｖｉｏｐとページを共有するゲストスレッドとの間の競合がある場合、ｔｒｕｅを返す
【０５３４】
（ｂｏｏｌ）ｖｉｏｐ＿ｃｏｎｔｅｎｔｉｏｎ（ｇｐａ，ｇｕｅｓｔ＿ｔｈｒｅａｄ＿ｉｄ，ｖｉｏｐ＿ｔｈｒｅａｄ）；
【０５３５】
上述の履歴情報、メトリック、コスト項などは、メタデータとして格納されてよい。かかる情報は、例えば、スレッドがマイグレートを必要とするｖｃｐｕで動作している場合には、ノード間で転送されてもよい。仮想環境内で管理下にあるゲストページの数は、多数でありうる。スレッドの数も多数でありうるが、通常は、ページの数よりもはるかに少ない。したがって、わずか且つしばしば不完全なデータが、ページのワーキングセットとスレッドを関連付けるメタデータを効果的に管理するために、処理されるかまたは他の方法で対処される。スレッドおよびページを関連付けるメタデータは、サイズが大きくなりすぎたり（現行の特徴が予測不能に変化しうるために）古くなりすぎたりするのを防止されてよく、ここで、メタデータは、スレッドがマイグレートしうることを考慮して実装され、関連メタデータもマイグレートされる（メタデータによって参照されるページも移動されてよい）。一実施形態では、エージングブルームフィルタが、コンパクトな表現で上述のメタデータの一部を実装するために利用される。
【０５３６】
後に詳述するように、上述の（スレッドをページのセットに関連付ける）メタデータは、ｖｃｐｕストールの対処についての決定を行うための（例えば、重み付き非線形多項式内の）因子として用いられてよい。いくつかの実施形態において、ｖｃｐｕがストールした時に、それは、ゲストスレッドを実行している。上述のように、ゲストスレッドは、ゲストオペレーティングシステムの制御下で（かつ、ハイパーカーネルの制御下ではない）、ｖｃｐｕからｖｃｐｕへ移動してもよい。ハイパーカーネルは、スレッドがどのｖｃｐｕ上で動作していても、スレッドのアクセスのパターンについてのその決定を基礎としてよい。ｖｃｐｕがストールした時の対処を決定するためにその他の因子が用いられてもよい。
【０５３７】
いくつかの実施形態において、スレッドについての上述の記録された履歴および決定されたメトリック／因子は、スレッドごとに格納される。
【０５３８】
図１３Ｄは、ゲストスレッド（ゲストオペレーティングシステムで動作するスレッド）に関する情報を格納するために用いられるテーブルの実施形態の一例を示す。その他のタイプのデータ構造が、必要に応じて用いられてもよい。
【０５３９】
この例において、テーブル１３３０は、ゲストオペレーティングシステムで動作しているゲストスレッドを含む。各ゲストスレッドに続くのは、スレッド情報である。この例において、各行（例えば、行１３３２）は、例えば、その一意的な対応するＦＳ−Ｂａｓｅ０レジスタ値によって識別される異なるスレッドに対応する。各スレッドについて、上述のスレッドごとのメタデータ情報への参照が記録される。この例では、各スレッドについて、温かさ（１３３４）、利用度（１３３６）、および、共通関心（１３３８）が、テーブルに記録される。（ブルームフィルタなどのデータ構造を用いて表された）スレッドよるページアクセスの記録された履歴が、テーブルに含まれてもよい。その他のコスト項／メトリックが、テーブルに格納されてもよい。所与の行（スレッド）のセルは、別個の情報へのリンクまたは参照またはポインタを含んでもよい。次いで、テーブル（例えば、ハッシュテーブル）は、スレッドごとの情報を取得するために、スレッドでインデックス化されてよい。したがって、上述のように、ゲストスレッドおよび／またはゲスト物理アドレス空間を識別することにより、図１３Ｄの例に示したようなテーブルが管理されてよい。したがって、特定のスレッドが、（ｖｃｐｕのアイデンティティを担うｐｃｐｕで動作する）ｖｃｐｕに関連する情報でタグ付けされてよい。いくつかの実施形態において、スレッドメタデータのテーブルは、ＲＡＭ（ランダムアクセスメモリ）に格納される。
【０５４０】
いくつかの実施形態において、コンピュータシステム内の各ノードは、スレッドおよびスレッド情報のテーブルを有する。これは、特定のノードで実行しているすべてのスレッドのテーブルを効果的に形成する。スレッドに関する情報は、ノード間で転送されてもよい。
【０５４１】
図１３Ｅは、ワーキングセットおよびスレッドを関連付けるための処理の一実施形態を示すフローチャートである。いくつかの実施形態において、処理１３５０は、ハイパーカーネルによって実行される。処理は、ストールイベントの示唆が受信された時に、工程１３５２において始まる。いくつかの実施形態において、ストールイベントは、上述のように、非ローカルページ要求に関連する。別の実施形態において、ストールイベントは、上述のように、スレッドコンテキスト切り替えの検出に応じてトリガされる。
【０５４２】
工程１３５４では、ストールイベントに関連する仮想プロセッサの状態が保存される。これは、上述のように、内部レジスタ、プログラムカウンタなど、プロセッサ状態のブロックの保存を含む。
【０５４３】
工程１３５６では、参照されたゲスト物理アドレス空間およびゲストスレッド識別子の少なくともいずれか一方が、少なくとも部分的に、保存されたプロセッサ状態を評価することによって決定される。実施形態の一例において、プロセッサ状態の保存されたブロック内のＣＲ３レジスタの値が取得される。ＣＲ３レジスタ値は、仮想プロセッサで実行しているプロセス（ゲストスレッド）によって参照されたゲスト物理アドレス空間に対応する。いくつかの実施形態において、仮想プロセッサで実行するゲストスレッドの識別子は、プロセッサ状態の保存されたブロックのＦＳ−Ｂａｓｅ０レジスタ内の値（異なるゲストスレッドはＦＳ−Ｂａｓｅ０レジスタ値を有するので、この値は、ゲストスレッドを一意的に識別する）にアクセスすることによって取得される。
【０５４４】
工程１３５８では、履歴情報が、上述のように、工程１３５６における決定に少なくとも部分的に基づいて記録される。例えば、識別されたスレッドによってアクセスされた識別されたページが、スレッドによるページアクセスの履歴に記録されてよい。一例として、スレッドによるページアクセスの履歴は、ブルームフィルタなどのデータ構造を用いて格納される。様々なメトリックおよび因子が、記録された履歴に基づいて決定され、格納される（例えば、温かさ、利用度、共通関心、優良度、など）。
【０５４５】
したがって、ページｐを所与として、上述の技術を用いると、どのスレッドがｐに対する強い必要性を有するのかが決定されうる。さらに、スレッドｔを所与として、どのページがｔによって強く必要とされるのかが決定されうる。次いで、後に詳述するように、様々な処理が、かかる情報に基づいて実行されてよい。
【０５４６】
リソースマイグレーションネゴシエーション
【０５４７】
上述のように、いくつかの実施形態において、非ローカルリソースが、（例えば、ゲストスレッドのために実行している）ＶＣＰＵによって必要とされている時、それは、いくつかの既知の戦略（例えば、ページを所有するノードにリソースを要求するか、または、ｖｃｐｕがオーナーノードにマイグレートすべきか）のコストを計算しようとする。それらのコストが計算されると、ハイパーカーネルコードは、コスト多項式に基づいて最低コストの戦略を選択する。
【０５４８】
上述した例において、リクエスタ側での一連のコスト多項式が記載されており、ここで、要求されたリソースのオーナー側では、最低限の意思決定がなされうるか、または、意思決定が全くなされえない。ページが、移動不可能なデバイスによる現在の利用（例えば、移動できないハードドライブなどの物理デバイスによる直接メモリアクセス）によって、ノードに縛られている（ｗｉｒｅｄ）かまたはロックダウンされていることを除けば、ページは、通例、上記の例ではリクエスタに送信される。
【０５４９】
一部の例において、要求されたページをオーナーが送信することが、最適ではない場合がある。例えば、リクエスタノード上のｖｃｐｕがページを要求すると仮定する。しかし、ページを積極的に利用してきたオーナーノード上のｖｃｐｕが３０ある場合、要求されたページは、オーナー側で大量の利用があるので、要求されたページをリクエスタに送信することは最適ではない。その代わり、ｖｃｐｕがリクエスタからオーナーへマイグレートするのと併せて、オーナーが要求を拒否または拒絶または否認することが最適である。
【０５５０】
以下に記載の実施形態の例では、オーナーも、リクエスタから受信する要求にどう対処するのかを決定する方法を選択するために、一連のコスト多項式を有する（ｖｃｐｕがマイグレートすると決定した場合、要求がないので、オーナー側で決定を行う必要はない）。オーナー側の一連の多項式を用いて、コスト効率がよいのは、要求を拒否することなのか、または、要求されたページを送信／マイグレートすることなのかを判定する（対して、リクエスタ側の多項式は、ページを要求するのか、または、ページを要求するｖｃｐｕをマイグレートするのかを決定するために用いられる）。リクエスタ側およびオーナー側の両方で決定することにより、要求を処理する方法に関して、より良好または改善された決定がなされうる。
【０５５１】
いくつかの実施形態において、リクエスタおよびオーナーノードのコスト多項式は、互いに独立しており、他方がなくても存在しうる。
【０５５２】
リクエスタおよびオーナーの決定多項式についての決定およびコスト項の例を以下に述べる。以下に記載の例は、ページの要求に言及しているが、本明細書に記載の技術は、適用できる場合、任意のその他のタイプのリソースに対応するよう様々に適合されてよい。
【０５５３】
リクエスタ側の決定およびコスト項
【０５５４】
リクエスタ側の決定
【０５５５】
１．要求−−オーナーノードからリクエスタノードへリソースを送信することを要求する。
【０５５６】
２．マイグレート−−ゲストスレッドを実行するＶＣＰＵをオーナーノードへ移動させる
【０５５７】
リクエスタ側のコスト項
【０５５８】
１．受信された拒否−−いくつかの実施形態において、この項は、拒否が受信されたばかりのページが要求されていることを示す。いくつかの実施形態において、拒否が受信されたばかりのページを要求することは、要求の極端に高いコストに寄与する。
【０５５９】
２．スレッド効率−−いくつかの実施形態において、この項は、ゲストスレッドがいかに良好にこのノード上で実行してきたのかを規定する。いくつかの実施形態において、スレッド効率は、ミスの数と、（例えば、スレッドが実行中であり、ミスがない時の）スレッドランタイムとの比較に基づいて測定され、ここで、スレッドランタイムに比較してミスが少ないほど、スレッドの効率が高くなる。いくつかの実施形態では、ゲストスレッドがリクエスタノード上で良好に実行するほど、ＶＣＰＵ（およびＶＣＰＵ上で実行中のゲストスレッド）のマイグレーションのコストが高くなる。スレッド効率の尺度の一例は、優良度メトリックである。
【０５６０】
３．メモリ不足−−いくつかの実施形態において、この項は、要求側ノードがメモリ不足であるか否かを示す。いくつかの実施形態において、要求側ノードがメモリ不足であることは、リソースの要求にとって高コストになる。
【０５６１】
オーナー側の決定およびコスト項
【０５６２】
オーナー側の決定
【０５６３】
１．送信−−要求側ノードにページを送信する
【０５６４】
２．拒否−−新たな決定をすべきであることを要求側ノードに通知する
【０５６５】
オーナー側のコスト項
【０５６６】
１．縛られたページ−−いくつかの実施形態において、この項は、ページが、移動不可能なデバイスによって使用中であり、移動できないことを示す。いくつかの実施形態において、縛られたページは、リソースの送信にとって極端に高いコストになる。ページがマイグレート不可能なリソースまたはデバイスによって使用中であるか否かは、１セットのビットによって示されてよい。縛られたページのステータスは、一時的であり、時間と共に変化しうる（例えば、ページが直接メモリアクセスのためにハードドライブによってもはや利用されなくなった時）。
【０５６７】
２．効率の比較−−いくつかの実施形態において、この項は、リクエスタ側の要求スレッドが、要求されたページを用いるオーナーノード上のどのスレッドよりもはるかに良好に実行しているか否かを示す。いくつかの実施形態において、リクエスタ側の要求スレッドが、要求されたページを用いるオーナーノード上のどのスレッドに比べても良好に実行するほど、要求を拒否するコストが高くなる。
【０５６８】
３．ページの温かさ−−いくつかの実施形態において、この項は、要求されているページが、最近の要求によってオーナーノードに移動されたか否か、および、オーナーノード上で頻繁にアクセスされているか否かを示す。いくつかの実施形態において、値が高いと、「送信」のコストが高いことを示す。
【０５６９】
いくつかの実施形態において、コスト多項式について、項の各々は、その項がどれだけ重要であるかを表すように重み付けされる。一例として、「受信された拒否」コスト項は、その他のコスト項が何であっても、ページにマイグレートするよりもページを要求する方が、はるかに高コストであることを反映するように重み付けされてよい（すなわち、要求コスト＞マイグレートコスト）。同様に、「縛られたページ」コスト項は、拒否よりも送信の方が高コストであることを反映するように重み付けされてよい（送信コスト＞拒否コスト）。いくつかの実施形態において、これは、提示される選択肢の中に他の選択肢が存在しえないことを反映する。そうでなければ、いくつかの実施形態において、重みは、パフォーマンスの解析および調整に基づいた値に設定されてもよい。
【０５７０】
いくつかの実施形態において、短絡多項式評価が実行され、ここで、短絡制御メカニズムが、重みに加えてまたは重みの代わりに用いられる。重み付けおよび短絡の両メカニズムが用いられてよい。
【０５７１】
ページを要求するためのトランザクションの例
【０５７２】
以下は、ページを要求するためのトランザクションの一例であり、図１４Ａ〜図１４Ｅに関連して説明する。
【０５７３】
初期構成の例
【０５７４】
以下の例では、以下のシナリオを仮定しており、これについては図１４Ａに関連して説明する。
【０５７５】
図１４Ａは、ゲスト仮想マシンの初期構成の一例を示す。
【０５７６】
・ポッド内に２つのノードがある（Ｎｏｄｅ＿１  （１４０２）およびＮｏｄｅ＿２  （１４０４））（ここで、ポッドの一例は、図１のコンピュータシステム１００などの仮想化システムである）。
【０５７７】
・ＶＣＰＵ＿１（１４０６）が、Ｎｏｄｅ＿１上でＧｕｅｓｔ＿Ｔｈｒｅａｄ＿１（１４０８）を実行している
【０５７８】
・Ｐａｇｅ＿１（１４１０）が、Ｎｏｄｅ＿２上にある
【０５７９】
・ＶＣＰＵ＿２（１４１２）が、Ｎｏｄｅ＿２上でＧｕｅｓｔ＿Ｔｈｒｅａｄ＿２（１４１４）を実行している
【０５８０】
・ＶＣＰＵ＿３（１４１６）が、Ｎｏｄｅ＿２上でＧｕｅｓｔ＿Ｔｈｒｅａｄ＿３（１４１８）を実行している
【０５８１】
・この例では、その実行の一部として、Ｇｕｅｓｔ＿Ｔｈｒｅａｄ＿１が、Ｐａｇｅ＿１を必要とする。これは、要求を満たすために、ゲスト（オペレーティングシステム）から抜けて、ハイパーカーネルへ入らせる。この例において、上述のように、（Ｇｕｅｓｔ＿Ｔｈｒｅａｄ＿１を実行している）ＶＣＰＵ＿１は、１セットの関数（図１４Ｂの工程１４２０）を呼び出して、ページを要求するのか、ページを現在有するノードにマイグレートするのかを決定する（例えば、上述したリクエスタ側コスト多項式を評価することによって）。いくつかの実施形態において、関数のセットは、共通のアプリケーションプログラミングインターフェース（ＡＰＩ）を有する関数ポインタのアレイとして実装され、新しい値を取得するために重みを乗じた値を返す。値を得るために、関数によって返された値すべてが合計され、それらの個々の関数の各々について重みを乗じられる。こうして、最終的な多項式の結果値がマイグレーションコストについて得られ、一方で、別の多項式の結果値が要求コストについて得られる。最低コストの（すなわち、最も安価な）アプローチが取られる。マイグレーションコストおよび要求コストの計算に関するさらなる例を以下に記載する。
【０５８２】
段階１の例
【０５８３】
以下は、ページを要求するためのトランザクション例の第１段階の一例であり、これは、図１４Ｂに関連して説明され、図１４Ａの例の続きである。
【０５８４】
この例において、ＶＣＰＵ＿１は、コスト多項式（上で列挙したものなど）に基づいて、ハイパーカーネルにおいてコスト分析（リクエスタ側）を実行する。この例では、工程１４２０に示すように、これは初期要求であるので、「受信された拒否」（ＲＲ）コスト項は０である。この時点まで、スレッド効率は非常に良好であり、そのため、「スレッド効率」値および重みの組みあわせは５０であると仮定する。この例では、このノード上には利用可能な多くのメモリがあるので、「メモリ不足」（ＯＯＭ）のチェックは０である。これは、「要求」決定に対して０のコスト、および、「マイグレート」決定に対して５０のコストにつながる。したがって、この例において、結果は、（要求のコストがマイグレートのコストよりも低いので）Ｎｏｄｅ＿２からページを要求する結果となる。結果がマイグレートである場合、要求は行われない。
【０５８５】
この例において、ＶＣＰＵ＿１は、Ｐａｇｅ＿１の要求パケットを作成し、様々な実施形態において、スレッド効率に関する情報、そのページがこのスレッドによって（短時間の）過去に要求された頻度、および、要求タイプ（例えば、読み出し／書き込み、など）を含む。この情報は、例えば、相互接続ネットワークを介して、Ｎｏｄｅ＿２に伝送される。後に詳述するように、要求と共に伝送された情報は、要求を拒否するかまたは要求されたページを送信するかを決定する時に、オーナーノード（Ｎｏｄｅ＿２）によって用いられてよい。要求と共に伝送された情報のその他の例は、上述のように、温かさ、利用度、および、共通関心など、Ｇｕｅｓｔ＿Ｔｈｒｅａｄ＿１に対応するメタデータ情報を含む。スレッドについて記録された履歴も伝送されてよい。例えば、履歴のデータ構造（例えば、ブルームフィルタ）表現が、要求と共に伝送されてもよい。メタデータ情報の他の例と、リソースマイグレーションネゴシエーションにおけるそれらの利用については、後に詳述する。
【０５８６】
この例においては、この時点で、ＶＣＰＵ＿１は、Ｎｏｄｅ＿２からページまたはメッセージが到着するのを待つ。
【０５８７】
段階２の例
【０５８８】
以下は、ページを要求するためのトランザクション例の第２段階の一例であり、これは、図１４Ｃに関連して説明され、図１４Ｂの例の続きである。
【０５８９】
この例において、Ｎｏｄｅ＿２は、Ｐａｇｅ＿１を要求するパケットをＮｏｄｅ＿１から受信する。いくつかの実施形態において、ハイパーカーネルの通常動作の一部としてＮｏｄｅ＿２に格納された情報を用いて、Ｎｏｄｅ＿２は、例えば、上で列挙したオーナー側コスト項に基づいて、コスト分析（１４２２）を実行する。この例において、この分析の結果は、ページを送信するかまたは要求を拒否するかのいずれかを実行する決定である。
【０５９０】
例示の目的で、この例では、要求されたページが移動不可能なデバイスに縛られておらず、Ｎｏｄｅ＿２上のスレッドＧｕｅｓｔ＿Ｔｈｒｅａｄ＿２およびＧｕｅｓｔ＿Ｔｈｒｅａｄ＿３によって最近頻繁に用いられていたと仮定する。
【０５９１】
この例において、コスト項「縛られたページ」は、ページが移動不可能なデバイスによって積極的に利用されていないために、０を返す。この例では、重みがどうであっても、この項は０である。次に、この例において、効率についてのスレッドＧｕｅｓｔ＿Ｔｈｒｅａｄ＿２およびＧｕｅｓｔ＿Ｔｈｒｅａｄ＿３の分析の結果、かなりの効率になると仮定する。この例において、これら２つのスレッドは、リソースを得るために複数回のコールを行っており、Ｇｕｅｓｔ＿Ｔｈｒｅａｄ＿１ほど効率的ではない。最後に、この例において、「ページの温かさ」コスト項が、このページについて計算される。この例において、このページは、Ｎｏｄｅ＿２上のスレッドＧｕｅｓｔ＿Ｔｈｒｅａｄ＿２およびＧｕｅｓｔ＿Ｔｈｒｅａｄ＿３のために最近何度もアクセスされていたので、これは、送信のコストを高くする。
【０５９２】
２つの値の評価に基づいて、ページの送信について値「７５」および要求の拒否について値「５０」が決定される。この例では、それらの値に基づいて、要求が拒否される（要求を拒否するコストが、ページを送信するコストよりも低いため）。いくつかの実施形態では、拒否の理由が、拒否パケットの一部として含められ、拒否パケットは、この例においては、Ｎｏｄｅ＿１上で待機するＶＣＰＵ＿１に送り返される。
【０５９３】
段階３の例
【０５９４】
以下は、ページを要求するためのトランザクション例の第３段階の一例であり、これは、図１４Ｄに関連して説明され、図１４Ｃの例の続きである。
【０５９５】
この例では、拒否パケットがＮｏｄｅ＿１に返され、ＶＣＰＵ＿１は、Ｇｕｅｓｔ＿Ｔｈｒｅａｄ＿１を実行できるように、実行準備される。いくつかの実施形態において、ゲストへのリエントリにより、Ｐａｇｅ＿１上で再びストールが発生する。このストールは、ゲストから抜けてハイパーカーネルへ入ることを引き起こし、いくつかの実施形態においては、Ｐａｇｅ＿１アクセスの解決についての対処を決定するために、コスト分析が再び実行される。この事例において、「受信された拒否」コスト項は、正の値を返し、その項の重みを伴って、要求およびマイグレートの決定のための値は、段階１とは異なる結果に終わり、ここで、段階３では、ＶＣＰＵ＿１をＮｏｄｅ＿２へマイグレートさせる決定がなされる（マイグレートのコストが、今ではリソースを要求する新たなコストより低いため）。
【０５９６】
リクエスタ／オーナーネゴシエーションの上記の３段階の例で見られるように、この例のネゴシエーションの最終結果は、図１４Ｄの例に続く図１４Ｅの例に示すように、Ｐａｇｅ＿１の要求を満たすために、（Ｇｕｅｓｔ＿Ｔｈｒｅａｄ＿１を実行中の）ＶＣＰＵ＿１をＮｏｄｅ＿１からＮｏｄｅ＿２へ移動させることである。
【０５９７】
様々な実施形態において、リクエスタ決定（要求、マイグレート）を支援するための様々なコスト項、および、オーナー決定（送信、拒否）を支援するためのコスト項を追加できる。オーナー決定を支援するために用いられるコスト項のさらなる例については後に詳述する。
【０５９８】
図１４Ｆは、リソースマイグレーショングレーションネゴシエーションのための処理の一実施形態を示すフローチャートである。いくつかの実施形態において、処理１４３０は、ハイパーカーネル（例えば、ページの要求を受信したターゲットノード上のハイパーカーネルであり、ここで、ターゲットノードは、要求されたページを所有する）によって実行される。この例において、ターゲットノードと、要求の送信元であるリモートノードとの間のペアワイズリソースマイグレーションネゴシエーションが実行される。処理は、リソース（例えば、物理メモリのページなど、物理メモリの必要な部分）の要求が受信された時に、工程１４３２で始まる。
【０５９９】
例えば、要求は、第１ノード（要求の送信元である「リクエスタノード」または「発信元ノード」とも呼ばれる）上のｐｃｐｕで動作するｖｃｐｕによってなされる。要求を行うｖｃｐｕは、メモリの要求されたページを必要とするゲストスレッドを実行している。例えば、ゲストスレッドを実行している時、仮想プロセッサは、ゲストスレッドによって必要とされるページにアクセスできなかった（例えば、ページが発信元ノードでローカルに利用可能ではないため）。ストールイベントが発生した。ここで、ゲストスレッドは、物理メモリの必要とされるページにアクセスすることができない限りは、その処理を継続することができない。上述のように、発信元ノード上のｖｃｐｕは、１セットのコスト関数（例えば、多項式）を評価して、適切な戦略（メモリの必要なページに近づくために自身を発信元ノードにマイグレートするか、または、メモリの必要なページの要求を送信するか）を決定する。この例において、ｖｃｐｕは、メモリの必要なページを要求する方が低コストであると決定した。したがって、発信元ノード上のゲストスレッドが非ローカルのページ要求でストールしたことに応答して、要求が、発信元ノードによって送信され、（要求されたページを所有する）ターゲットノード１４０２によって受信される。
【０６００】
受信された要求は、メタデータ情報も含み、その情報の少なくとも一部は、要求されたページを送信するかまたは要求を拒否するかを決定するために、ターゲットノードによって用いられる。要求は、要求されているリソースの識別子（例えば、要求されている物理メモリのページのｇｐａ）を含む。要求に含まれるメタデータ情報は、メモリの要求されたページを必要とするゲストスレッドに対応するスレッドごとのメタデータを含む。メタデータ情報は、相互接続ネットワークを介してオーナーノードに伝送される要求パケットに含まれてよい。
【０６０１】
例えば、図１４Ｂの段階１の例に関連して説明したように、要求は、スレッド効率に関する情報、要求されたページがリクエスタノード上のゲストスレッドによって短期間の過去に要求された頻度、および、要求タイプ（例えば、読み出し、書き込みなど）を含んでよい。
【０６０２】
リクエスタノードからの要求に含まれるスレッドメタデータ情報のその他の例は、温かさ、利用度、優良度／スレッド効率、アフィニティ、デューティ、（例えば、フラグによって示される）ページ競合、共通関心のサイズなど、上述したようなメタデータ情報を含む。要求を行うリクエスタ側のｖｃｐｕにおけるゲストスレッドのアクセスの（最近の）履歴も、要求に含まれてよい。上述のように、アクセスの最近の履歴は、ビットのアレイを用いてかかる情報を表すブルームフィルタに格納されてよい。送信されたアクセス履歴は、特定の最近の期間または時間窓内のアクセス、もしくは、例えば、メモリのページを必要とするリクエスタ側のゲストスレッドによってなされた最も最近のアクセスのセット（例えば、最新の１０，０００アクセス、または、任意の適切な数の最も最近のアクセス）を含んでよい。
【０６０３】
工程１４３４では、受信された要求に含まれる情報に少なくとも部分的に基づいて、メモリの要求された部分を送信するかまたは要求を拒否するかの決定がなされる。決定は、１セットのコスト関数／多項式を評価することによってなされてよい。
【０６０４】
コスト関数／多項式のセットは、リクエスタノードからの要求に含まれる情報、および、ハイパーカーネルの通常動作の一部としてオーナーノードに格納された情報を考慮してよい。例えば、オーナーノードでのコスト分析は、上で列挙したオーナー側コスト項に基づいてよい（例えば、縛られたページ、効率の比較、ページの温かさ、など）。オーナー側コスト項の別の例は、リクエスタノードから以前に受信した要求の数である。
【０６０５】
戦略（すなわち、ページを送信するかまたは要求を拒否するか）のコストを評価する／決定する時、リクエスタノードからの要求内のスレッドメタデータ情報の一部は、オーナーノードに格納された情報と直接的に比較／ネゴシエートされうるが、リクエスタノードからのその他のメタデータ情報は直接的にネゴシエートされない。
【０６０６】
直接的にネゴシエートされうる要求に含まれる情報の例は、明確に比較できる直接的な対応物／等価なメトリックをオーナーノード上に有する情報を含む。様々な実施形態において、かかる直接的にネゴシエートできる情報は、温かさ、利用度、および、共通関心のサイズを含む。
【０６０７】
例えば、リクエスタ側からの要求に含まれるスレッドごとの情報は、オーナー側によってアクセス可能な／格納されたローカルノードレベルの情報と比較されてよい。オーナー側の情報は、（要求されたページを含む）オーナー側によって現在所有されているページに関する情報を含みうる。
【０６０８】
一例として、要求に含まれるスレッドごとの温かさ情報は、要求されたページが（現在リクエスタ側にある）ゲストスレッドによってどれだけ最近にアクセスされたのかを示しうる。オーナー側の温かさ情報は、要求されたページが、オーナー側ノードでローカルに動作または実行しているスレッドによってどれだけ最近にアクセスされたのかを示しうる。
【０６０９】
別の例として、オーナー側の利用情報は、或る期間にわたって、要求されたページにアクセスしたオーナー側で動作するスレッドの数、および、その頻度（例えば、最近の１０秒間に、１スレッドが、要求されたページに一度アクセスした、など）を示す情報を含む。この情報は、ページが（任意のスレッドによって）そのノード上で非常に利用されているか否かを判定するために用いられてよい。オーナー側で、要求されたページの利用度が高い場合、ワーキングセットの中断につながることから、そのページを引き渡すべきではない（ここで、ノード上のすべてのスレッドが、それらの求めるページと同じ場所にあることを保証するために時間および労力が以前に費やされている）。したがって、オーナー側で構築されたこのワーキングセットを中断するコストは、高いはずである（そして、要求されたページは容易に手放すべきではない）。
【０６１０】
利用度に関して、オーナー側は、リクエスタ側で実行中のゲストスレッドに対応する利用情報も有してよい。例えば、ゲストスレッドは、以前にオーナー側で実行されている場合があり、スレッドの動作についての履歴情報もオーナーノードに存在しうる。かかる利用情報がターゲットオーナーノードで利用可能である場合、その情報は、要求内の利用情報と比較されてよい。オーナー側利用情報が利用できない場合、かかる比較はなされる必要がない（すなわち、オーナーノード上にゲストスレッドの履歴がないので、ネゴシエートする関連情報がない）。どの情報がオーナー側にありうるかの保証がなくても、温かさ／利用情報が比較／ネゴシエーションのためにオーナー側で利用可能である／格納されている場合には、要求は、かかる情報を含みうる。
【０６１１】
オーナー側コスト分析で利用されうるが直接ネゴシエートされないリクエスタ側からの要求に含まれる情報の例は、発信元／リクエスタノードに関して要求側ｖｃｐｕにおけるゲストスレッドについて計算された情報を含むが、それに対しては、ターゲット／オーナーノードの対応物はない。様々な実施形態において、直接的にネゴシエートできないかかる情報は、優良度、アフィニティ、デューティ、ページ競合、および、記録された履歴を含む。例えば、ゲストスレッドがノード上でそのデューティ（例えば、上述のように、リクエスタノードに到着して以来の閾値数のアクセス）を完了させたか否かを示すデューティに関して、ページを必要とするゲストスレッドは実際にはオーナーノード上にはないので、オーナーノードに関してゲストスレッドについてのデューティを決定することはできない。
【０６１２】
別の例として、リクエスタ側のゲストスレッドは、オーナー側で実行していないが、要求に含まれるゲストスレッドの最近のアクセス履歴は、ゲストスレッドがオーナー側でローカルに実行されてきた場合のゲストスレッドの動作方法または実行方法を決定するために、オーナー側で用いられてよい。
【０６１３】
ページ競合に関しては、要求が、送信されたページ競合フラグを含む場合、これは、要求されたページが、ページにアクセスしようとするリクエスタ側のゲストスレッドによって非常に必要とされていることを、オーナー側に示す。上述のように、ページ競合が存在する場合、優良度メトリック、スレッドの頻度、および、共通関心などのコスト項は、取るべき行動の決定を容易にするために用いられてよい。
【０６１４】
例えば、２（またはそれ以上）のゲストスレッドが、同じページについてページ競合する場合がある。２つのスレッドが同じノード上に共存するのがよいか否かを判定するために、共通関心の計算が用いられてよい。例えば、（リクエスタ側の）競合するゲストスレッドがリクエスタ側で実行中のその他のゲストスレッドとの間に有する共通関心のサイズは、リクエスタ側のゲストスレッドがオーナー側でローカルに実行中であるゲストスレッドとの間に有する共通関心のサイズと比較されてよい。共通関心は、上述の技術を用いて（例えば、ハミング重みを合計および決定することによって）計算されてよい。
【０６１５】
リクエスタ側のスレッドに対するゲストスレッドの共通関心のサイズが取得され（例えば、動的に計算されるか、または、最近計算された共通関心が取得されてもよい）、要求に含められてよい。
【０６１６】
ゲストスレッドは、オーナー側で実行中ではないが、オーナー側のスレッドのセットに対する（リクエスタ側で実行中の）ゲストスレッドの共通関心は、ゲストスレッドのアクセスパターン履歴が要求に含まれる場合には決定されうる。上述のように、要求に含めてアクセスパターン履歴を送信することにより、オーナー側は、ゲストスレッドがオーナー側でローカルに実行されてきた場合のゲストスレッドの動作方法または実行方法を決定してよい。例えば、ゲストスレッドのアクセスのパターンは、ゲストアプリケーションによって規定され、ゲストスレッドがどのノード上で実行しているのか、とは関係がない。ゲストスレッドがオーナー側で実行してきた場合、同じパターンのアクセスがなされただろう（ゲストスレッドの位置によって異なりうるものは、どのアクセスがヒットまたはミスであるかということである）。
【０６１７】
したがって、要求内のスレッドのアクセスパターン履歴を受信することにより、オーナー側でローカルに実行中のスレッドに対するゲストスレッドの共通関心が計算されうる。例えば、上述のように、オーナー側で、オーナー側でローカルに実行中の各ゲストスレッドに対する（ページの要求を行ったｖｃｐｕ内の）ゲストスレッドの共通関心の個々の推定値が計算および合計（または他の方法で集計）される（ここで、共通関心の個々の推定値は、それらが閾値未満である場合、合計から除外またはフィルタリングされてよい）。
【０６１８】
いくつかの実施形態において、共通関心の計算は、要求されたページに対するゲストスレッドによるページ競合の決定に応じてトリガされる。上述のように、いくつかの実施形態において、共通関心の計算は格納され、共通関心が最後に推定された時を示すタイムスタンプと関連付けられてよい。（リクエスタ側またはオーナー側のいずれかまたは両方での）ストールに適用可能な共通関心の値が、（例えば、閾値期間内に）最近計算された場合、共通関心の推定値（または推定値の一部）は、（その閾値期間内に変化した可能性が低いので）再計算される必要はなく、それらの最近の値が再利用される（したがって、再計算を避けて、利用される計算リソースの量を削減できる）。
【０６１９】
（要求を行うｖｃｐｕ内の）対象ゲストスレッドが（リクエスタ側のスレッドと比較して）オーナー側のスレッドとの間に大きい共通関心を有する場合、これは、要求を拒否するコストの低下（または送信するコストの上昇）に寄与しえ、ゲストスレッドをオーナー側にマイグレートさせることになる。
【０６２０】
したがって、ゲストスレッドが要求されたページに対する高い要求を高頻度で有するか否かを判定することに加えて、ゲストスレッド間でのアクセスページの重複、および、（例えば、最近）オーナーノードで実行中のスレッドとのアクセスページの重複が、要求されたページを送信するかまたは要求を拒否するかの戦略決定を行う際に利用されてよい。
【０６２１】
上述のように、ページ競合が存在する場合、オーナー側がどのような決定をすべきかを決定するために、優良度メトリック／スレッド効率が用いられてもよい。例えば、競合するゲストスレッドがリクエスタ側で良好に実行していない（例えば、ページ競合フラグが設定され、リクエスタノードで実行している時のゲストスレッドの優良度メトリック値が低い）場合、ページ要求が拒否され、スレッドをオーナーへマイグレートさせることが好ましい。
【０６２２】
いくつかの実施形態において、直接的にネゴシエートできない情報は、タイブレークを実行するために用いられてよい。例えば、リクエスタ側およびオーナー側の対応物を有するメトリックの比較（例えば、リクエスタ側の情報およびオーナー側に格納された情報を用いた比較）を実行した後に、タイ（同点）であると決定された場合に、優良度、アフィニティなどがタイブレークを実行するために用いられてよい。例えば、スレッドが、高い効率／優良度、または、リクエスタノードへのアフィニティを有する場合、オーナーノードは、多項式を用いて、ページをリクエスタノードに送信するよう決定しうる。一方で、スレッドが、低いアフィニティまたはリクエスタノード上で低い優良度／効率を有する場合、オーナーノードは、要求を拒否するよう決定し、スレッドを実行するｖｃｐｕをオーナーノードにマイグレートさせうる。等価な対応物のない因子も、（タイブレーク中に用いられるだけでなく）多項式計算の一部として用いられてよい。
【０６２３】
オーナー側コスト項のその他の例は、上述のように、要求されたページが縛られているか否か、効率の比較、および、ページの温かさを含む。例えば、要求されたページがオーナーノードに現在縛られている（例えば、ＤＭＡのためにディスクによってアクセスされている）場合、オーナー側で行われてきた処理を阻害することになるので、ページの送信は、非常に高コストになる。
【０６２４】
いくつかの実施形態において、ページ送信のコストおよび要求拒否のコストが計算される。最も低いコストを持つ動作（ページ送信または要求拒否）が、実行される動作である。
【０６２５】
工程１４３６では、決定に少なくとも部分的に基づいて、応答が提供される。例えば、要求されたページを送信する決定が、ターゲット／オーナーノードでなされた場合、ページは、発信元／リクエスタノードへ送信される。いくつかの実施形態において、適切なデータ構造およびマッピングが、物理メモリのページの新たな位置を示すように更新される。例えば、オーナーは、メモリのページがリクエスタに送信されたことを記録してよく、その結果、現時点では以前のそのページのオーナーがページの要求を受信した場合に、ページの現在のオーナーに要求をリダイレクトできる。
【０６２６】
例えば、要求が拒否される（すなわち、要求コストがページの送信コストよりも低い）場合、拒否メッセージ（例えば、パケット）が、リクエスタ／発信元ノードへ送り返される。この例では、拒否に応答して、リクエスタノードのｖｃｐｕは、そのコスト関数のセットを再評価してよい（例えば、図１４Ｄに関連して説明した段階３の例で述べたように）。再評価は、以前の要求の拒否、または、要求が拒否された理由など、新しい情報を考慮に入れてよい。ページのマイグレートおよび／または要求のための新たなコストが計算されてよく、リクエスタは、決定された新たなコストに基づいて動作を選ぶ。
【０６２７】
例えば、リクエスタノードのｖｃｐｕが、再評価に基づいて、自身をターゲットノードにマイグレートするよう決定した場合、そのｖｃｐｕは、上述のようにマイグレートされる。ｖｃｐｕは現在新しいノード上にあるので、マイグレートされたｖｃｐｕで実行中のゲストスレッドに関連するスレッド情報も更新される。例えば、ゲストスレッドは現在新しいノード上にあるので、スレッドごとのメタデータ情報（温かさおよび利用度など）が更新される。
【０６２８】
別の例として、ディスクが、要求されたページへの直接メモリアクセスを実行していたために、オーナー側が要求を拒否したと仮定する。かかるＤＭＡは、一時的な動作である傾向がある。この情報に基づいて、リクエスタ側のハイパーカーネルは、ページを再び要求するが要求を行うのに待機もすると決定してもよい（例えば、マイグレートするか要求するかの決定に加えて、リクエスタ多項式は、再び要求しようと待つか否かを計算するために用いられてもよい）。いくつかの実施形態において、オーナー側のハイパーカーネルは、送信するか要求を拒否するかを決定するのに加えて、要求を再び試みるようリクエスタに命令するなど、別の動作を決定してもよい。
【０６２９】
したがって、上述のように、いくつかの実施形態において、ストール時に、ゲストスレッドは、リソースのオーナーに要求を送信する。いくつかの実施形態において、この要求は、ノード間でさらなるローカリティ情報（例えば、ゲストスレッドに関する上記のメタデータ情報の例）を通信するために利用できる比較的多量の未使用空間を有しうるメッセージである。ノードのペアの間でのこの情報交換は、上述のように、２つのノード間の或るローカリティネゴシエーションを実行するために用いられる。また、ペアごとのネゴシエーションは、グローバルに一貫した状態情報を維持する必要性に置き換わりうる。ペアごとのネゴシエーションを通して、すべてのゲストスレッドについて、十分によい状態に収束されうる。１−ｎ（１ノード対多ノード）タイプのネゴシエーションが用いられてもよいが、より高価でありうる。かかるネゴシエーションに関する詳細については、「リソースマイグレーションネゴシエーション」のセクションで上述しており、そこでは、ネゴシエーション中に他のノードに送信された情報のタイプの例も記載されている。様々な共通コストメトリックが、比較のために特定されてよい。例えば、共通関心のサイズの推定値は、２つのノード間で単一のゲストスレッドについて比較されてよく、コストの値ではないが、その代わりに、ゲストスレッドが潜在的に他のゲストスレッドとより共通した関心を有するノードの識別子である答えを提供する。この情報は、上記の例で記載したように、ネゴシエーションの効率を改善するために有益でありうる。上述のように、様々な実施形態において、優良度メトリック、メモリ状態、および、デューティ情報が、ネゴシエーション実行時に送信される。かかる情報は、共通関心およびその他の状態情報でさらに拡張されてもよい。かかる情報は、上述のように、多くの利用可能な空間を有する要求メッセージに追加される（例えば、これらのさらなるネゴシエーションパラメータがなければ、要求メッセージがほとんど情報を保持していないと仮定する）。
【０６３０】
ハイパーカーネル、イベントテーブル、および、タイダルツリーのさらなる詳細および実施形態
【０６３１】
ハイパーカーネルスレッド
【０６３２】
以下に記載の例は、ＦｒｅｅＢＳＤスレッドについて様々な言及を行う。ＦｒｅｅＢＳＤは、ハイパーカーネルが協働しうるホストオペレーティング環境の一例にすぎず（例えば、ここで、ハイパーカーネルは、ＦｒｅｅＢＳＤのサービス（Ｉ／Ｏおよびスレッド管理のためのサービスなど）を利用して、ＦｒｅｅＢＳＤと共に働く）、本明細書に記載のＦｒｅｅＢＳＤの機能の一部または全部が、別のホストオペレーティング環境と共に、または、ＦｒｅｅＢＳＤを利用することなしに、再実装されてよい。例えば、ハイパーカーネルは、ＦｒｅｅＢＳＤを全く利用しないように書かれてもよい。一例として、ＦｒｅｅＢＳＤなどのホストオペレーティングシステムを用いる代わりに、マルチスレッディングマイクロカーネルが、任意の必要な機能を提供するために構築されうる。これは、ホストオペレーティングシステムへの依存を最小化する。オプションを最大化するために、ＦｒｅｅＢＳＤとハイパーカーネルとの間の相互作用の回数が制限されてよい。例えば、ＦｒｅｅＢＳＤは、スレッド管理サービスを提供し、それらのサービスの一態様は、スレッドスケジューリングである。ＦｒｅｅＢＳＤスケジューラは、スレッドに基本的な抽象化を提供し、スレッドは、物理プロセッサに割り当てられてよい（すなわち、ＦｒｅｅＢＳＤスケジューラは、実物理プロセッサ上にスレッドを割り当てるエンティティである）。通例、ＦｒｅｅＢＳＤよりむしろ、ハイパーカーネルが割り当てを制御することが望ましい。ハイパーカーネルスケジューラとＦｒｅｅＢＳＤスケジューラとの間の相互作用は、減少されうる。ハイパーカーネルスケジューラに関するさらなる詳細については、後に記載する。
【０６３３】
ホストは、ユーザモードまたはカーネルモードのいずれかで動作してよい。ハイパーカーネルによって実行される処理は、ホストのユーザモードまたはカーネルモードのいずれかにあってよい。例えば、ハイパーカーネル処理は、ＦｒｅｅＢＳＤにおけるユーザモードとカーネルモードとの間のコンテキスト切り替えの回数を削減するために、カーネルモードで実行されてよい。これは、レジスタの保存および格納、セキュリティ手段の管理など、オーバーヘッドを削減する。例えば、イベントテーブルは、ハイパーカーネル内でカーネルモードで実行されてよい（すなわち、ＦｒｅｅＢＳＤカーネルモードで実行する）。
【０６３４】
全体にわたって記載した実施形態の例において、ゲストオペレーティングシステム（およびゲストオペレーティングシステム上で動作するゲストアプリケーション）は、実際には、ゲストオペレーティングシステムが、ハイパーカーネルによって提供されたｖｃｐｕを管理している時に、自身が物理プロセッサを管理していると考える。ゲストオペレーティングシステムは、ゲストスレッドも管理する（ここで、ゲストオペレーティングシステムは、自身のスレッドスケジューラを有する）。これらのゲストスレッドは、（ゲストオペレーティングシステムの視点からは、物理プロセッサである）ｖｃｐｕにおいて実行する。ゲストスレッドが生成されると、それらは、名称（例えば、ビット列である識別子）を割り当てられる。上述のように、ゲストオペレーティングシステムは、特別なレジスタ（例えば、ＦＳ−Ｂａｓｅ０レジスタ）にゲストスレッドの名称を配置し、そのレジスタは、ハードウェアアーキテクチャによってハイパーカーネルから見えるようになっている。したがって、ゲストスレッドは、識別されうる（ここで、ゲストスレッドは、ＦｒｅｅＢＳＤスレッドとは異なる空間にある）。ゲストスレッドは、ゲストスレッドを実行するｖｃｐｕのアイデンティティを物理プロセッサが担う場合に実行される。
【０６３５】
各ハイパーカーネルインスタンスに維持されるハイパーカーネルスレッドのタイプの３つの例は、以下を含む：ハウスキーピングスレッド、Ｉ／Ｏスレッド、および、ｖｃｐｕスレッド。いくつかの実施形態において、ハイパーカーネルスレッドの数は、初期化時に知られ、各ハイパーカーネルインスタンスは、それが開始時にその上で実行中であるノード上のすべてのスレッドを生成してよい。
【０６３６】
実施形態の一例において、ハイパーカーネル初期化の時に、各ノードで実行する各ハイパーカーネルインスタンスは、ハイパーカーネル内の各ｖｃｐｕおよび各ｖｉｏｐ（仮想入力／出力動作）を表すために、ＦｒｅｅＢＳＤスレッドを作成する。結果として、この実施形態の例においては、各ｖｃｐｕおよび各ｖｉｏｐが各ノード上に一意的な対応するＦｒｅｅＢＳＤを有することになる。補助スレッドが、ハイパーカーネルインスタンスによって生成されてもよい。
【０６３７】
ｖｃｐｕスレッドは、ｖｃｐｕを表すために用いられるＦｒｅｅＢＳＤスレッドであり、ｖｃｐｕおよびそのデータ構造に関連するソフトウェアを実行する。上述のように、各ｖｃｐｕ（仮想化システムにとってグローバルであり、クラスタ内の任意のノード上に存在しうる）は、各ノード上の一意的な対応するＦｒｅｅＢＳＤスレッド（本明細書ではサロゲートｖｃｐｕスレッドと呼ぶ）を有する。例えば、クラスタに４つのノードがある場合、各ｖｃｐｕは、４つのノードの各々に１つずつの４つのサロゲートｖｃｐｕを有する。ｖｃｐｕスレッドは、エンプティまたはフルのいずれかであってよく（すなわち、それぞれ非アクティブまたはアクティブ）、ここで、ｖｃｐｕに対して１つのｖｃｐｕスレッドのみが、同時に実行すなわちアクティブになり（ｖｃｐｕに対するすべての他のサロゲートｖｃｐｕは、エンプティすなわち非アクティブである）、ゲストオペレーティングシステムの違反になる（ここで、１つのｖｃｐｕが２つの異なるｐｃｐｕ上で実行すべきではない）ことから、２つのノードが同じｖｃｐｕに対するアクティブなｖｃｐｕスレッドを有することは決してない。ｖｃｐｕは、同時に１つのノード上にしか存在しえず、ここで、ゲストオペレーティングシステムのためのｖｃｐｕを実行しているｖｃｐｕスレッドは１つだけであり、その他の非アクティブなｖｃｐｕスレッドは待機している。したがって、サロゲートｖｃｐｕスレッドは、ｖｃｐｕのためのプロキシとして機能し、ｖｃｐｕが実行している位置（ノード）の代わりに処理を行う（例えば、ｖｃｐｕスレッドがノード上のｖｃｐｕを実行し、一方で、ｖｃｐｕ自体は任意のノード上で動作しうる）。クラスタのノード上のサロゲートスレッドを利用して、例えばｖｃｐｕマイグレーション中に、ロッキングおよび同期の必要性を排除する。
【０６３８】
ｖｃｐｕスレッドは、ゲストオペレーティングシステム内のｖｃｐｕを実行しているか、または、ゲストオペレーティングシステム内のｖｃｐｕを実行しておらず、いくつかの他の動作を実行しうるか、いずれかである。例えば、ｖｃｐｕスレッドは、ｖｃｐｕのアイデンティティを担うよう命令される或る時点まで、ハイパーカーネルコードを動作／実行してよい。例えば、Ｉｎｔｅｌアーキテクチャにおいて、ｖｃｐｕスレッドは、ＶＭエンター命令を実行してよく、その時点で、それは、ゲストｖｃｐｕ内で命令を実行している（そして、例えばＶＭイグジットが発生するまでは、ハイパーカーネルで命令を実行していない）。例えば、ｖｃｐｕスレッドがゲストオペレーティングシステム内でｖｃｐｕを実行している間にページフォールトが発生したので、ＶＭイグジットが発生しうる。ページフォールトは、ＶＭイグジットを発生させる。次いで、ｖｃｐｕスレッドは、ゲストオペレーティングシステムコードの実行を停止し、その代わりに、ハイパーカーネルコードの実行を開始する。次いで、ｖｃｐｕスレッドは、ｖｃｐｕについて、ハイパーカーネルコードを用いて、（例えば、上述のコスト関数／多項式を用いて）ｖｃｐｕをマイグレートするかページの要求を送信するかを決定する。ｖｃｐｕスレッドは、それに対応するｖｃｐｕのためにのみ決定を行い、その他のｖｃｐｕには行わない。
【０６３９】
ｖｃｐｕスレッドが（所与のノード上の）ｖｃｐｕに関連する作業を実行する方法の一例は、以下の通りである。例えば、ｖｃｐｕがターゲットノードにマイグレートされると仮定する。マイグレートすると、ｖｃｐｕのプロセッサの状態が、（例えば、継続を作成する際に格納されるように）明示的にメモリに保存される。次いで、この保存されたメモリは、（例えば、かかるネットワーキングを扱うよう構成されたネットワークスレッドによって）ターゲットノードへメッセージとして送信される。次いで、ターゲットノード上のサロゲート／補助スレッドは、ウェイクアップするよう信号送信または通知され、ターゲットノード上のｐｃｐｕで実行される（ＦｒｅｅＢＳＤは、ｐｃｐｕにｖｃｐｕスレッドを割り当てるために呼び出されてよく、ここで、ホストオペレーティングシステムは、物理プロセッサ上にスレッドをスケジューリングするために用いられる）。ｖｃｐｕスレッドは、現在ｐｃｐｕ上で実行中であり、（メッセージに含まれるプロセッサ状態を用いて）ストールしたｖｃｐｕの状態を自身に復元する。ＶＭエンターが実行される。ターゲットノード上のｐｃｐｕが、今や、ｖｃｐｕのアイデンティティを担っている。次いで、ｐｃｐｕは、ゲストオペレーティングシステムに戻ってよく、ｖｃｐｕスレッドは、（ハイパーカーネルコードの代わりに）ゲストコードを実行し続ける。ゲストオペレーティングシステムの視点からは、フォールトが観察されなかった（ハイパーカーネルは、フォールトを阻止し、ｖｍイグジット／エンターを実行した）。その代わり、ゲストオペレーティングシステムは、ページへのアクセスを試み、次の命令で、すでにページにアクセスしていた（ここで、ゲストオペレーティングシステムは、ハイパーカーネルによって実行された根底にあるマイグレーションを認識していない）。上述のように、クラスタのノード上のサロゲートスレッドを利用して、ｖｃｐｕマイグレーション中にロッキングおよび同期の必要性を排除し、ここで、ｖｃｐｕに対して１つだけのｖｃｐｕスレッドが同時に実行しており（ｖｃｐｕに対するすべての他のサロゲートｖｃｐｕスレッドは、エンプティである）、２つのノードが同じｖｃｐｕに対するアクティブなｖｃｐｕスレッドを有することは決してない（すなわち、ｖｃｐｕは、同時に１つのノード上にのみ存在しうる）。
【０６４０】
この例において、ＦｒｅｅＢＳＤは、ｖｃｐｕスレッドのスケジューリングを制御しない。その代わり、ｖｃｐｕスレッドは、初期化時に、待機状態で開始する。ｖｃｐｕスレッドは、ハイパーカーネルがｖｃｐｕにウェイクアップするように信号を送信した時に、実行を開始するよう信号送信されるだけである。例えば、後に詳述するように、ハイパーカーネルスケジューラおよびタイダルツリーは、ｖｃｐｕスレッドをバインドすることでアクティブにする（例えば、ｖｃｐｕが所与のノード上で実行を開始できるように、そのノード上のｖｃｐｕのためのｖｃｐｕスレッドをウェイクアップする）。かかるｖｃｐｕスレッド（これらは、データ構造である）を作成することは、比較的コストがかからず、待機中には、全く処理を実行しない（または計算リソースを使い尽くさない）。ｖｃｐｕを実行しているｖｃｐｕスレッドは、ｖｃｐｕの表現であり、ハイパーカーネルの視点からは、スケジュール可能なエンティティである（ここで、後に詳述するように、ｖｃｐｕスレッドは、ハイパーカーネルの制御下でウェイクアップまたはスリープするよう信号送信されうる）。様々な時点で、ｖｃｐｕスレッドは、ゲストスレッドを実行しているが、別の時点では、実行していない場合がある。例えば、ｖｃｐｕがノード上で実行している時、対応するｖｃｐｕスレッドは、（ゲストスレッドを実行している）ｖｃｐｕを実行している。ｖｃｐｕスレッドが実行していない時（例えば、ｖｃｐｕが、ｖｃｐｕスレッドの存在するノード上で実行していない時）、ｖｃｐｕスレッドは、待機中またはスリープ中であってよい。
【０６４１】
ｖｃｐｕが実行している（例えば、継続ではない）場合、それは、ｖｃｐｕスレッドで実行している。計算の実行がｖｃｐｕスレッドでなされ、ここで、ｖｃｐｕがゲストスレッドを実行している場合、それは、ゲストスレッドを実行しているｖｃｐｕスレッドである（ここで、ゲストスレッドは、ゲストオペレーティングシステムによって管理される）。
【０６４２】
ｖｃｐｕスレッドが実行している時、ゲストスレッドが物理プロセッサであると考えているものに対応するレジスタ状態は、実際にはｐｃｐｕ上で実行している（ここで、ｐｃｐｕは、１セットのプロセッサ状態を有するｖｃｐｕのアイデンティティを担っている）。ｖｃｐｕスレッドが実行している時、仮想プロセッサ状態情報が利用されている。例えば、ゲストスレッドは、プログラムカウンタ、レジスタなどを持っている。ゲストスレッドがタイダルツリー内にスケジューリングされ、ｖｃｐｕ上で実行を開始する時、ｖｃｐｕは、プログラムカウンタ、レジスタなどを継承する。ｖｃｐｕが動作している時、それは、ゲストが物理プロセッサであると考えているもののビット対ビットの正確な表現であり、実際、ｖｃｐｕは、物理プロセッサ上で動作している（すなわち、物理プロセッサは、ｖｃｐｕのプロセッサ状態を取ることによってｖｃｐｕのアイデンティティを担う）。任意の時間に、ｖｃｐｕが物理プロセッサ上で動作している時、それは、ゲストが物理プロセッサとして考えているものと正確に一致する。物理プロセッサが仮想プロセッサにバインドされると、仮想プロセッサに関連するすべてのレジスタは、ゲストオペレーティングシステムが物理プロセッサであると考えているものに関連する情報と同じである。オペレーティングシステムがベアメタル上で実行している場合、ｐｃｐｕは、ｖｃｐｕと同じ状態を有することになる。
【０６４３】
ｖｃｐｕがストールした時、一部の例では、ｖｃｐｕは、ゲストオペレーティングシステム（ＯＳ）が物理プロセッサであると考えるもの（本明細書に記載の仮想化システム／マシン内では、実際には仮想プロセッサ（すなわち、ｖｃｐｕ）である）において実行するゲストスレッドを実行している。一部の例において、ゲストＯＳ（例えば、Ｌｉｎｕｘ、ここで、その他のゲストオペレーティングシステムにも対応可能である）内のスケジューラは、ハイパーカーネルの視点から、任意に見えうる或る根拠に基づいてゲストスレッドおよびｖｃｐｕのマッピングを頻繁に変更しうる（すなわち、上述のようなスレッドコンテキスト切り替え）。ゲストスレッド／ｖｃｐｕの関連性は、ストールが処理される間は変わらない（ｖｃｐｕは、ストールされている間は動作しないため）。ゲストオペレーティングシステムが、物理プロセッサであると考えているものの間でゲストスレッドを多重化する場合、これは、ハイパーカーネルによって気付かれる。上述のように、ハイパーカーネルは、（例えば、上述のように、プロセッサ状態のＦＳ−Ｂａｓｅ０レジスタによって示された）ｖｃｐｕで実行中のスレッドのアイデンティティを追跡し、関連スレッド遷移イベントに気付く。これは、部分的には、ノード、メモリ、および、スレッドの間のバインディング／アフィニティがゲストスレッドの観点から起きるからであり、ここで、スレッドコンテキスト切り替えが、上述のように、繰り返して起こりうる。例えば、上述のように、ゲストオペレーティングシステムが、ゲストスレッドを、自身が別の物理プロセッサであると考えている（ただし、ハイパーカーネルの視点からは実際には仮想プロセッサである）ものへ切り替える場合に、レジスタ（例えば、ＦＳ−Ｂａｓｅ０レジスタ）が更新され、これは、ハイパーカーネルにとって可視である。スレッドコンテキスト切り替えの検出は、ストールイベントの発生を引き起こす。
【０６４４】
イベントテーブル（ＥＴ）のさらなる詳細および実施形態
【０６４５】
以下では、イベントテーブルのさらなる詳細および実施形態について記載しており、イベントテーブルは、スレッドを考慮するよう構成されてよい。イベントテーブル（本明細書では「ＥＴ」と呼ぶ）およびタイダルツリー（本明細書では「ＴＴ」と呼ぶ）は、緊密に連携して動作しうる。ＥＴ上の動作は、単純、安価、スレッドセーフ、かつ、包括的であるように設計される。本明細書で用いられているように、協働するＥＴおよびＴＴは、「ハイパーカーネルスケジューラ」と呼ばれる。
【０６４６】
本明細書に記載した例において、ＥＴは、将来に起こると予測される非同期イベントを見込んだデータ構造である。ＥＴは、待たれているイベントが発生した時に参照されうるデータ構造であり、ＥＴは、イベント発生の結果として１セットの動作を実行するようにハイパーカーネルに指示する。
【０６４７】
いくつかの実施形態において、イベントは、抽象データ型であり；イベントは、その型に限定されるが明確に定義された動作セットを有しうる。
【０６４８】
多くのスレッドが、ＥＴへのアクセスを望みうるので、ＥＴへのアクセスおよび更新の前後の同期が実行される。例えば、ＥＴ内のイベントを待つスレッドは、ｖｃｐｕで実行中のゲストスレッド、もしくは、Ｉ／Ｏ動作の完了またはリモートノードからの完了割り込みの受信を待つｖｉｏｐスレッドでありうる。
【０６４９】
ハイパーカーネルスレッドは、スレッドがすでにＥＴ内で待っていない限りは、直接的または間接的に待つためにＦｒｅｅＢＳＤスケジューラを呼び出さない。これについての１つの理由は、ハイパーカーネルの適切な決定を行うために、ハイパーカーネルがそのリソースのスケジューリングを厳密に制御することである。これらは、ＦｒｅｅＢＳＤスケジューリング戦略と衝突する場合も衝突しない場合もある。いずれの場合でも、目標は、ハイパーカーネル／ＦｒｅｅＢＳＤスケジューラ相互作用を最小限に抑えて厳密に制御することである。
【０６５０】
いくつかの実施形態において、ハイパーカーネルスケジューラおよびＦｒｅｅＢＳＤスケジューラは、非干渉的である。例えば、ＦｒｅｅＢＳＤスケジューラの暗黙的な呼び出しが除去される（例えば、ｃｏｎｄ＿ｗａｉｔ）。下層のＩ／Ｏデバイスが、それらの動作を完了させるために或る程度の時間を必要としうるので、ｖｉｏｐは、ｗａｉｔを呼び出してよい。この場合、ｖｃｐｕが、イベントテーブル内に表されてよく、イベント発生時に、ｖｃｐｕは、タイダルツリー（ＴＴ）へ移行する。いくつかの実施形態において、Ｉ／Ｏは、ＦｒｅｅＢＳＤドメインで実行される。したがって、いくつかの実施形態において、（例えば、ｖｃｐｕではなく）ｖｉｏｐが、ｃｏｎｄ＿ｗａｉｔを呼び出す。
【０６５１】
ＥＴと相互作用する他のスレッドも存在しうる（例えば、ネットワークサブシステム内のスレッド）。以下は、非同期的イベントの例のリストである。
【０６５２】
・応答型ページの受信
【０６５３】
・非応答型ページの受信
【０６５４】
・Ｉ／Ｏ完了通知の受信
【０６５５】
・リモート割り込み通知の受信
【０６５６】
・リモートまたはローカルのＩ／Ｏ動作の受信
【０６５７】
・リモートまたはローカルの命令エミュレーション要求の受信
【０６５８】
この例では、どのイベントも、ステータスを有する。ステータスは、｛予定（ａｎｔｉｃｉｐａｔｅｄ），ポスト済み（ｐｏｓｔｅｄ），完了（ｃｏｍｐｌｅｔｅｄ）｝の内の１つでありうる。本明細書に記載のように、ｖｃｐｕが待つことを望むイベントをＥＴに入れる決定をしたが、イベントをトリガするために必要なすべての作業を行っていない場合に、イベントは、予定の状態となる。イベントをトリガする作業が完了すると、イベントの状態は、予定からポスト済みに変わる。イベントが発生すると、状態は、完了に変更される（そして、ＥＴから除去される）。（いくつかの実施形態では、イベントが発生すると、イベントテーブルからすぐに除去されるので、完了状態は必要とされず、例示の目的で本明細書に記載されている）。ＥＴ内には、完了済みのイベントはないことが好ましい。ＥＴからパージされると、イベントを待つ任意のスレッドは、イベントに対応する適切な動作を取る。
【０６５９】
いくつかの実施形態では、ページが要求されたことを示すペンディングビットが用いられる。ペンディングビットは、ページがすでに要求されている（ただし、ページはまだ受信されていない）ことを示すページデータベース内のページに関するビットとして実装されてよい。ページが要求された場合、要求されたページに対応するイベントテーブル内にイベントが存在することに注意されたい。したがって、ペンディングビットおよびイベントは両方とも必要でない場合がある。いずれにしても、情報は、ノードが同じページを２回要求しないことを保証するために用いられてよい（これは、限りなくページを要求することを防ぎうる−例えば、ノードは、ページを送信した時に、そのページが要求側ノードによって受信されたか否かをわからないーペンディングビットがこれを保証するのに役立ちうる）。
【０６６０】
一部の状況においては、ページが正式に要求される前に、ページ到着イベントが発生しうる（すなわち、要求の成立がまだ途中である）。この場合、到着によってトリガされたＥＴの更新は、イベントがまだポストされていないが、予定状態でイベントテーブルにあるとする。したがって、いくつかの実施形態において、ページが到着した後、イベント状態は完了としてマークされ、実際の要求はなされない。この場合、ＥＴの更新がポスト済みとしてマークするようになされると、更新はその代わりに、持っているイベントが発生したかのようにその状態を完了へとシミュレートし、通常通りにイベントがイベントテーブルから除去される。また、ページが求められることなしに到着した場合、または、ページを待っている複数のスレッドがあった場合、ＥＴ内でページを待っているすべてのスレッドが、実行準備される。
【０６６１】
考慮すべき別の問題の別の例は、以下の通りである。本明細書に記載の仮想化システムにおける不変条件の一例は、同じページに対しては同じノード上に重複する要求が存在しないことである。これは、ハイパーカーネルによる動員されたリソースの検索が最終的に終了することを保証するために行われる。これは、未処理の要求の完了に対応する第２イベントを有することによって解決されうる。したがって、任意のスレッド（元々のスレッドまたは後続のスレッド）が同じページでストールした場合、最初の要求が満たされるまで、別の要求は発行されない。
【０６６２】
したがって、本明細書に記載の仮想化システムにおいて、各ノード上のあらゆるｖｃｐｕおよびあらゆるｖｉｏｐは、関連するＦｒｅｅＢＳＤスレッドを有する。いくつかの実施形態において、ハイパーカーネルは、ｖｃｐｕと１：１で対応するｖｃｐｕスレッドを扱う。ｖｃｐｕは、例えばハイパーカーネル初期化時に生成された関連ＦｒｅｅＢＳＤスレッド（上述のｖｃｐｕスレッド）を有する。ｖｉｏｐも、ＦｒｅｅＢＳＤスレッドを有する。ｖｃｐｕまたはｖｉｏｐは、ハイパーカーネルスレッドｉｄで識別されるか、または、例えば、ＦｒｅｅＢＳＤスレッド番号で表されてよい。いくつかの実施形態において、２つは、ばらばらに維持され、ここで、ハイパーカーネルｖｃｐｕまたはｖｉｏｐをＦｒｅｅＢＳＤスレッドに対応付けるテーブルが別個に維持される。これは、ハイパーカーネルおよびＦｒｅｅＢＳＤの相互依存を制限することに関して上述した理由でなされてよい。いくつかの実施形態において、どちらのＦｒｅｅＢＳＤスレッドがＥＴからのイベントの除去に責任を持っていても、待機中のハイパーカーネルスレッドを、例えば、それに対応するＦｒｅｅＢＳＤスレッドに信号送信することによって目覚めさせる。このようにすることは、いくつかの実施形態において、継続に関するさらなる考慮を行う必要がないことを意味することに注意されたい。いくつかの実施形態において、計算の状態は、ＦｒｅｅＢＳＤスレッド番号（または、同等に、ハイパーカーネル定義のｖｃｐｕまたはｖｉｏｐ番号）によって表される。その後、この例において、ＦｒｅｅＢＳＤは、スレッドランタイム状態を保存および復元する責任を持つことになる。
【０６６３】
いくつかの実施形態では、どのイベントも、イベントタイプ（この例については、上で列挙した）、イベントステータス、および、イベントが完了した時に信号送信される１セットのスレッド、を含む。また、上述のように、複数のスレッドが、同じイベントを待つ場合があり、その場合、イベントが発生した時、イベントを待つすべてのスレッドがウェイクアップされる。これは、以下に記載のＡＰＩ例の副作用でありえ、本明細書に記載のＥＴ実施の例の一部である。いくつかの実施形態では、すべてのイベントが、リソースＩＤ（例えば、ゲスト物理ページのｇｐａ）にも関連付けられている。いくつかの実施形態において、イベントテーブル内の（対応するリソースＩＤによって識別された）各イベントについて、イベントテーブルは、イベントを待っている（グローバルに一意的なｖｃｐｕ識別子によって識別された）ｖｃｐｕのリストを含む。
【０６６４】
いくつかの実施形態において、イベントテーブルのためのＡＰＩはすべて、セーフＡＰＩとして（すなわち、或るミューテックスの下で）実装されるので、コレクションは、ホーアスタイルモニタとみなされてよい。
【０６６５】
／／安全にイベントをイベントテーブルに挿入する
【０６６６】
／／ｍｙ＿ｅｖｅｎｔが、イベントテーブルへのインデックスであってよい
【０６６７】
／／イベントがすでにイベントテーブル内にある場合、
【０６６８】
／／イベント「ｅ」が発生した時に起こされるスレッドのリストにスレッド「ｔ」を追加する
【０６６９】
ｍｙ＿ｅｖｅｎｔ＝ｔｓ＿ｉｎｓｅｒｔ＿ｅｖｅｎｔ（ｔｈｒｅａｄ  ｔ，ｅｖｅｎｔ  ｅ）；
【０６７０】
【０６７１】
／／指示されたイベントのステータスをポスト済みに変更する
【０６７２】
ｔｓ＿ｃｈａｎｇｅ＿ｅｖｅｎｔ＿ｓｔａｔｕｓ＿ｔｏ＿ｐｏｓｔｅｄ（ｍｙ＿ｅｖｅｎｔ  ｅ）；
【０６７３】
【０６７４】
／／それを待つすべてのスレッドに開始するよう信号を送信し、イベントテーブルからｅを除去する
【０６７５】
ｔｓ＿ｔｒｉｇｇｅｒ＿ｅｖｅｎｔ（ｍｙ＿ｅｖｅｎｔ  ｅ）；
【０６７６】
タイダルツリー（ＴＴ）およびスケジューリングのさらなる詳細および実施形態
【０６７７】
以下では、タイダルツリー（ＴＴ）およびスケジューリングのさらなる詳細および実施形態について記載しており、これらは、いくつかの実施形態において、スレッドを考慮する。
【０６７８】
最適化タイダルツリー
【０６７９】
図１５Ａは、タイダルツリーの別の実施形態を示す。この例において、タイダルツリーの別の実施形態は、「最適化タイダルツリー」と呼ばれ、上述のタイダルツリーを最適化または平坦化または縮小したバージョンである。
【０６８０】
タイダルツリーの上記の実施例において、タイダルツリーは、物理ツリー（例えば、（ハイパースレッドを含む場合）深さ５のツリー）として実装され、ここで、ツリーの各ノード／頂点は、実行準備のできたｖｃｐｕの作業キューを有していた。ＴＴの物理ツリー実施例において、各第２レベルのサブツリーは、ノード上に存在し、ツリーにおける各頂点は、計算階層の物理部分を表していた。例えば、リーフは、ハイパースレッドに対応していた。１つ上のレベルは、ハイパースレッドを組み合わせてコアにすることを表していた。そこから１つ上のレベルは、それが含むすべてのコアを含む物理プロセッサを表していた。そこから１つ上のレベルは、それが含むすべてのプロセッサを含むマザーボードを表していた。最後に、１つ上のレベルは、タイダルポッドを表していた（すなわち、システム内のマザーボードすべて）。実行準備のできたｖｃｐｕをキューする時に、ｖｃｐｕが最後に動作したｐｃｐｕのキューにｖｃｐｕを配置する試みがなされる。そのキューが満杯だった場合、ｖｃｐｕを作業キューに追加できるまで、１つ上のレベルの次のキューが検索され続ける。
【０６８１】
深さ５のＴＴの上記の実施例において、ルートの位置は、任意であってよいが、いくつかの実施形態においては、周知のノードまたは起動時に指定されたノード上であってよい。ルートは、どのノード上のｐｃｐｕキューにも入れられていない実行準備のできたタイダルポッド全体のｖｃｐｕのキューを含む。いくつかの実施形態において、ルートキューを含むノードは、エンキュールートおよびデキュールートのメッセージに応答するが、ルートの位置は、ｖｃｐｕマイグレーションポリシーとは無関係であってよく、いくつかの実施形態では、キューを維持するノードであってよい。
【０６８２】
タイダルツリー構造の最適化バージョンにおいて、（深さ５のＴＴなどで）物理ツリー構造を構築または実装する代わりに、最適化タイダルツリーは、ハードウェア構成内の各物理プロセッサに対応する１セットのキュー（例えば、図２の例におけるハイパースレッド）、および、グローバルにアクセス可能なキューとして実装され、ここで、ツリーの階層は、訪問順で置き換えられる。例えば、ハイパーカーネルに割り当てられた各ｐｃｐｕに対して１つのキューが存在する。（例えば、後述の分割スケジューラについての議論を参照）。物理プロセッサの各々に対応するキュー（例えば、キュー１５０２および１５０４）は、本明細書では「ｐｃｐｕキュー」と呼ばれ、グローバルにアクセス可能なキュー（１５０６）は、本明細書では「ルート」と呼ばれる。上記の深さ５のタイダルツリーの二次元構造ではなく、最適化タイダルツリーは、一次元構造を用いて実装される。この実装例において、ｐｃｐｕキューは、深さ５のタイダルツリーのリーフの例であり、一方で、グローバルにアクセス可能なキューは、深さ５のタイダルツリーのルートキューの一例である。
【０６８３】
最適化タイダルツリーは、深さ５のタイダルツリーの上記実施例と比較して、作業キューの数が削減されている。例えば、ハイパーカーネルに割り当てられたＮ個の物理プロセッサがある場合、最適化タイダルツリーにはＮ＋１個のキュー（Ｎ個の物理プロセッサおよび１個のグローバルアクセス可能なルートキュー）があるが、深さ５のＴＴは、ツリー内の頂点の数に等しい数のノードを有する。したがって、最適化ＴＴにおいてトラバース／訪問するためのキューの数が削減される。
【０６８４】
したがって、上述のように、最適化ＴＴのこの実施例において、最適化ＴＴは、キューのセットとして実装され、ここで、ツリーウォークを模倣したトラバースアルゴリズムと共に、ハイパーカーネルに割り当てられた各物理プロセッサのための１つのキューが存在する。一実施形態において、ｐｃｐｕキューは、実行準備のできたｖｃｐｕの先着順（ＦＣＦＳ）リストとして実装される。いくつかの実施形態において、ｐｃｐｕキューが検索される順序は、キャッシュアフィニティを実現するために予め決定される。例えば、概念ツリーのキャッシュレベルに対応する検索パスが用いられる。キャッシュレベルの知識は、深さ５のＴＴの上記実施形態で述べたように、ツリーの頂点上に複数のキューを維持するのではなく、物理プロセッサのトラバースアルゴリズムに埋め込まれる。トラバースの順序は、起動時に固定されてよく、本明細書に記載の仮想化システムの物理トポロジに対応する。
【０６８５】
例えば、ハイパーカーネルに割り当てられたノード上にｐ個の物理プロセッサがあると仮定する。各ノード上には、ＦｒｅｅＢＳＤのために確保されたｎ個の物理プロセッサがあり、残りのｐ−ｎ個の物理プロセッサは、ｖｃｐｕのスケジューリングに用いるようにハイパーカーネルのために確保される。ｋ個のノードを仮定すると、スケジューリングされるｖｃｐｕは、ｋ＊（ｐ−ｎ）個である。
【０６８６】
上述のように、各ｐｃｐｕは、実行準備のできたｖｃｐｕの関連ＦＣＦＳリストを有する。
【０６８７】
上述のように、ｖｃｐｕは、ストールすると、ノードのイベントテーブルに配置されて、イベントの発生を待つ。この状態で、ｖｃｐｕはマイグレートできない。イベントが（例えば、或るｐｃｐｕ  ｐｅによってトリガされて）ノード上で発生すると、ｐｅは、そのイベントを獲得して、このイベントを待つすべてのｖｃｐｕを仮想タイダルツリーにエンキューし、その後、以前に行っていたことは何でも継続する。（プロセッサｐｅは、確保されたＦｒｅｅＢＳＤプロセッサまたは確保されたハイパーカーネルプロセッサのいずれかであってよく、どちらのプロセッサがイベントを処理していても、それは、イベントを待つ適切なｖｃｐｕを解放し、それらをタイダルツリー上へキューすることが好ましい）。
【０６８８】
ｐｃｐｕ  ｐｎｅｗが利用可能になると、それは、例えば、動作させるのに最も適切なｖｃｐｕを検索することによって、自身に作業を割り当てる。次いで、ｐｎｅｗは、そのｖｃｐｕのアイデンティティを担い、ｖｃｐｕは動作を開始する。
【０６８９】
ｖｃｐｕを（例えば、ＥＴから外された後に）ＴＴ上へ配置（「エンキュー」）する処理、ならびに、（例えば、匿名のｐｃｐｕが実行すべき作業を探している時に）ＴＴからｐｃｐｕへデキューする処理、に関するさらなる詳細および実施形態について、以下に詳述する。
【０６９０】
ＴＴ上へのＶＣＰＵのエンキュー
【０６９１】
上述のように、ｖｃｐｕは、（例えば、ｖｃｐｕが待っていたイベントが発生したために）イベントテーブルから除去された時、または、マイグレートするｖｃｐｕがノードに到着した結果として、キューされる。どちらの場合も、ｖｃｐｕは、適切なｐｃｐｕキューを見つけられる場合には、このノード上の選択されたｐｃｐｕにキューアップされる（すなわち、特定のｐｃｐｕに対応するキューに配置される）。
【０６９２】
ｐｃｐｕキューが検索される順序は、キャッシュアフィニティを実現するために予め決定されてよく、ここで、いくつかの実施形態において、トラバース順序は、キャッシュ階層に従う。キャッシュ階層すなわちキャッシュの階層の一例では、同じコア上の２つのハイパースレッドがキャッシュデータを共有し、プロセッサチップ上の複数のコアがキャッシュデータを共有し、マザーボード上の複数のプロセッサがキャッシュデータを共有する。
【０６９３】
いくつかの実施形態において、コア上の複数のハイパースレッドが、同じプロセッサハードウェアを利用していて、互いの実行と衝突する場合があるため、可能であれば、同じコア上の複数のハイパースレッドの過密スケジューリングが避けられる。したがって、かかる実行の衝突を防ぐために、ハイパースレッドを分散させることが望ましい場合もあるが、できるだけ多くキャッシュアフィニティを利用して、２つの潜在的に衝突する目標という結果になることが望ましい場合もある。したがって、いくつかの実施形態において、用いられるプロセッサの特定のタイプに対して、検索順序が、（例えば、起動時に）確立される。
【０６９４】
一例として、ｖｃｐｕの実行準備ができると、実行準備のできたｖｃｐｕを配置すなわちエンキューするキューの検索が、以下のように実行される。出発点として選択されたｐｃｐｕから開始する。一例として、検索は、ｖｃｐｕが最後に動作したｐｃｐｕに対応するキューで開始される。いくつかの実施形態において、各ｖｃｐｕの状態は、ｖｃｐｕが動作した最後のノードおよびその最後のノード上のｐｃｐｕを記録するように拡張される。利用可能なｐｃｐｕキュー（ひいてはｐｃｐｕ）の検索は、ｖｃｐｕが動作した最後のｐｃｐｕで開始する（ｖｃｐｕが最後に動作した時に、それが現在存在するのと同じノード上にあったと仮定する）。ｖｃｐｕがマイグレートしたばかりである（したがって、以前に動作していたｐｃｐｕ上で動作できない）場合、または、ちょうど始動している場合、アクセスまたは訪問する第１ｐｃｐｕキューは、任意に選択されてよい。上述のように、１つの目標は、コアにオーバーロードさせないことである。いくつかの実施形態において、検索は、後に詳述するように、可能であればフルセットのコアにわたって実行準備のできたｖｃｐｕを分散させるようにバイアスされる。
【０６９５】
一例として、検索は、選択されたｐｃｐｕ（すなわち、上述のように、可能であれば、ｖｃｐｕが最後に動作していた物理プロセッサ）から始まり、キュー長がゼロ（すなわち、キューがエンプティ）である同じコア上にはないキャッシュ関連ｐｃｐｕが検索される。１つも見つからなかった場合、実行準備のできたｖｃｐｕをすでに有するコア上のｖｃｐｕをキューする試みがなされる。例えば、キュー長が１であるキュー、次に、２であるキュー、最大キュー長を有するキューまでが検索される。検索の順序は、キャッシュ階層に従う。一例において、第１すなわち出発ｐｃｐｕ（キュー）にｖｃｐｕをエンキューする試みが最初になされ、次にその兄弟、次に従兄弟、次に第２従兄弟、などへの試みが続く。一実施形態において、ｐｃｐｕ  ｐの兄弟は、ｐと同じコアを共有するハイパースレッドのことである。従兄弟プロセッサとは、共通の先祖を有するｐｃｐｕのことである。従兄弟ｐｃｐｕの一例は、同じチップの別のコア上にあるｐｃｐｕである。かかるｐｃｐｕが見つからない場合、チェックされる次のｐｃｐｕは、別のチップまたはソケット上にあるが同じマザーボード上にあるｐｃｐｕである（すなわち、ｐへの物理的接続を有するもの）。このように、暗黙的に、最も温かいキャッシュが見つけられ、ｖｃｐｕは、このノード上の利用可能なｐｃｐｕ上に分散される。
【０６９６】
別の例として、ｖｃｐｕの実行準備ができると、可能であれば、対応するキューがエンプティのスロットを有する（すなわち、キュー長が最大長未満である）場合に、ｖｃｐｕが最後に動作していた物理プロセッサ（例えば、ハイパースレッド）から、検索が開始される。そうでなければ、検索は、ノード上ですべての可能性がなくなるまで、次のｐｃｐｕなどに進む。その後、ｖｃｐｕは、ルート上に配置される。
【０６９７】
様々なトラバース順序が、起動時に設定されてよい。一例として、コアの番号順のリスト内の次のコアが検索される。ｖｃｐｕをそのコア上に配置できる場合、ｖｃｐｕは、そのコア上に配置される。これは、ｖｃｐｕが最後に動作していたｐｃｐｕと同じキャッシュラインの一部を共有する結果になりうる。上述のように、いくつかの実施形態において、同じコア上のハイパースレッドの利用が、そのコア上の兄弟ハイパースレッドがビジーである場合に回避される。
【０６９８】
図１５Ｂは、実行準備のできたｖｃｐｕをエンキューする先のｐｃｐｕキューの検索の一実施形態を示す図である。図の例において、ノードのためのマザーボードは、（例えば、マザーボード上の２つのソケットに）２つのチップを有しており、各チップは２つのコアを有し、各コアは２つのハイパースレッドを有する（その他のハードウェア構成も可能でありうる）。したがって、この例に示すように、ＰＣＰＵ０〜ＰＣＰＵ７としてこの例にラベル付けされた８つのｐｃｐｕが存在する。検索がＰＣＰＵ０（１５１０）から始まると仮定する。ｖｃｐｕをＰＣＰＵ０上に配置できない場合、この例において、検索で訪問される次のｐｃｐｕキューは、ＰＣＰＵ２に対応するキューであり、ＰＣＰＵ２は、同じチップ上にあるが、ＰＣＰＵ０とは異なるコアである。この例において、ＰＣＰＵ２を次に訪問することにより、ＰＣＰＵ１がビジーである場合に、チップ０のコア０のオーバーロードを回避できる。さらに、これは、（例えば、他のコア上のｐｃｐｕに）ノード上のｖｃｐｕを分散することを試みる。
【０６９９】
この例において、ＰＣＰＵ２が訪問された後の次のＰＣＰＵは、ＰＣＰＵ１である（例えば、ＰＣＰＵ１が以前にビジーであった場合に、検索のこの時点ではもはやビジーではない可能性があり、オーバーロードが回避されうる）。その後に訪問されるＰＣＰＵは、ＰＣＰＵ３であり、次はＰＣＰＵ４（この例においてはマザーボード上の他のチップに移動する）、次はＰＣＰＵ６、次はＰＣＰＵ５、次はＰＣＰＵ７である。
【０７００】
この例において、上記の順序を規定する反復式は、（＋２−１＋２）＋１（＋２−１＋２）などである。「クリーネ」または正規表現パターンとして、上記は、以下の式の例によって規定される。
【０７０１】
［（＋２−１＋２）＋１］＾＊
【０７０２】
最大キュー長以下の任意の適切なｐｃｐｕキューがノード上で見つからない場合、ｖｃｐｕは、クラスタ内の任意のノード上で動作するために利用可能なｖｃｐｕのグローバルアクセス可能なＦＣＦＳリスト（図１５Ａに記載したようなルート）上にキューされる。ｖｃｐｕは、例えば多項式戦略のローカリティに基づいた理由で、特定のノードにあるので、他のノード上のｐｃｐｕのためのキューは評価されない、すなわち、ｖｃｐｕは、特定のノードへマイグレートされているか、または、それが存在するノードにページが移動されるように要求していた。
【０７０３】
別の実施形態では、ルート上にｖｃｐｕを配置するのではなく、そのノードについて最もパフォーマンスの低いｖｃｐｕが、エビクトされ、ルートキュー上に移動される。次いで、キューされるｖｃｐｕは、最もパフォーマンスの低いｖｃｐｕがエビクトされたｐｃｐｕキューに配置される。
【０７０４】
ノード上のｐｃｐｕをオーバーロードしないように注意することが好ましく；ハイパーカーネルスレッドを実行するＦｒｅｅＢＳＤスケジューラキューは、できるだけ短く維持されることが好ましい。いくつかの実施形態において、実行準備完了にされうる（すなわち、ＴＴのｐｃｐｕキューおよびルートキューに配置されうる）タイダルツリースレッドの最大数は、ハイパーカーネル初期化パラメータとして指定される。
【０７０５】
仮想化システム上の利用可能なｐｃｐｕと比べてｖｃｐｕが多すぎる場合、ＣＰＵ負荷は、ポッドのノードの間でバランスを取られることがｊ好ましい。利用可能なｐｃｐｕと比べてｖｃｐｕが多すぎるという判定は、実行準備のできたタイダルツリー内のｖｃｐｕの総数を追跡することによってなされてよい。許容できる或る程度のレベルのオーバーコミットメントがあると仮定できる。このレベルは、起動時パラメータによって確立されてよい。オーバーコミットメントに関するさらなる詳細については後述する。ノードのタイダルツリー（例えば、ノードにローカルなｐｃｐｕに対応するｐｃｐｕキューのセット）が過密になると（すなわち、コミットメントレベルを超えると）、ハイパーカーネルは、例外動作を実行してよく、ここで、上述のように、タイダルツリーは、実行準備のできたｖｃｐｕ（例えば、ノード上の最もパフォーマンスの低いｖｃｐｕ）を選択し、それを特別なキュー（上述のように、グローバルＴＴルート）に配置し、ここで、ポッド全体に対して１つのルートが存在する。
【０７０６】
ノードのｐｃｐｕキューからエビクトされ、グローバルアクセス可能なルートキュー上にバンプされるｖｃｐｕは、以下のように選択されてよい。エビクトされるｖｃｐｕは、ゲストスレッドを現在実行しており、したがって、関連する優良度メトリックを有する。このゲストスレッドをエビクトすることにより（ゲストスレッドを実行しているｖｃｐｕをエビクトすることにより）、これは、ゲストスレッドの必要とするメモリの位置、および、そのゲストスレッドと共通関心を有しうる他のゲストスレッドのメモリの位置に影響しうる。いくつかの実施形態において、（将来プルされるルートにｖｃｐｕを配置することによって）どのｖｃｐｕをエビクトするのかを決定するために、優良度メトリック、メモリ状態、および、共通関心（これらの例については上述した）など．１セットの項が考慮される。例えば、（例えば、優良度メトリックを用いて測定された）最もパフォーマンスの低い（ノード上のｐｃｐｕキュー内の）ｖｃｐｕがエビクトされ、グローバルアクセス可能なルートキュー上に配置される。
【０７０７】
ｐｃｐｕをビジーに維持することとキャッシュラインを再利用することの両方が重要でありうるが、いくつかの実施形態において、本明細書に記載のトラバースアルゴリズムは、キャッシュラインの再利用よりもｐｃｐｕをビジーに維持することに向かうバイアスをアサートするが、あまりに多いハイパースレッドでコアをオーバーロードする犠牲を払うことはない。
【０７０８】
本明細書に記載のスケジューリングアルゴリズムは、スレッドアイデンティティを考慮してよい。例えば、本明細書に記載のスケジューリングアルゴリズムを用いて、ｖｃｐｕが実行した最後のｐｃｐｕ上にｖｃｐｕを復元する試みがなされる。ｖｃｐｕはゲストスレッドを実行していた。そして、ゲストスレッドは、ｖｃｐｕがストールしていた間に変化していない。ｖｃｐｕが復元される時、識別されうる最も有利なｐｃｐｕに復元されるだけでなく、ｖｃｐｕの復元時に、スレッドも、スレッドが実行していた最後のｐｃｐｕ上に同時に復元される。これは、（Ｌ１、Ｌ２、または、Ｌ３キャッシュを観察することは可能ではない場合があるので）発見的であるが、このアプローチが最適であり、ここで、スレッドは、それが実行した最後のｐｃｐｕ上、または、識別されうる同じコア上にはない最も近い関連物の上に配置される。
【０７０９】
いくつかの実施形態において、コアは、オーバーロードを防止される。例えば、上述の検索は、フルセットのコアにわたってｖｃｐｕを分散させるようにバイアスされてよい。バイアスは、エンプティコアが利用可能である時にハイパースレッド上にスレッドを同時スケジューリングしないように加えられる（ここで、ｐｕｐｕキュー上にｖｃｐｕを配置することで、ｖｃｐｕが、対応するｐｃｐｕ上で動作することになり、それによって、ｐｃｐｕ上でのｖｃｐｕの動作をスケジューリングする）。例えば、ｖｃｐｕ（ひいては、ストールしたｖｃｐｕにおいて実行中のゲストスレッド）は、それが実行した最後のｐｃｐｕ上、または、同じコア上にはない最も近い関連物の上に配置されてよい。したがって、このように、ハイパースレッド上にキューアップされたｖｃｐｕがすでに存在する場合、新たな実行準備のできたｖｃｐｕは、同じコアを共有する次のハイパースレッド上には配置されない。
【０７１０】
いくつかの実施形態において、トラバースの順序（キューの訪問の順序）は、起動時に固定され、システムの物理トポロジに対応する。
【０７１１】
ＴＴからＰＣＰＵへのＶＣＰＵのデキュー
【０７１２】
ＴＴからｐｃｐｕへｖｃｐｕをデキューする以下の例において、ゲストオペレーティングシステムが、クラスタにわたって集合的に実行されると仮定する。ゲストアプリケーションが、ゲストオペレーティングシステム上で実行している。ゲストアプリケーションは、次に、ゲストスレッドに関連付けられる。（ｖｃｐｕが動作しているノード上のｖｃｐｕスレッドによって管理された）ｖｃｐｕは、ゲストスレッドを実行する。
【０７１３】
ｖｃｐｕは、ハイパーカーネルのコンテキスト内に存在する。この例において、ｖｃｐｕは、ｖｃｐｕスレッド内で実行している。この例において、このｖｃｐｕスレッドは、実際にはＦｒｅｅＢＳＤスレッドであり、したがって、ＦｒｅｅＢＳＤスレッドとしてＦｒｅｅＢＳＤによって管理されるが、ハイパーカーネルによってｖｃｐｕスレッドとしても管理される。任意のノード上で、ｖｃｐｕスレッドとｖｃｐｕとの間の１：１の対応関係がある。一実施例において、所与のノード上で、ｖｃｐｕスレッドとＦｒｅｅＢＳＤスレッドとの間の１：１の対応関係がある。一部の例において、ハイパーカーネルは、ハイパーカーネルがＦｒｅｅＢＳＤに依存して提供するスレッド以外にはスレッドを持たない。
【０７１４】
仮想化システムが定常状態にあると仮定する。ゲストオペレーティングシステム（例えば、Ｌｉｎｕｘ）が、アプリケーションを実行している（例えば、読み出し、書き込み、計算を実行している、命令を実行している、プログラムカウンタを進めている、など）。例えば、アプリケーションに関連するゲストスレッドが、（ゲストオペレーティングシステムによって）ｖｃｐｕに割り当てられており、ｖｃｐｕは、物理プロセッサに割り当てられている。
【０７１５】
ここで、物理プロセッサは、ゲストスレッドのために、命令を実行し、物理プロセッサにとって利用可能ではないメモリのページ（例えば、メモリのページが、物理プロセッサと同じノード上にない）にアクセスを試みると仮定する。例えば、仮想化ハードウェアは、（例えば、物理プロセッサが存在するノードのための第２レベルページテーブルを用いて動的アドレス変換を実行することによって）ゲスト物理ページ（そのアドレスは、上述のように、第１レベルページテーブルを用いて取得された）を、ホスト物理メモリ内の実物理メモリアドレスに変換しようとした。この例において、ｇｐａのためのエントリがなく（例えば、第２レベルページテーブルのエントリが、無効化、ゼロ化などされており、ｇｐａとノード上の実物理ページとの間のマッピングがない）、対応する実物理ページは、（ｖｃｐｕスレッドによって実行され、ゲストスレッドに従事しているｖｃｐｕのアイデンティティを担っている）物理プロセッサによって解決または参照されることができないと仮定する。
【０７１６】
仮想化ハードウェア（例えば、Ｉｎｔｅｌ  ＶＴ−ｘまたはＡＭＤ  ＡＭＤ−Ｖ）は、ｇｐａを実物理アドレスに変換できないので、割り込みが自動的に生成される。ハードウェアは、割り込みを生成する時、割り込みテーブル（オペレーティングシステムの一部）にアクセスし、割り込みテーブルは、割り込みが発生した時に呼び出されるルーチンのアドレスを含む。次いで、ハードウェアは、（例えば、対応するアドレスを用いることによって）ルーチンへベクトルする。例えば、プログラムカウンタ（および任意のその他のレジスタ状態）が、ハードウェアによって保存され（例えば、プロセッサの状態が割り込みスタックにプッシュされ）、新しいプログラムカウンタが、割り込みテーブル内で指定されたルーチンに設定される。割り込みルーチンを実行する前にプロセッサ状態を保存することにより、物理プロセッサは、割り込みから戻った後にその以前の状態に戻ることができる（例えば、割り込みから戻った後、保存された状態が、逆順に割り込みスタックから外され、それにより、プロセッサは、割り込み発生後に次の位置へ効果的にジャンプし、その結果、ゲストオペレーティングシステムは、割り込みが発生しなかったかのように継続する）。
【０７１７】
この例において、呼び出される割り込みテーブル／ベクトルに含まれるルーチンは、ハイパーカーネルルーチン／コードである。いくつかの実施形態において、ホストオペレーティングシステムは、ハイパーカーネルに割り込みを送るよう構成されており（例えば、割り込みをハイパーカーネルに再ベクトルする）、ここで、ハイパーカーネルコードがその後に実行される。
【０７１８】
発生時に割り込みを処理するために実行されるハイパーカーネルコードの例については、上述している。例えば、保存されたプロセッサ状態を用いて継続が生成されてよい（例えば、割り込みスタックを見ることができ、継続のために保存されたプロセッサ状態のスナップショットまたはコピーを取りうるハイパーカーネルコードによって）。ストールイベントが処理された後、ｖｃｐｕの状態は、継続から復元されてよい（例えば、物理プロセッサがｖｃｐｕのアイデンティティを担うまたは引き受ける時に、ｖｃｐｕ内のプロセッサ状態をロードする）。
【０７１９】
この例では、ストールが発生している。ストールは、すぐに扱うことができるもの、または、待つ必要があるもののいずれかでありうる。すぐに処理できるストールイベントの一例は、タイマーの要求である。タイマーが取得された後、ストールが処理され、割り込みが退けられてよい。
【０７２０】
しかしながら、ストールが、例えば、（非ローカルページ要求による）ページストールである場合、ストールの処理は待機を必要とする。例えば、上述のように、１セットの多項式が、ストールを処理するための戦略を決定するために評価される。上述のように、ページを要求する決定がなされるか、または、メモリのページが存在するノードにｖｃｐｕをマイグレートさせる決定がなされるかのいずれかである。
【０７２１】
例えば、ページの要求が送信されることが決定されると仮定する。ｖｃｐｕスレッドは、この場合には待機しなければならない。その後、ｐｃｐｕは、（ｖｃｐｕのｖｃｐｕスレッド表現で実行中のゲストスレッドの）スレッドＩＤおよび継続へのポインタをイベントテーブル内に配置する。イベントテーブルに格納されたその他の情報は、ｖｃｐｕ（継続）が待っている要求されたページの識別子を含む。
【０７２２】
したがって、上述のように、ｖｃｐｕがストールすると、そのｖｃｐｕは、ゲストが物理プロセッサであると思っているが、ハイパーカーネルの視点からは、実際には仮想プロセッサ（すなわちｖｃｐｕ）であるものにおいてゲストスレッドを実行していた可能性がある。ゲストオペレーティングシステム（例えば、Ｌｉｎｕｘ）内のスケジューラは、ハイパーカーネルの視点から、或る任意の根拠（すなわち、上述のように、スレッドコンテキスト切り替え）に基づいて、ゲストスレッドおよびｖｃｐｕのマッピングを変更しうるが、ゲストスレッド／ｖｃｐｕの関連性は、ストール中には変化しえない。上述のように、ハイパーカーネルは、プロセッサ状態を調べることによってｖｃｐｕで実行中のスレッドのアイデンティティを追跡してよく、また、ｖｃｐｕストール時にスレッド遷移イベントに気付きうる。ｖｃｐｕは、上記イベントテーブルに関する議論において上述したように、すぐにストールを解消するために必要なことを実行してもよいし、ゲストが後に動作を完了できるように動作を開始する必要があってもよい。
【０７２３】
例えば、後者のケースである場合、戦略決定（ｖｃｐｕのマイグレートまたはページ要求の送信）がこのストールに対してなされ、これが遅延につながる（すなわち、ストールをすぐに処理できない）ことがわかると、上述のように、エントリがイベントテーブルに配置され、それが待っているイベントは、予定としてマークされる。ストールに対応する動作は、戦略代替の選択後に開始され（例えば、ページ要求を開始する、Ｉ／Ｏ動作を開始する、など）、（ストールしたｖｃｐｕを表す）ｖｃｐｕスレッドは、イベントテーブル内の状態をポスト済みに設定する。
【０７２４】
ここで、ｖｃｐｕスレッドがイベントテーブルにイベントを入力した後、ｖｃｐｕスレッドは、ｐｃｐｕでまだ実行しているが、ｖｃｐｕは（技術的に）実行していない（例えば、ｖｃｐｕスレッドは、ハイパーカーネルコードを実行している）。次いで、ｖｃｐｕスレッドを実行してきたｐｃｐｕ（ここで、ｐｃｐｕは現在では匿名プロセッサである）は、限られた量のハウスキーピング（例えば、メモリ利用のバランシング）を直接的または間接的に実行してよい。いくつかの実施形態において、ｖｃｐｕスレッドは、ハウスキーピングスレッドに信号を送信して、ハウスキーピングをウェイクアップして実行する。あるいは、ｖｃｐｕスレッドは、ハウスキーピング自体を実行してもよく、これは、コンテキスト切り替えの回数を削減する。
【０７２５】
ハウスキーピングスレッドが実行できる作業量を制限するためのメカニズムが用いられてよい。このメカニズムは、ゲストによって行われる必要があるペンディングの作業の量によってパラメータ化されてよい。ペンディング作業の量は、例えば、実行準備のできたタイダルツリー内のｖｃｐｕの数によって特徴付けられてよい。これは、以下に提供される例で与えられうる：例えば、実行準備のできたｖｃｐｕが多くある場合、実行されるハウスキーピングは少ない。一方で、実行準備のできたｖｃｐｕが少数である場合、より多くのハウスキーピングが実行されうる。
【０７２６】
／／実行準備のできたＴＴ内のｖｃｐｕの数を返す
【０７２７】
ｎ＝ｒｕｎｎａｂｌｅ＿ｖｃｐｕｓ（）；
【０７２８】
ゲストオペレーティングシステムのために作業を実行するｐｃｐｕから、ＦｒｅｅＢＳＤ作業を実行するｐｃｐｕを分離することが望ましい場合がある。例えば、少数の物理プロセッサが、ＦｒｅｅＢＳＤのために確保され（例えば、２であり、これは、起動時パラメータであってよい）、一方で、残りは、ハイパーカーネルのために確保されてよい。この責任の分割は、本明細書では「スケジューラ分割」と呼ばれる。上述のように、ＦｒｅｅＢＳＤは、スレッドのスリープおよびウェイクアップを処理するために用いられてよく、ここで、ＦｒｅｅＢＳＤは、所与のノード上のｖｃｐｕスレッドに対応するＦｒｅｅＢＳＤスレッドの適切な状態を保存および復元するよう注意しており、所与ノードは、ｖｃｐｕに対応する。ＦｒｅｅＢＳＤは、ハイパーカーネルのためにこれらの動作を自動的に（そして、おそらく、高度に最適化された方法で）処理する。ハイパーカーネルマイグレーションコードは、ノードおよびホストのスケジューラ限界にわたってこの動作をシミュレートする。
【０７２９】
以下は、どのｖｃｐｕが現在の匿名物理プロセッサで動作するのか（すなわち、実行準備のできたｖｃｐｕを選択するか、または、ＴＴから物理プロセッサへデキューするか）を選択する一実施例である。
【０７３０】
イベントテーブルに配置されたばかりのｖｃｐｕを実行していたｖｃｐｕスレッドは、実際には、ｐｃｐｕで実行している。ｐｃｐｕで実行しているそのｖｃｐｕスレッドは、ここで、すでに実行準備のできたタイダルツリー内の待機中のｖｃｐｕを（もしあれば）選択してよい。例えば、以下のデキューアルゴリズムは、ｖｃｐｕスレッドを実行する（現在は匿名／利用可能である）ｐｃｐｕによって実行される。
【０７３１】
匿名物理プロセッサ上で実行するｖｃｐｕの検索は、匿名物理プロセッサに対応するｐｃｐｕキューで開始される。上述したエンキュー／スケジューリングアルゴリズムと同様に、概念ツリーは、キャッシュラインを再利用するために上方へトラバースされる。上述のように、ｖｃｐｕが、タイダルツリーに配置されると、ｖｃｐｕが最後に動作したｐｃｐｕのキューにｖｃｐｕを配置する試みがなされる。現在の匿名ｐｃｐｕ（任意のｖｃｐｕスレッドとは無関係に、ハイパーカーネルコードを現在実行している）は、最も最近にｐｃｐｕ上で実行していた実行準備のできたｖｃｐｕを検索するために、独自のキューをスキャンする。現在の匿名ｐｃｐｕは、スキャニングを実行するためにＦｒｅｅＢＳＤスレッドを実行中であってよい（一方で、担うべき新しいｖｃｐｕアイデンティティを検索している）。いくつかの実施形態において、匿名ｐｃｐｕは、キャッシュの温かさによってそのｐｃｐｕ上で最後に動作したノード上のｖｃｐｕを選択するよう試み、ここで、最後に匿名ｐｃｐｕ上で実行していたｖｃｐｕの選択は、最も温かいキャッシュの再利用を可能にする。例えば、各物理プロセッサは、トランスレーション・ルックアサイド・バッファ（ＴＬＢ）およびページのためのキャッシュラインエントリなど、１または複数レベルのキャッシュを有する。探されているページがすでにキャッシュ内にある場合、メモリ内でそれを検索する必要はない。匿名ｐｃｐｕのキューが、実行準備のできたｖｃｐｕを全く持たない場合、例えば、概念的なキャッシュ階層順位に従って、その他のキューが次に検討される。
【０７３２】
本明細書に記載の順位訪問の理由の一例は、以下の通りである。マルチコアプロセッサが、４つのコアを有すると仮定する。各コアは、キャッシュを有する。２つのマルチコアプロセッサがあり、各々が４つのコアを有する場合、ｐｃｐｕは、それが一部を形成するマルチコアプロセッサのためのキューに留まることが好ましい。なぜなら、その後に共有キャッシュを利用できるからである（すなわち、別のコアのためのキューが利用される場合よりも、キャッシュラインを再利用できる可能性が高くなるので、物理的なローカリティを有するコアを用いる方が有利である）。これは、ハードウェア構成を調整する（ここで、ハードウェア構成は、図２に関連して記載したように、ツリー構造または階層として記載されてよい）。ｐｃｐｕのノード上のすべてのｐｃｐｕキューがエンプティである場合、いくつかの実施形態において、ｐｃｐｕは、すべてのノード上のすべてのｐｃｐｕにとってグローバルにアクセス可能なルートキューを検索する。これは、すべてのノード上の活動のバランスを取るのに役立つ効果を奏する。ルートキューもエンプティである場合、ｐｃｐｕは、ハウスキーピングなど、他の処理を実行するよう構成されてよい。
【０７３３】
いくつかの実施形態において、同じコア上の２つのハイパースレッドは、同じプロセッサハードウェアを共有または利用していることで、潜在的に互いの実行との衝突を引き起こす場合があるので、それらのハイパースレッドは、連続的にスケジュールされない。
【０７３４】
実行準備のできた待機ｖｃｐｕの選択後に、ｐｃｐｕは、選択されたｖｃｐｕのアイデンティティを引き受ける。例えば、ｐｃｐｕキューで最も長く待っているｖｃｐｕおよび／または最も温かいキャッシュアフィニティが、タイダルツリーから外される（例えば、最も長く待機しているｖｃｐｕになる第１ｖｃｐｕが、ＦＣＦＳリスト／キューから外される）。また、どの継続がハイパースレッドに割り当てるのに最も適切であるかを決定するために、コスト関数が用いられてもよい。いくつかの実施形態において、ｖｃｐｕスレッドは、選択された待機中ｖｃｐｕをウェイクアップするために信号を送信し、その後、自身をスリープさせて、それが完了を待っているイベントテーブル内のイベントを待つ。選択されたｖｃｐｕの状態は、ｐｃｐｕ上に復元される。この例において、このスリープ動作は、ホストスケジューラの暗黙的な呼び出しであり、ＦｒｅｅＢＳＤスケジューラが、ｐｃｐｕ（そこで、ｖｃｐｕスレッドが他の目的（例えば、ハウスキーピングスレッド、または、新たに起こされたｖｃｐｕ）で実行していた）を利用することを可能にする。ＦｒｅｅＢＳＤは、別のｐｃｐｕを選択して利用してもよい。上述の信号送信／ウェイク動作は、ハイパーカーネルが同期的にＦｒｅｅＢＳＤスケジューラを呼び出す明確な時点の間にある。
【０７３５】
実行準備のできたｖｃｐｕがノード上にない（すなわち、ノード上のキューのためのすべてのｐｃｐｕキューがエンプティである）場合、ｐｃｐｕは、自身をアイドル状態にしておかないことが好ましい。その代わりに、それは、ルートからｖｃｐｕを選択することが好ましい。ｐｃｐｕで実行する以前のｖｃｐｕがストールして、イベントテーブルに配置された後に、作業を検索することにより、ｐｃｐｕは、最大限にビジーに維持される（ｖｃｐｕのストールイベントが解消されるのを待つのではなく、ｐｃｐｕは、実行すべき新たな作業を検索する）。ルート上にｖｃｐｕがある場合、一実施形態において、上述したデキュー／ｖｃｐｕ選択アルゴリズムは、（ローカルノードのｐｃｐｕキュー上またはグローバルアクセス可能なルート上のいずれかで）実行準備のできたｖｃｐｕが見つかるまでループされる。別の実施形態において、別のノード上に実行準備のできたｖｃｐｕが存在する場合、ワークスチーリングが実行されてよく、ここで、他のノードが、ｖｃｐｕの実行のためにクエリされ、１つはｐｃｐｕ上で実行するためにノードから「盗まれる」。それが失敗した場合、ｐｃｐｕは、ポッド／クラスタのどこにも、実行すべき作業を全く見出すことができないので、停止されて、電力を節約するために節電モードにされる。いくつかの実施形態において、ｐｃｐｕは、最大限にビジー状態を維持するために、ハウスキーピングの実行を課せられる。
【０７３６】
したがって、上述のように、ｐｃｐｕが利用可能になると（すなわち、イベントテーブルにｖｃｐｕが格納されたため、ｖｃｐｕマイグレーションが発生するため、もしくは、スタートアップまたはシャットダウン時に、ｖｃｐｕの実行を停止すると）、実行するのに最も適したｖｃｐｕを探して、ｐｃｐｕキューが検索される。ノードに、実行準備のできたｖｃｐｕが完全にない（すなわち、ノードに関連するｐｃｐｕキューがエンプティである）場合、第１ｖｃｐｕは、ＴＴのグローバルルートをプルされ、そのｐｃｐｕ上で復元される。
【０７３７】
複数の戦略が、タイダルツリーからどのｖｃｐｕをプルまたはデキューまたは他の方法で選択するのかを選ぶために用いられてよい。いくつかの実施形態では、コスト関数が、最高利益の戦略に到達するために用いられる。考慮すべき因子の例は、以下を含む。
【０７３８】
１．スタベーションを避けることが好ましい。
【０７３９】
２．ローカリティーゲストスレッドをプルしているノード上でのプルされたゲストスレッドのメモリ状態が参照されてよい。
【０７４０】
３．最少可能数のノードにｖｃｐｕ負荷を圧縮する試みがなされる場合、（ｖｃｐｕ負荷に）不必要ないくつかのノードが、含められずに除外されてよい。
【０７４１】
オーバーコミットメントに関するさらなる詳細
【０７４２】
いくつかの実施形態において、利用可能なｖｃｐｕ（すなわち、実行準備のできたｖｃｐｕ）の各ｐｃｐｕキューの最大長は、調整可能である。キュー長は、起動時に固定されてもよいし、動的に調節可能であってもよい。最大キュー長の決定の一例として、ｐｃｐｕの数がｖｃｐｕの数に等しいことが望ましいと仮定する。最大キュー長は、ｖｃｐｕの数に制限されうるが、これは、システム内のすべてのｖｃｐｕが単一のｐｃｐｕ上にキューアップできることを意味する。いくつかの実施形態において、ノードあたりｐ個のｐｃｐｕがあるｎ−ノードポッドの均一な分散を促すために、ｐｃｐｕあたりの最大キュー長が、以下の式に従って決定されてよい。
【０７４３】
ｐｃｐｕあたりの最大キュー長＝（（ｖｃｐｕの数）／ｎ）／ｐ
【０７４４】
幅広い作業負荷のベストパフォーマンスを提供するキュー長を決定するために、実験を行ってもよい。
【０７４５】
データ構造の例
【０７４６】
ｐ個のｐｃｐｕがハイパーカーネルに割り当てられている仮想化システムを仮定し、ここで、ｐ個のｐｃｐｕは、ｎ個のノードに分散されている。各ノード上の各ｐｃｐｕに対応して、実行準備のできたｖｃｐｕのキューが存在する。最初、キューはエンプティである。いくつかの実施形態において、各ｐｃｐｕは、さらに、起動時に固定されたパターンで検索すべき次のｐｃｐｕを特定する。いくつかの実施形態において、検索は巡回検索であり、ここで、この例においては、検索は、２つのパラメータ（現在のｐｃｐｕおよび開始点）で開始する。検索が開始点に戻ると、すべてのキューが訪問されたことになる。
【０７４７】
物理プロセッサが各ノード上で開始すると、それらのプロセッサは、取り組むべきｖｃｐｕを探す。最初に、物理プロセッサは、ローカルに（例えば、ノードにローカルなｐｃｐｕキュー上を）探し、次いで、グローバルに（例えば、グローバルアクセス可能な「ルート」キューで）探す。タイダルツリーのルートをオーバーロードしないように、スタートアップ時に注意することが好ましい。
【０７４８】
ハウスキーピング関数
【０７４９】
上述のように、例えば、先述のタイダルツリーメカニズムが準備されていると仮定すると、ｖｃｐｕスレッドが、そのｖｃｐｕをＥＴに配置した後に、様々なハウスキーピング関数を直接的または間接的に呼び出してよい。
【０７５０】
いくつかの実施形態において、ハウスキーピングは、（別のＦｒｅｅＢＳＤスレッドとして実装されてよい）バランサスレッドを介して実行されてよい。実施形態の一例において、バランサスレッドは、単一の同期スレッドである。バランサスレッドは、メモリの量を追跡し、他のハウスキーピング関数を実行してよい。バランサスレッドは、上述したサンプリングを実行するために用いられてもよい。バランサスレッドによって取られる動作は、利用度によって決まりうる。一実施形態において、利用度は、以下の３つのレベルに分類される：低、高、および、危機的。
【０７５１】
バランサは、１または複数のｐｃｐｕによって非同期的に実行されてよい。ｐｃｐｕは、匿名である間（すなわち、以前のｖｃｐｕエンティティを脱した後で、新しいｐｃｐｕのアイデンティティを担う前）、或る程度のハウスキーピングを実行してよい。これは、（オーバーロードになりうる１つのスレッドだけでなく）様々なｐｃｐｕにハウスキーピング作業負荷を分散させることを可能にする。
【０７５２】
ｐｃｐｕによって実行されるハウスキーピング作業の量は、様々な要素に応じて様々でありうる。一例として、ｐｃｐｕによって実行されるハウスキーピング作業の量は、上述のように、実行するためにキューアップされたｖｃｐｕの数の合計に依存する。実行準備のできた多数のｖｃｐｕが存在する場合、ハウスキーピングの量は最小限に抑えられることが好ましい。キューアップされたｖｃｐｕが多数ではない場合、より多くのハウスキーピングがｐｃｐｕによって実行されてよい。これは、ｐｃｐｕが、最大限にビジーなままで有用な仕事をすることを可能にする。
【０７５３】
したがって、バランサが行うことを許される追加の作業の量は、制限されている。例えば、ノードが、実行準備のできた多数のｖｃｐｕで過密状態である場合、ハウスキーピングコードは、この情報（すなわち、実行準備のできたｖｃｐｕの数）を用いて、それに従って自身を制限してよく、その結果、ｐｃｐｕは、例えば、ｖｃｐｕのためのコンテナとして利用できるようになる。上述のように、バランサは、いくつのｖｃｐｕがタイダルツリーにあり、したがって、実行準備ができているのか、を示す情報を提供される。実行準備のできたｖｃｐｕが少数であると、バランサは、より多くの時間をハウスキーピングに費やし；多数であると、バランサは、より少ない時間をハウスキーピングの実行に費やす。
【０７５４】
実行されるハウスキーピングの一例は、危機的なメモリ利用レベルの時に（例えば、上述のように、メモリ圧迫が危機的な状態にある時に）、ページを取り除くかまたはエビクトすることである。上述のように、メモリ管理が実行されてよく、メモリ管理は、各ページについて、どのスレッドがページを必要とするのかを追跡すること、および、各スレッドについて、どのページを必要とするのかを追跡することを含む。どのページをエビクトするのかは、かかる情報および優良度メトリックに基づいて決定されてよい。例えば、エビクトに向けてページを評価する時、ページを必要とする各スレッドの優良度メトリックが決定されてよい。例えば、ページを利用しているスレッドが良好に実行している場合、他の条件が全て同じなら、ページはおそらく、エビクトされないことが好ましい。対照的に、スレッドの挙動が悪いページは、エビクトされてよい。
【０７５５】
いくつかの実施形態において、以下のコールはいずれも、ステータスを返さない（一部の例において、それを終わらせうるものがないため）。いくつかの実施形態において、コールは、タイダルツリーからアクティブ化する次のスレッドを選択する機会を許すことなしに、ＦｒｅｅＢＳＤスケジューラを含めさせる任意のコード（例えば、ｗａｉｔなど）を呼び出すことを妨げられる。
【０７５６】
／／いくつかの実施形態において、このコード例は、ＶＣＰＵを別のノードへ送信する前に呼び出され、
【０７５７】
／／ハウスキーピングコードがハウスキーピング処理（予めページを移動するなど）を
【０７５８】
／／実行することを可能にする。
【０７５９】
／／この例において、ｔｓ＿ｌｏａｄ＿ｈｉｎｔは、システムがビジーである（そして自身を制限する）こと、または、
【０７６０】
／／システムがビジーではないことを、
【０７６１】
／／ハウスキーピングコードに示す列挙型（ｅｎｕｍ）である。
【０７６２】
【０７６３】
ｖｏｉｄ  ｔｓ＿ｈｏｕｓｅｋｅｅｐｉｎｇ＿ｏｎ＿ｖｃｐｕ＿ｍｏｖｅ（ｉｎｔ  ｖｃｐｕｉｄ，  ｖｏｉｄ  ＊ａｒｇ，  ｔｓ＿ｌｏａｄ＿ｈｉｎｔ  ｈｉｎｔ）
【０７６４】
【０７６５】
／／いくつかの実施形態において、これは、イベントテーブルにＶＣＰＵを配置した後に呼び出される。
【０７６６】
ｖｏｉｄ  ｔｓ＿ｈｏｕｓｅｋｅｅｐｉｎｇ＿ｉｎｃｒｅｍｅｎｔａｌ（ｔｓ＿ｌｏａｄ＿ｈｉｎｔ  ｈｉｎｔ）
【０７６７】
【０７６８】
以下は、ハウスキーピングシステムが決定を行う場合の一連の事例を規定しており、ここで、本明細書に記載のコスト項の内の１または複数が利用されうる。
【０７６９】
動作すべき時の選択の例：ハウスキーピングは、常に起きる必要がない場合がある。ハウスキーピング関数が、例えば、多すぎるページを送り出すことによって「過剰反応している」場合、これは、潜在的にメモリ断片化を引き起こしうる。一方で、ハウスキーピングが十分高速に動作しない場合、メモリ圧迫により、あまりに多くのｖｃｐｕマイグレーションが余儀なくされていることがある。様々な実施形態において、メモリ容量の推定、アクティブなスレッド／ｖｃｐｕの数、および、ＩＯの頻度が、動作すべき時、および、エビクトされる必要があるページの数の決定を容易にするために用いられる。
【０７７０】
エビクトすべきページの選択の例：いくつかの実施形態において、バランサは、或る短期間内に特定の数のページをエビクトする（例えば、過度のメモリ圧迫を避けるために）。メモリ状態、優良度、共通関心などの項からの入力が、そのノード上のゲストスレッドに関連してノード上の「最も低い」有用性のページをエビクトするため、または、例えば、そのノード上の最低の優良度のゲストスレッドに有用な１セットのページをエビクトするために用いられてよい。様々な代替例が実施されてよい。
【０７７１】
エビクトされる宛先の選択の例：いくつかの実施形態において、メモリは、必要以上に分散されない。他のノードの容量に関する情報が、自身のバランシングの問題を持たないノード上にメモリを移動させる際にバランサを支援するために用いられてよい。
【０７７２】
図１５Ｃは、ストールイベントに対処するための処理の一実施形態を示すフローチャートである。いくつかの実施形態において、処理１５２０は、ハイパーカーネルによって実行される。処理は、物理プロセッサにおいて動作する仮想プロセッサに関連するストールイベントの示唆が受信される工程１５２２で開始する。ストールの一例は、非ローカルページ要求によるものである。
【０７７３】
工程１５４２で、ストールイベントがすぐに対処されうるか否かが判定される。ストールイベントがすぐに対処されうる場合、工程１５２６ですぐに対処され、処理１５２０は終了する（ここで、仮想プロセッサは、ストールの迅速な対処の後に物理プロセッサで動作し続ける）。
【０７７４】
ストールイベントがすぐに対処されえない場合、処理は、工程１５２８へ進み、ここで、仮想プロセッサはイベントテーブルに配置される。例えば、ストールイベントが、非ローカルページアクセスが原因であるために、すぐに対処されえないと仮定する。この例では、ページの要求が送信される。次いで、ｖｃｐｕは、イベントテーブルに配置され（ここで、例えば、その継続がイベントテーブル内に配置される）、そこで、要求されたページを待つ。イベントが発生するかまたは満たされると、仮想プロセッサは、イベントテーブルから外され、タイダルツリー（例えば、図１５Ｅの処理１５６０を用いて、図１５Ａのタイダルツリー１５００）上に配置またはエンキューされる。ｖｃｐｕをイベントテーブルから外して、ｖｃｐｕをタイダルツリー上にエンキューすることは、ｐｃｐｕ上でのｖｃｐｕの実行を効果的にスケジューリングする（ｖｃｐｕは、最終的には、ｐｃｐｕが匿名になって作業を検索した時にｐｃｐｕによって実行されるため）。
【０７７５】
仮想プロセッサを実行していた物理プロセッサは、もはや、ｖｃｐｕを実行しているとは見なされず、現在は匿名である。処理は、工程１５３０へ進み、ここで、物理プロセッサが実行するために、実行準備のできた仮想プロセッサが選択される。実行準備のできた仮想プロセッサを選択するための処理の例は、図９の処理９００および図１５Ｄの処理１５４０を含む。工程１５３２では、選択された仮想プロセッサは、物理プロセッサ上に復元される（ここで、物理プロセッサは、選択された仮想プロセッサのアイデンティティを担い、もはや匿名ではなくなる）。
【０７７６】
いくつかの実施形態において、工程１５３０の前に（例えば、ｐｃｐｕが匿名になった時から、ｐｃｐｕが次のｖｃｐｕアイデンティティを回復する時までの間）、物理プロセッサは、上述のように、ハウスキーピングを実行するよう割り当てられてよい。ハウスキーピング作業が完了すると、処理は、工程１５３０に進む。
【０７７７】
図１５Ｄは、実行準備のできたｖｃｐｕを検索する処理の一実施形態を示すフローチャートである。これは、ｖｃｐｕをタイダルツリーから物理プロセッサへデキューする工程を含んでよい。いくつかの実施形態において、処理１５４０は、ハイパーカーネルによって実行される。いくつかの実施形態において、処理１５４０は、図１５Ｃの処理１５２０の処理工程１５３０および１５３２を実施するために用いられる。
【０７７８】
処理は、ストールイベントの示唆が受信される工程１５４２において始まる。ストールイベントは、ノード上の物理プロセッサで動作する仮想プロセッサに関連する。ノードは、複数の物理プロセッサを備える。ノードは、ノードのクラスタに含まれており、クラスタにわたって、ゲストオペレーティングシステムが集合的に実行される。いくつかの実施形態において、工程１５４２は、図１５Ｃの工程１５２２の一例である。
【０７７９】
工程１５４４で、ノード上の物理プロセッサに対応する１セットのキューで、実行準備のできた仮想プロセッサが検索される。物理プロセッサに対応するキューのセットの例は、図１５Ａに関連して上述したｐｃｐｕキューである。セット内のキューは、概念的なキャッシュ階層順位に従うように検索される。例えば、セット内のキューは、上述のように、所定のトラバースアルゴリズムに従って検索されてよく、ここで、キューの訪問の順序は、キャッシュアフィニティに対応し、ツリーウォークを模倣する。いくつかの実施形態において、訪問および検索される最初のキューは、ストールした仮想プロセッサを実行していた現在は匿名である物理プロセッサに対応するキューである。
【０７８０】
実行準備のできた仮想プロセッサが、ノード上の物理プロセッサに対応するキューのセット内で見つからない場合、クラスタ内の複数のノードにとってグローバルにアクセス可能なルートキューの検索が実行される。
【０７８１】
工程１５４６では、実行準備のできた仮想プロセッサが、検索に基づいて選択される。例えば、トラバース順序で訪問される最初の非エンプティキューの先頭の仮想プロセッサが選択される（ここで、キューはＦＣＦＳである）。いくつかの実施形態において、実行するのに（例えば、匿名物理プロセッサに割り当てるのに）適切なｖｃｐｕが、コスト関数に基づいて選択される。例えば、最も長い時間にわたってキューに入れられていた継続が、割り当てられうる。選択された仮想プロセッサは、物理プロセッサに割り当てられる（例えば、物理プロセッサ上に復元され、ここで、物理プロセッサは、選択された仮想プロセッサのアイデンティティを担う）。
【０７８２】
図１５Ｅは、実行準備のできたｖｃｐｕをタイダルツリーに配置するための処理の一実施形態を示すフローチャートである。これは、ｖｃｐｕをタイダルツリー上にエンキューする工程を備えてよい。いくつかの実施形態において、処理１５６０は、ハイパーカーネルによって実行される。
【０７８３】
処理は、仮想プロセッサの実行準備ができている旨の示唆が受信される工程１５６２において開始する。示唆は、仮想プロセッサが待っていたイベントが発生したことに応じて受信されうる。仮想プロセッサは、それが待っていたイベントが発生した結果として、イベントテーブルから外される。一例として、ストールしたｖｃｐｕがページを要求したと仮定する。ページは到着し、ストールしたｖｃｐｕが待っていたイベントを満たす。例えば、ページが到着すると、イベントテーブルは、どのｖｃｐｕがページ（それのゲスト物理アドレスなど、それのリソース識別子によって識別される）を待っていたのかを決定するためにアクセスされる。仮想プロセッサ（およびページを待つ任意のその他のプロセッサ）は、実行可能にされる。
【０７８４】
工程１５６４では、仮想プロセッサを配置するキューが、少なくとも部分的には、ノード上の１セットの物理プロセッサに対応する１セットのキューをトラバースすることによって決定される。例えば、上述のように、キューの物理ツリーとして実装されたタイダルツリーが検索される。別の例として、タイダルツリーは、実行準備のできたｖｃｐｕのキューのラインまたはセットとして実装され、ここで、ハイパーカーネルに割り当てられた各物理ｃｐｕ（「ｐｃｐｕ」）に１つのキューがあり、物理タイダルツリーの階層は、訪問順序に置き換えられる（例えば、図１５Ａに関連して記載したような最適化タイダルツリー）。いくつかの実施形態において、訪問される最初のキューは、仮想プロセッサが最後に動作していた物理プロセッサに対応する。上述のように、仮想プロセッサの状態（例えば、継続）は、それが動作していた最後の物理プロセッサを示すよう拡張されてよい。ｐｃｐｕがオーバーロードにならない限り、ｖｃｐｕは、キューに配置される。最初のキューが満杯またはオーバーロードであった場合、トラバースは、固定されたトラバース順序に従って、セット内のその他のキューに進む。いくつかの実施形態において、トラバース順序は、システムトポロジによって規定される。トラバース順序は、ツリーウォークを模倣する（例えば、概念ツリーのウォーク）。
【０７８５】
物理プロセッサキューが満杯でない場合、仮想プロセッサは、物理プロセッサキュー上に配置される（例えば、キューの最後すなわち尾部に配置され、ここで、キューはＦＣＦＳである）。したがって、現在作業を探している次のｐｃｐｕは、自身がそれになりうるさらなるｖｃｐｕを検討する必要がある。だから、次のｖｃｐｕがストールすると、ストールしたｖｃｐｕを実行していたｐｃｐｕは、ページ到着の結果としてキューに配置され、最も温かいキャッシュを有し、（キュー上に他のｖｃｐｕがすでに存在しうるため、いつかの時点で）新たなｖｃｐｕになる次のｖｃｐｕを選択する。上述のように、一実施形態において、ｐｃｐｕキューは、外されるｖｃｐｕが、最も長い時間にわたってキューの中にあったｖｃｐｕになるように、ＦＣＦＳまたは先入れ先出し（ＦＩＦＯ）である。非ＦＩＦＯの戦略が用いられてもよい。次いで、コンピュータシステムは、半自動的に自身を最適化してよい。
【０７８６】
ノードの物理プロセッサに対応するキューがすべて、満杯である（および、実行準備のできた仮想プロセッサを配置する物理プロセッサキューがない）場合、一実施形態において、ｖｃｐｕは、クラスタ全体からグローバルにアクセスでき、任意のｐｃｐｕがアクセスできるキュー（「ルート」と呼ぶ）上に配置される。一例として、ルートキューは、クラスタのノード間のプロトコルを通してクラスタ全体にわたるすべてのｐｃｐｕからグローバルにアクセスできるようになっている（例えば、ここで、ルートの内容はブロードキャストされる）。
【０７８７】
上記において、ｖｃｐｕは、ノード上のすべての他のキューが満杯であったために、ルート上に配置された。これは、ローカリティに影響を与えうるため、最も最適な決定ではない場合がある。例えば、所与のノード（例えば、ｖｃｐｕが最後に動作していたノード）上で、ｖｃｐｕは、（例えば、優良度メトリックによって測定して）非常に良好に機能していた可能性がある。別の実施形態において、ルートキュー上にｖｃｐｕを配置する代わりに、ノード上のキューのセットにおいて最もパフォーマンスの低いｖｃｐｕが識別され、それの物理プロセッサキューからエビクトされる。一例として、最もパフォーマンスの低いｖｃｐｕは、上述のように、優良度メトリックに従って決定される。次いで、エビクトされた仮想プロセッサは、実行準備のできた仮想プロセッサのルートであるグローバルアクセス可能なキューに配置される。次いで、実行準備のできた仮想プロセッサは、エビクトされた仮想プロセッサが除去された物理プロセッサキュー上に（例えば、その最後に）配置される（すなわち、ｖｃｐｕがノード上で良好に実行する場合、それほど良好に実行しないノード上の実行準備のできたｖｃｐｕが、パフォーマンスの良好なｖｃｐｕへキュー内の場所を明け渡すことが好ましい）。したがって、上述のように、キューにｖｃｐｕを配置しようとする時に、その優良度は、他のｖｃｐｕの優良度と比較される（ストールしたｖｃｐｕにあるスレッドの優良度と比較する）。次いで、ノード上において優良度で最も悪いパフォーマンスのｖｃｐｕは、ルートへ移動される。したがって、配置されているｖｃｐｕが、ノードのキュー内の別のｖｃｐｕよりもノード上で良好なローカリティを有する場合、よりパフォーマンスの悪いｖｃｐｕがノードから移動され、ルートキューに配置される（すなわち、ｖｃｐｕにおいて実行している最も優良度の低いスレッドが、ルートキューへエビクトされるよう選択されたスレッドである）。
【０７８８】
いくつかの実施形態において、トラバースアルゴリズムは、エンプティコアが利用可能である時に、ハイパースレッド（ｐｃｐｕキュー）上へスレッドを同時スケジューリングしないようにバイアスされる。
【０７８９】
いくつかの実施形態において、キューが長くなりすぎないように、オーバーロード閾値が実施される（例えば、キュー上に最大で３つのｖｃｐｕ）。オーバーロード閾値は、起動時パラメータであってよい。例えば、ノード上のすべてのｐｃｐｕキューが満杯であると仮定する。例えば、キューの長さは合わせると、ノードが対応できるよりも長くなる場合がある。例えば、ノード上に複数のｐｃｐｕがあると、２倍、３倍、ないし、１０倍の数のｖｃｐｕが存在しうる。オーバーロード閾値は、優良度メトリックと共に、ノード上の最もパフォーマンスの低いｖｃｐｕをルートキューへエビクトさせる。これは、プロセッサを分散させ、フロッキング／オーバーロードを防止する利点を有する。また、この結果、ページとのローカリティを形成することになる（すなわち、ワーキングセットを構築する）。また、仮想化システム全体の負荷が、需要駆動でバランスされうる。
【０７９０】
上述の実施形態は、理解しやすいようにいくぶん詳しく説明されているが、本発明は、提供された詳細事項に限定されるものではない。本発明を実施する多くの代替方法が存在する。開示された実施形態は、例示であり、限定を意図するものではない。
【図１】
2019528539.tif 000003
【図２】
2019528539.tif 000004
【図３Ａ】
2019528539.tif 000005
【図３Ｂ】
2019528539.tif 000006
【図４Ａ】
2019528539.tif 000007
【図４Ｂ】
2019528539.tif 000008
【図５】
2019528539.tif 000009
【図６Ａ】
2019528539.tif 000010
【図６Ｂ】
2019528539.tif 000011
【図７】
2019528539.tif 000012
【図８】
2019528539.tif 000013
【図９】
2019528539.tif 000014
【図１０】
2019528539.tif 000015
【図１１】
2019528539.tif 000016
【図１２】
2019528539.tif 000017
【図１３Ａ】
2019528539.tif 000018
【図１３Ｂ】
2019528539.tif 000019
【図１３Ｃ】
2019528539.tif 000020
【図１３Ｄ】
2019528539.tif 000021
【図１３Ｅ】
2019528539.tif 000022
【図１４Ａ】
2019528539.tif 000023
【図１４Ｂ】
2019528539.tif 000024
【図１４Ｃ】
2019528539.tif 000025
【図１４Ｄ】
2019528539.tif 000026
【図１４Ｅ】
2019528539.tif 000027
【図１４Ｆ】
2019528539.tif 000028
【図１５Ａ】
2019528539.tif 000029
【図１５Ｂ】
2019528539.tif 000030
【図１５Ｃ】
2019528539.tif 000031
【図１５Ｄ】
2019528539.tif 000032
【図１５Ｅ】
2019528539.tif 000033
【国際調査報告】
2019528539.tif 000034
2019528539.tif 000035
2019528539.tif 000036