(57)【要約】  効率的なパフォーマンスを達成するためにソフトウェアトランザクショナルメモリ命令に対する最適化を実行するソフトウェアトランザクショナルメモリシステムを説明する。ソフトウェアトランザクショナルメモリブロックが、ソフトウェアトランザクショナルメモリ命令によって置換され、このソフトウェアトランザクショナルメモリ命令は、さらに、分解されたソフトウェアトランザクショナルメモリ命令に分解される。分解された命令は、命令セマンティクスの知識を有するコンパイラが、伝統的なソフトウェアトランザクショナルメモリシステムでは使用不能な最適化を実行することを可能にする。プロシージャ呼出しの前後でのコード移動、強い原子性を提供するための動作の追加、不必要なｒｅａｄ−ｔｏ−ｕｐｄａｔｅアップグレードの除去、および新たに割り振られたオブジェクトに関する動作の除去など、高水準ソフトウェアトランザクショナルメモリ最適化が実行される。【特許請求の範囲】
【請求項１】
コンピュータシステム内の方法であって、前記コンピュータシステムは、処理ユニットおよびコンパイラを含み、前記コンパイラは、ソフトウェアトランザクショナルメモリ動作の知識を用いて構成され、前記方法は、プログラムをコンパイルするために実行され、前記プログラムは、ソフトウェアトランザクショナルメモリブロックを含み、前記方法は、
ソフトウェアトランザクショナルメモリ命令を含む最適化されたプログラムを作成するために前記プログラムを最適化すること（４６０）と、
前記最適化されたプログラムをコンパイルすること（３４０）と
を含むことを特徴とする方法。
【請求項２】
前記プログラムを最適化することは、
前記プログラムの前記ソフトウェアトランザクショナルメモリブロックに直接アクセスソフトウェアトランザクショナルメモリ命令を挿入することと、
最適化の少なくとも一部が、特に前記直接アクセスソフトウェアトランザクショナルメモリ命令に対して動作するように構成されるように、最適化されたプログラムを作成するために、前記ソフトウェアトランザクショナルメモリ命令を含む、前記プログラムに対する前記最適化を実行することと
を含むことを特徴とする請求項１に記載の方法。
【請求項３】
最適化を実行することは、分解されたソフトウェアトランザクショナルメモリ命令に対して動作するように変更された共通部分式除去プロシージャを実行することを含むことを特徴とする請求項２に記載の方法。
【請求項４】
前記共通部分式除去プロシージャは、読取のためにオブジェクトをオープンする命令が、同一トランザクション内の更新のためにオブジェクトをオープンする命令の後で除去されるように変更されることを特徴とする請求項３に記載の方法。
【請求項５】
前記共通部分式除去プロシージャは、メモリアドレスに対する冗長な読取および書込ならびにトランザクション内のメモリアドレスに関する冗長なログが除去されるように変更されることを特徴とする請求項３に記載の方法。
【請求項６】
前記共通部分式除去プロシージャは、さらに、第１トランザクション内の読取および書込が、第２トランザクション内の読取または書込によって冗長にされる場合に前記第１トランザクション内の前記読取および前記書込が除去されるように変更され、前記第１トランザクションは、前記第２トランザクション内にネストされることを特徴とする請求項５に記載の方法。
【請求項７】
最適化を実行することは、コード移動最適化を実行することを含むことを特徴とする請求項２に記載の方法。
【請求項８】
最適化を実行することは、メモリトランザクションの外部でオブジェクトにアクセスする少なくとも１つの非トランザクショナルメモリ動作を、前記オブジェクトに対するトランザクショナルメモリアクセスと前記非トランザクショナルメモリ動作との間の原子性を保証する１つまたは複数のトランザクショナルメモリ動作を用いて増補することを含むことを特徴とする請求項２に記載の方法。
【請求項９】
非トランザクショナルメモリ動作を増補することは、
前記非トランザクショナルメモリ動作の前に、前記非トランザクショナルメモリ動作によるアクセスのために前記オブジェクトをオープンするオープン動作を挿入することと、
前記非トランザクショナルメモリ動作の後に、前記非トランザクショナルメモリ動作の実行中に前記オブジェクトに対する衝突するアクセスがあったかどうかを判定するコミット動作を挿入することと
を含むことを特徴とする請求項８に記載の方法。
【請求項１０】
前記非トランザクショナルメモリ動作は、読取動作であり、
前記オープン動作は、前記非トランザクショナルメモリ動作の実行の前に、前記オブジェクトの状態の表示を取り出すように構成され、
前記コミット動作は、
前記非トランザクショナルメモリ動作の実行の後に前記オブジェクトの状態の表示を取り出し、
前記オブジェクトの状態が衝突するアクセスを示す場合に、読取が可能になるまで、前記オープン動作、前記読取動作、および前記コミット動作をループさせる
ように構成される
ことを特徴とする請求項９に記載の方法。
【請求項１１】
前記非トランザクショナルメモリ動作は、書込動作であり、
前記オープン動作は、前記オブジェクトへの書込アクセスを入手するように構成され、
前記コミット動作は、前記オブジェクトに対して行われた前記書込をコミットするように構成される
ことを特徴とする請求項９に記載の方法。
【請求項１２】
前記オープンコマンドおよび前記コミットコマンドは、前記非トランザクショナルメモリ動作が原子的に実行することを保証するために、前記オブジェクトに対する同期化を利用することを特徴とする請求項９に記載の方法。
【請求項１３】
前記オープンコマンドは、アクセスのために前記オブジェクトをオープンできるまでブロックすることを特徴とする請求項９に記載の方法。
【請求項１４】
メモリトランザクションの外部でオブジェクトにアクセスする１つまたは複数のメモリ動作を識別することをさらに含むことを特徴とする請求項８に記載の方法。
【請求項１５】
１つまたは複数のメモリ動作を識別することは、
前記ソフトウェアの実行中にトランザクショナルメモリ動作によってアクセスされ得るフィールドを判定するためにトランザクショナルメモリアクセスを分析することと、
トランザクショナルメモリ動作によってアクセスされ得るフィールドにアクセスする１つまたは複数の非トランザクショナルメモリ動作を識別することと
を含むことを特徴とする請求項１４に記載の方法。
【請求項１６】
トランザクショナルメモリ動作によってアクセスされないことが保証される任意のフィールドについて、そのフィールドにアクセスする非トランザクショナルメモリ動作を増補することは、回避されることを特徴とする請求項１５に記載の方法。
【請求項１７】
１つまたは複数のトランザクショナルメモリ動作を用いてメモリトランザクションの外部でオブジェクトにアクセスする非トランザクショナルメモリ動作を増補することは、前記非トランザクショナルメモリ動作の前後に原子的メモリトランザクションブロックを挿入することを含むことを特徴とする請求項１６に記載の方法。
【請求項１８】
最適化を実行することは、
プログラム点のセットでトランザクション内の新たに割り振られたオブジェクトに必ず束縛されるオブジェクトへの参照を識別することと、
前記識別された参照を介して達するオブジェクトに対するソフトウェアトランザクショナルメモリ動作を防ぐことであって、前記動作は、前記トランザクションの外部で効果を有しない、防ぐことと
を含むことを特徴とする請求項２に記載の方法。
【請求項１９】
プログラム点のセットで新たに割り振られたオブジェクトに必ず束縛されるオブジェクトへの参照を識別することは、プロシージャ呼出しにまたがって発生することを特徴とする請求項１８に記載の方法。
【請求項２０】
プログラム点のセットで新たに割り振られたオブジェクトに必ず束縛されるオブジェクトへの参照を識別することは、前記プログラムに対して順方向データフロー分析を実行することを含むことを特徴とする請求項１９に記載の方法。
【請求項２１】
前記順方向データフロー分析は、基本ブロック内の変数が、新たに割り振られるオブジェクトに必ず代入されるか、おそらくは前記トランザクションの外部で割り振られるオブジェクトに代入され得るかのいずれかであることがわかっているかどうか、または情報が前記変数について未知であるかどうかを、各前記変数について前記基本ブロック内の位置で表すデータ構造を前記基本ブロックごとに維持することを含むことを特徴とする請求項２０に記載の方法。
【請求項２２】
前記データ構造は、各参照から参照ごとに保たれるデータへのマップを含み、参照ごとに保たれる前記データは、格子値および参照の間の依存性を含む更新可能なセルを含むことを特徴とする請求項２１に記載の方法。
【請求項２３】
前記データ構造を維持することは、前記データフロー分析が進行する際に格子値の前記更新可能なセルを介して参照の間の前記依存性を使用して情報を伝搬させることを含むことを特徴とする請求項２２に記載の方法。
【請求項２４】
情報を伝搬させることは、マッピングされない変数のプログラムステートメントが分析される前に、変数から格子値の更新可能なセルへの前記マップ内の前記マッピングされない変数に情報を分配することを含むことを特徴とする請求項２３に記載の方法。
【請求項２５】
前記識別された参照を介して達するオブジェクトに対するソフトウェアトランザクショナルメモリ動作を防ぐことであって、前記動作は、前記トランザクションの外部で効果を有しない、防ぐことは、参照ごとに、前記参照を介する更新動作を、分解されたソフトウェアトランザクショナルメモリ動作に分解されたときに更新ログ動作を含まない更新動作に置換することを含むことを特徴とする請求項１８に記載の方法。
【請求項２６】
前記識別された参照を介して達するオブジェクトに対するソフトウェアトランザクショナルメモリ動作を防ぐことであって、前記動作は、前記トランザクションの外部で効果を有しない、防ぐことは、ソフトウェアトランザクショナルメモリ動作が分解されたソフトウェアトランザクショナルメモリ動作に分解された後に、前記識別された参照を介して動作する分解されたログ動作を除去することを含むことを特徴とする請求項１８に記載の方法。
【請求項２７】
前記識別された参照のうちのどれが、前記トランザクションの後にアクセス可能ではないオブジェクトに対するものであるかを判定することをさらに含み、
前記識別された参照を介して達するオブジェクトに対するソフトウェアトランザクショナルメモリ動作を防ぐことであって、前記動作は、前記トランザクションの外部で効果を有しない、防ぐことは、前記判定された参照を介する読取または更新のためにオブジェクトをオープンするソフトウェアトランザクショナルメモリ動作を除去することを含む
ことを特徴とする請求項１８に記載の方法。
【請求項２８】
最適化を実行することは、
実行中に更新のために参照をオープンする第１ソフトウェアトランザクショナルメモリ命令が続くことがわかっている、読取のために前記参照をオープンするソフトウェアトランザクショナルメモリ命令を突き止めることと、
読取のために前記参照をオープンする前記命令を、更新のために前記参照をオープンする第２命令に置換することと
を含むことを特徴とする請求項２に記載の方法。
【請求項２９】
前記方法は、さらに、更新のために前記参照をオープンする前記第１命令を除去することを含むことを特徴とする請求項２８に記載の方法。
【請求項３０】
前記第１命令を除去することは、前記第１命令を含む冗長命令を除去するために共通部分式除去を使用することを含むことを特徴とする請求項２９に記載の方法。
【請求項３１】
前記ソフトウェアは、制御フローグラフによって表され、前記方法は、前記制御フローグラフに対して実行されることを特徴とする請求項２８に記載の方法。
【請求項３２】
読取のために参照をオープンする命令を突き止めることは、前記制御フローグラフ内の基本ブロックについて、
読取のために参照をオープンする命令を識別することと、
前記参照を記録することと、
前記基本ブロックを通って前記識別された命令から順方向にスキャンすることと、
前記参照への代入が見つかるときに、前記識別された命令に関するスキャンを停止することと、
更新のために前記参照をオープンする命令が見つかるときに、前記識別された命令の置換に進むことと
を含むことを特徴とする請求項３１に記載の方法。
【請求項３３】
読取のために参照をオープンする命令を突き止めることは、前記制御フローグラフ内の基本ブロックについて、
更新のために参照をオープンする命令を識別することと、
前記参照を記録することと、
前記基本ブロックを通って前記識別された命令から逆方向にスキャンすることと、
前記参照への代入が見つかるときに、前記識別された命令に関するスキャンを停止することと、
読取のために前記参照をオープンする命令が見つかるときに、読取のために前記参照をオープンする前記見つかった命令の置換に進むことと
を含むことを特徴とする請求項３１に記載の方法。
【請求項３４】
読取のために参照をオープンする命令を突き止めることは、更新のために参照をオープンする命令によって冗長にされる、読取のために参照をオープンする命令を基本ブロック境界にまたがって検索するデータフロー分析を実行することを含むことを特徴とする請求項３１に記載の方法。
【請求項３５】
データフロー分析を実行することは、
更新のためにオープンされた参照を参照することがわかっている前記制御フローグラフ内の各基本ブロックの前記境界で変数のセットを維持することと、
基本ブロックごとに、
前記制御フローグラフを通って逆方向にスキャンすることと、
特定の変数について更新のために参照をオープンする命令が見つかるときに、その変数を前記基本ブロックの変数の前記セットに追加することと、
特定の変数について定義が見つかるときに、その変数を前記基本ブロックの変数の前記セットから除去することと、
前記基本ブロックの始めが見つかるときに、前記基本ブロックの前記変数セットを、前記基本ブロックに直接につながる基本ブロックの終りに記憶された変数セットと交差させることと、
変数の安定したセットが基本ブロックごとに作成されるまでこのプロセスを繰り返すことと、
基本ブロックごとに、前記基本ブロックの変数の前記セットによって参照される参照を読取のためにオープンする命令を冗長命令と考えることと
を含むことを特徴とする請求項３４に記載の方法。
【請求項３６】
最適化を実行することは、
前記プログラム内の１つまたは複数のプロシージャであって、前記プロシージャの外部で最適化され得る１つまたは複数のソフトウェアトランザクショナルメモリ動作を含む前記１つまたは複数のプロシージャを識別することと、
前記１つまたは複数のプロシージャのそれぞれについて、前記プロシージャのクローン化されたバージョンの外部で最適化され得る前記ソフトウェアトランザクショナルメモリ動作の呼出しを可能にする前記クローン化されたバージョンを作成することと、
前記プロシージャの外部で最適化され得る前記１つまたは複数のソフトウェアトランザクショナルメモリ動作を移動することと、
前記１つまたは複数のプロシージャのそれぞれへの呼出しをそのクローン化されたバージョンへの呼出しに置換することと
を含むことを特徴とする請求項２に記載の方法。
【請求項３７】
最適化され得る前記１つまたは複数のソフトウェアトランザクショナルメモリ動作の間で冗長性を除去することによって前記プログラムを最適化することをさらに含むことを特徴とする請求項３６に記載の方法。
【請求項３８】
前記プログラムを最適化することは、前記プログラムに対して共通部分式除去を実行することを含むことを特徴とする請求項３７に記載の方法。
【請求項３９】
最適化され得る前記１つまたは複数のソフトウェアトランザクショナルメモリ動作は、トランザクションマネージャを得る動作を含むことを特徴とする請求項３７に記載の方法。
【請求項４０】
トランザクションマネージャを得る動作を含むプロシージャのクローン化されたバージョンは、入力としてトランザクションマネージャのインスタンスをとるプロシージャを含むことを特徴とする請求項３９に記載の方法。
【請求項４１】
最適化され得る前記１つまたは複数のソフトウェアトランザクショナルメモリ動作は、読取または更新のために参照をオープンする動作を含み、前記参照は、入力として前記プロシージャにわたされることを特徴とする請求項３７に記載の方法。
【請求項４２】
読取または更新のために参照をオープンする動作を含むプロシージャのクローン化されたバージョンは、前記プロシージャが呼び出される前に前記参照がオープンされることに頼るプロシージャを含むことを特徴とする請求項４１に記載の方法。
【請求項４３】
読取または更新のために参照をオープンする動作を含むプロシージャのクローン化されたバージョンを作成することは、どのプロシージャが前記プロシージャの始めに既知である参照について読取または更新のために参照をオープンする動作を含むかを判定するために逆方向データフロー分析を実行することを含むことを特徴とする請求項４２に記載の方法。
【発明の詳細な説明】
【背景技術】
【０００１】
本願は、２００５年１２月７日出願の米国特許仮出願第６０／７４８，３８６号明細書の利益を主張する２００６年３月２３日出願の米国特許出願第１１／３８９，４５１号明細書の利益を主張するものである。
【０００２】
マルチスレッドプロセスの複数のスレッドが並行実行中に共通のメモリ位置を共有することが、一般的である。その結果、マルチスレッド式プロセスの２つの異なるスレッドが、プログラムによってアクセス可能な同一のメモリ位置を読み取り、更新する可能性がある。しかし、一方のスレッドが共有メモリ位置の値に依存する動作のシーケンスの途中である間に、他方のスレッドがその値を変更しないことを保証するために注意を払わなければならない。
【０００３】
例えば、あるプログラムが、２つの異なるソフトウェアオブジェクトの内容にアクセスしており、各オブジェクトが、異なる銀行口座の金額を表すと仮定する。当初に、第１口座の金額は１０ドルであり、メモリアドレスＡ１にストアされ、第２口座の金額は、２００ドルであり、メモリアドレスＡ２にストアされる。バンキングプログラムの第１スレッドは、Ａ２からＡ１に１００ドルを転送するようにコーディングされ、第２スレッドは、両方の口座の資金の総額を計算するようにコーディングされている。第１スレッドは、Ａ１の内容に１００ドルを加算し、これを１１０ドルに更新することによって開始し、その後、Ａ２の内容から１００ドルを減算し、これを１００ドルに更新することに進む。しかし、第２スレッドが、この２つの動作の間に実行される場合に、第２スレッドは、２１０ドルという正しい合計ではなく、両方の口座の３１０ドルという不正な合計を計算する場合がある。
【０００４】
ソフトウェアトランザクショナルメモリは、スレッドが一連の共有メモリアクセスを安全に実行できるプログラミング抽象化を提供し、スレッドが、別のスレッドからの干渉なしでそのトランザクションを完了することを可能にする。したがって、トランザクショナルメモリをソフトウェアで使用して、第１スレッドの例示的な加算演算および減算演算を含むトランザクションが、メモリ位置Ａ１およびＡ２に関して「原子的」であり、したがって、第２スレッドが両方の口座の正しい総額を計算するようになることを保証することができる。
【発明の開示】
【発明が解決しようとする課題】
【０００５】
しかし、ソフトウェアでトランザクショナルメモリを実施する既存の手法は、性能問題をこうむる。例えば、１つの既存手法では、あるスレッドがトランザクション内でメモリ位置のシーケンスにアクセスするときに、そのスレッドは、それがトランザクション中に読み取り、更新する（すなわち、書き込む）ことを望むメモリ位置および値の別々のリストを維持し、その後、このトランザクションの終りに、そのスレッドが、実際の共有メモリ位置のこれらの値のすべてを更新する。このトランザクション中に、そのスレッドがそのリスト内のメモリ位置のいずれかを再読取するか再書込することを望む場合に、そのスレッドは、エントリにアクセスするためにリスト内のメモリ位置のエントリを検索しなければならず、これは、プログラム的に低速の仕事である。したがって、ソフトウェアでトランザクショナルメモリを実施するこの間接的方法は、低い性能に悩まされる。
【０００６】
さらに、ソフトウェアでトランザクショナルメモリを実施する既存の手法は、トランザクショナルメモリへの不必要な呼出しおよびレコードを保持する命令を含むかなりのオーバーヘッドを導入し、特にこれらの命令が非効率的な形で実行される場合に、プログラムの実行に損害を与える。さらに、一部のトランザクショナルメモリ方式に固有のレコードを保持するアクティビティは、それらが作成するレコードの作成および維持を効果的に制限せず、これは、メモリならびにディスクスペースおよび他のシステムリソースを浪費する可能性がある。
【課題を解決するための手段】
【０００７】
ソフトウェアトランザクショナルメモリシステム（「ＳＴＭ」）を説明する。本明細書で説明するシステムおよび技法は、ソフトウェアトランザクショナルメモリ命令に対する最適化を実行して、効率的なパフォーマンスを達成する。ソフトウェアトランザクショナルメモリブロックをソフトウェアトランザクショナルメモリ命令に置換し、さらに、これらの命令を分解されたソフトウェアトランザクショナルメモリ命令に分解するコンパイラを説明する。このコンパイラは、命令セマンティクスの知識を利用して、伝統的なソフトウェアトランザクショナルメモリシステムでは使用不能な最適化を実行する。このコンパイラは、さらに、ＳＴＭコードに対する高水準最適化を実行する。これらの最適化の一部は、低水準最適化を活用するために実行される。これらの高水準最適化は、不必要なｒｅａｄ−ｔｏ−ｕｐｄａｔｅアップグレードの除去、プロシージャ呼出しの前後でのＳＴＭ動作の移動、および新たに割り振られたオブジェクトに対する不必要な動作の除去を含む。さらに、ＳＴＭコードは、トランザクションの外部で書き込まれるメモリアクセスに対する強い原子性を提供するように最適化される。
【０００８】
一例で、処理ユニットと、ソフトウェアトランザクショナルメモリ動作の知識を用いて構成されたコンパイラとを含むコンピュータシステム内で、ソフトウェアトランザクショナルメモリブロックを含むプログラムをコンパイルする方法を説明する。この方法は、ソフトウェアトランザクショナルメモリ命令を含む最適化されたプログラムを作成するためにプログラムを最適化することと、最適化されたプログラムをコンパイルすることとを含む。
【０００９】
この「課題を解決するための手段」は、下の「発明を実施するための最良の形態」でさらに説明する概念の抜粋を単純化された形で紹介するために提供される。この「課題を解決するための手段」は、請求される主題の主要な特徴または本質的特徴を識別することを意図されたものではなく、請求される主題の範囲を判定する際の助けとして使用されることを意図されたものでもない。
【００１０】
追加の特徴および利益は、添付図面を参照して進行する、実施形態の次の詳細な説明から明白になる。
【発明を実施するための最良の形態】
【００１１】
本明細書で示す例は、ソフトウェアベースおよびハードウェアベースのトランザクショナルメモリシステムおよびこれらのシステムでの性能改善の例を説明する。具体的に言うと、下の実施態様の例は、分解されたソフトウェアトランザクション動作、コード最適化を可能にするためのコンパイラ中間表現（「ＩＲ」）でのＳＴＭプリミティブの使用（この用語は下で説明する）、これらのプリミティブに関する性能を改善するように働くコンパイラの改善、アソシアティブテーブル（ａｓｓｏｃｉａｔｉｖｅ  ｔａｂｌｅ）を使用するランタイムログフィルタリング、および効率的なランタイムのオブジェクトごとの動作を説明する。本明細書で提供される説明は、特定のソフトウェアトランザクショナルメモリ実施態様の最適化として提供されるが、本明細書で説明する技法およびシステムが、様々な実施態様で動作でき、必ずしも本明細書で説明する技法の実施態様、性能、または要件に対する限定を暗示しないことを理解されたい。
【００１２】
１．ソフトウェアトランザクショナルメモリシステムの例
原子的ブロックは、並行プログラムを記述するという問題に対する有望な単純化を提供する。本明細書で説明するシステムでは、あるコードブロックが、原子的とマークされ、コンパイラおよびランタイムシステムは、関数呼出しを含むそのブロック内の動作が原子的に見えることを提供する。プログラマは、もはや、手動ロック、低水準競合条件、またはデッドロックを気にする必要がなくなる。原子的ブロックは、例外回復をも提供することができ、これによって、あるブロックが例外によって終了される場合に、そのブロックの副作用がロールバックされる。これは、シングルスレッドアプリケーションにおいても貴重である。というのは、エラーハンドリングコードが、しばしば、記述しテストするのが難しいからである。原子的ブロックの実施態様は、大規模マルチプロセッサマシンにもスケーリングされる。というのは、この実施態様が、並列性を保存するからであり、原子的ブロックは、あるブロックで更新される位置が他のブロックのいずれにおいてもアクセスされない限り、並行に実行することができる。これは、従来のデータキャッシュで許容される種類の共有を保存する。
【００１３】
本明細書で説明する技法は、コンパイラおよびランタイムシステムに緊密に統合されたＳＴＭ実施態様に関連するようにされる。この実施態様の１つの特徴は、直接更新ＳＴＭであることである。これは、オブジェクトのプライベートシャドウコピーを操作するのでも、オブジェクト参照と現在のオブジェクト内容との間の余分なレベルのインダイレクションを介するのでもなく、オブジェクトをヒープ内で直接に更新することを可能にする。これは、成功してコミットされるトランザクションについてより効率的である。
【００１４】
本明細書で説明するシステムおよび技法は、分解されたＳＴＭインターフェースを提供する実施態様の特徴を利用する。例えば、トランザクショナルストアｏｂｊ．ｆｉｅｌｄ＝４２は、（ａ）ｏｂｊが現在のスレッドによって更新されようとしていることを記録するステップと、（ｂ）ｆｉｅｌｄが保持する古い値をログ記録するステップと、（ｃ）新しい値４２をｆｉｅｌｄにストアするステップとに分割される。この新設計は、トランザクション動作に対して古典的な最適化を提供することを可能にする。例えば、この例の３つのステップは、コンパイラによって別々に処理され、（ａ）および（ｃ）は、しばしばループからホイストすることができる。本明細書で説明する技法では、分解されたＳＴＭインターフェースは、ＳＴＭインターフェースおよびセマンティクスの特定の知識を有し、特にこのインターフェース上で働くように構成された最適化を実行できるコンパイラの使用を介して、より効率的にされる。
【００１５】
もう１つの例で、本明細書で説明するシステムおよび技法は、統合されたトランザクションバージョニングを利用する効率的なオブジェクトごとの動作を介する、説明されるＳＴＭ実施態様の効率を示す。これらの実施態様は、既存のオブジェクトヘッダワードを用いるトランザクショナルバージョニングの統合を使用する。これは、他のＳＴＭシステムとは異なる。というのは、これらのシステムが、バージョニングレコードの外部テーブル、追加のヘッダワード、またはオブジェクト参照と現在のオブジェクト内容との間のインダイレクションのレベルのいずれかを使用するからである。これらの手法は、低いキャッシュ局所性を引き起こすか、スペース使用量を増やす。本明細書で説明する実施態様は、膨張させられた（ｉｎｆｌａｔｅｄ）ヘッダワードを、トランザクショナルコミット中のオブジェクト変更のすばやい検証を可能にする効率的なスナップショット命令と共に利用する。
【００１６】
さらに、ランタイムログフィルタリングを説明する。このフィルタリングは、すべての不必要なＳＴＭ動作をコンパイル時に静的に識別できるわけではないので、有用である。
【００１７】
一実施態様で、本明細書で説明する例は、Ｂａｒｔｏｋすなわち、Ｍｉｃｒｏｓｏｆｔ  ．ＮＥＴプラットフォームと対抗する性能を有する共通中間言語（ＣＩＬ）プログラムの最適化ａｈｅａｄ−ｏｆ−ｔｉｍｅ研究コンパイラおよびランタイムシステムで実施される。このランタイムシステムは、ガーベジコレクタおよび新しいＳＴＭを含めてＣＩＬで実施することができる。
【００１８】
１．１  セマンティクス
本明細書で説明する技法は、原子的ブロックの実行に焦点を合わせたものである。様々な実施態様は、ロックするコードとの原子的ブロックの相互作用、およびこれらの技法を利用し続けながらの原子的ブロックとの入出力動作の組合せを含めて、正確なセマンティクスにおいて異なる可能性がある。
【００１９】
１．２  設計の仮定
本明細書で説明する例では、原子的ブロックをどのように使用するかに関していくつかの仮定を行う。これらは、必ずしも本明細書で説明する実施態様に対する限定を表すのではなく、説明を容易にするように働くものである。
【００２０】
１つの仮定は、ほとんどのトランザクションが成功してコミットされることである。これは、穏当な仮定である。というのは、第１に、並列性を保存するＳＴＭの使用が、トランザクションが「自発的に」すなわちプログラマが理解できない衝突のゆえに異常終了しないことを意味するからである（代替実施態様では、衝突は、ハッシュ値に基づいて検出され、ハッシュ値は、予期されずに衝突する可能性がある）。これの一部として、プログラマが、キャッシュの間の過度なデータ移動のコストのゆえに、競合を回避する強いインセンティブを既に有すると仮定する。激しい競合動作を単一のスレッドによって管理される作業キューにわたすことなどの技法は、価値があるままである。
【００２１】
第２の仮定は、原子的ブロックで、読取が数において更新に優ることである。この仮定は、現在のプログラムの観察および現在のプログラムのトランザクショナルバージョンを開発する試みから生まれたものである。これは、トランザクショナル読取のオーバーヘッドを特に低く保つことの利益を強調する。読取は、読み取られるオブジェクトのアドレスおよびそのヘッダワードの内容のログ記録だけを伴う。
【００２２】
最後の仮定は、トランザクションサイズを制限してはならないことである。これは、コンポジショナリティを維持すると同時に、トランザクションの長さが増えるときにＳＴＭ実施態様が良好にスケーリングする必要があることを暗示する。この設計では、スペースオーバーヘッドは、行われるアクセスの回数ではなく、トランザクションでアクセスされるオブジェクトの量に伴って増加する。本明細書で説明する例では、トランザクションを、非形式的に「短い」または「長い」と称する。短いトランザクションは、ＳＴＭによるメモリ割振りを一切必要とせずに動作する可能性が高い。長いトランザクションは、その実行がＧＣサイクルにまたがる可能性が高いトランザクションである（例えば、ＳＰＥＣ９５ベンチマークｘｌｉｓｐのＣ＃に変換されたバージョンのＬＩＳＰベンチマークのうちの１つの評価）。
【００２３】
１．３  ワードベースのＳＴＭの例
ワードベースのＳＴＭの１つの従来のインターフェースは、次の２セットの動作を提供する。
【００２４】
【表１】
2009523271.tif 000002
【００２５】
第１セットは、トランザクションを管理する。ＴＭＳｔａｒｔは、現在のスレッドでトランザクションを開始する。ＴＭＡｂｏｒｔは、現在のスレッドのトランザクションを異常終了する。ＴＭＣｏｍｍｉｔは、現在のスレッドのトランザクションをコミットすることを試みる。トランザクションがコミットできない（例えば、一実施態様で、並行トランザクションが、それがアクセスした位置のうちの１つを更新済みなので）場合には、ＴＭＣｏｍｍｉｔは、偽を返し、現在のトランザクションは、破棄される。そうでない場合には、ＴＭＣｏｍｍｉｔは、真を返し、そのトランザクション中に行われたすべての更新が、共有ヒープに原子的に伝搬される。ＴＭＩｓＶａｌｉｄは、呼出しの時点で現在のスレッドのトランザクションをコミットできる場合に限って真を返す。動作の第２セットは、データアクセスを実行する。ＴＭＲｅａｄは、指定された位置の現在の値、または現在のトランザクション内でＴＭＷｒｉｔｅによって書き込まれた最新の値を返す。
【００２６】
本明細書で説明する技法の一実施態様では、ＳＴＭを直接にプログラムするプロセスは、コンパイラに、ＳＴＭ動作を使用するように原子的ブロック内のメモリアクセスを書き直させることと、コンパイラに、ＴＭＲｅａｄおよびＴＭＷｒｉｔｅが１つの原子的ブロック内で行われるすべてのメモリアクセスに使用されることを保証するために、呼び出されるメソッドの特殊化されたバージョンを生成させることとによって自動化される。
【００２７】
上で説明した設計は、その適用可能性を制限する複数の問題から損害を受ける。次のコードの例に、これを示す。下に示す例１ａは、センチネルノードｔｈｉｓ．Ｈｅａｄとセンチネルノードｔｈｉｓ．Ｔａｉｌとの間でリンクリストの要素を通って反復する。例１ａは、ノードのＶａｌｕｅフィールドを合計し、その結果をｔｈｉｓ．Ｓｕｍにストアする。例１ｂは、すべてのメモリアクセスについてＴＭＲｅａｄおよびＴＭＷｒｉｔｅへの呼出しを自動的に配置することの１つの例を示す。
【００２８】
しかし、複数の性能問題が、このワードベースのシステムに関して発生する可能性がある。第１に、ＴＭＲｅａｄおよびＴＭＷｒｉｔｅの多数の実施態様は、すべてのＴＭＲｅａｄ動作およびＴＭＷｒｉｔｅ動作の際に検索されるトランザクションログを使用する。ＴＭＲｅａｄは、同一トランザクションによる以前のストアを知らなければならず、したがって、仮更新を保持するトランザクションログを検索する。そのような検索は、大きいトランザクションをサポートするようにスケーリングしない可能性がある。性能は、トランザクションログの長さおよび補助インデックス構造体の有効性に依存する。第２に、ＳＴＭライブラリへの不透明な呼出しが、最適化を妨げる（例えば、ＴＭＲｅａｄの挙動がコンパイラに未知なので、ｔｈｉｓ．Ｔａｉｌをループからホイストすることは、もはや不可能である）。最後に、モノリシックなＴＭ動作は、作業の繰り返しを引き起こす。例えば、あるフィールドにループ内でアクセスするときの検索の繰り返しである。
【００２９】
１．４  分解された直接アクセスＳＴＭ
分解された直接アクセスＳＴＭ実施態様は、本明細書で提供する例で使用されるが、これらの問題に対処する。第１の問題は、トランザクションが、ヒープに対して直接に読取動作および書込動作を実行できるようになり、読取が、先行するトランザクショナルストアを検索なしで自然に見られるようになるシステムを設計することによって対処される。ログは、それでも、異常終了するトランザクションをロールバックするため、およびアクセスされた位置のバージョニング情報を追跡するために、必要である。短いトランザクションの場合に、これらのログはアペンド専用である。したがって、検索は、トランザクションサイズに関わりなく不要である。
【００３０】
第２の問題は、コンパイル中の早期にＴＭ動作を導入し、後続の分析フェーズおよび最適化フェーズがそのセマンティクスを知るようにこれらのフェーズを拡張することによって対処される。最後に、第３の問題は、モノリシックＴＭ動作を別々のステップに分解し、その結果、作業の繰り返しを回避できるようにすることによって対処される。例えば、トランザクションログの管理は、実際のデータアクセスから分離され、しばしば、ログ管理をループからホイストすることを可能にする。
【００３１】
このインターフェースは、トランザクショナルメモリ動作を次の４つのセットに分解する。
【００３２】
【表２】
2009523271.tif 000003
【００３３】
最初の２つのセットは、単純であり、現在のスレッドのトランザクションマネージャを入手するＤＴＭＧｅｔＴＭＭｇｒを提供し、その後、通常のトランザクション管理動作を提供する。第３のセットは、競合検出を提供する。ＤＴＭＯｐｅｎＦｏｒＲｅａｄおよびＤＴＭＯｐｅｎＦｏｒＵｐｄａｔｅは、指定されたオブジェクトが読取専用モードでアクセスされることを、または後に更新される可能性があることを示す。静的フィールドへのアクセスは、それらのフィールドの代わりにバージョニング情報を保持するサロゲートオブジェクトによって調停され、ＤＴＭＡｄｄｒＴｏＳｕｒｒｏｇａｔｅは、アドレスをそのサロゲートにマッピングする。最後のセットは、異常終了時に更新をロールバックするのに必要なアンドゥログを維持する。ＤＴＭＬｏｇＦｉｅｌｄＳｔｏｒｅは、オブジェクトフィールドへのストアを扱い、ＤＴＭＬｏｇＡｄｄｒＳｔｏｒｅは、任意のアドレスへのストアを扱う。
【００３４】
これらの動作への呼出しは、原子性を実現するために正しくシーケンシングされなければならない。３つのルールがある、すなわち、（ａ）位置は、読み取られるときに読取用にオープンされなければならず、（ｂ）位置は、更新されるときまたはストアがそれに関してログ記録されるときに更新用にオープンされなければならず、（ｃ）位置の古い値は、更新される前にログ記録されていなければならない。実際には、これは、あるオブジェクトのあるフィールドに関するＴＭＲｅａｄへの呼出しが、ＤＴＭＧｅｔＴＭＭｇｒ、ＤＴＭＯｐｅｎＦｏｒＲｅａｄ、およびその後のフィールド読取のシーケンスに分割されることを意味する。ＴＭＷｒｉｔｅは、ＤＴＭＧｅｔＴＭＭｇｒ、ＤＴＭＯｐｅｎＦｏｒＵｐｄａｔｅ、ＤＴＭＬｏｇＡｄｄｒＳｔｏｒｅ、およびその後のフィールド書込である。静的フィールドに関するＴＭＲｅａｄの呼出しは、ＤＴＭＧｅｔＴＭＭｇｒ、ＤＴＭＡｄｄｒＴｏＳｕｒｒｏｇａｔｅ、ＤＴＭＯｐｅｎＦｏｒＲｅａｄ、およびその後の静的フィールド読取に分割される。ＴＭＷｒｉｔｅは、ＤＴＭＧｅｔＴＭＭｇｒ、ＤＴＭＡｄｄｒＴｏＳｕｒｒｏｇａｔｅ、ＤＴＭＯｐｅｎＦｏｒＵｐｄａｔｅ、ＤＴＭＬｏｇＡｄｄｒＳｔｏｒｅ、および静的フィールド書込である。
【００３５】
次の例に、分解された直接アクセスＳＴＭの使用の例を示す。例１のコードは、センチネルノードｔｈｉｓ．Ｈｅａｄとセンチネルノードｔｈｉｓ．Ｔａｉｌとの間でリンクリストの要素を通って反復する。例１のコードは、ノードのＶａｌｕｅフィールドを合計し、その結果をｔｈｉｓ．Ｓｕｍにストアする。例２は、分解された直接アクセスＳＴＭを使用してＳｕｍをどのように実施できるかを示す。
【００３６】
例１ａ
【００３７】
【表３】
2009523271.tif 000004
【００３８】
例１ｂ
【００３９】
【表４】
2009523271.tif 000005
【００４０】
例２
【００４１】
【表５】
2009523271.tif 000006
【００４２】
２．コンパイラ最適化
セクション２では、ＳＴＭ動作の知識を用いて構成されたコンパイラを利用する、分解されたＳＴＭ動作の最適化を説明する。本願で使用されるときに、用語「最適化する」、「最適化された」、「最適化」、および類似物が、全般的に特定の改善の度合に一切言及せずに改善を指す技術用語であることに留意されたい。したがって、様々なシナリオで、「最適化」が、システムまたは技法の性能の１つまたは複数の態様を改善する場合があるが、そのシステムまたは技法のすべての態様が改善されることは、必ずしも要求されない。さらに、様々な状況で、「最適化」は、必ずしも任意の特定の最小の度合または最大の度合までの任意の態様の改善を暗示しない。さらに、「最適化された」システムまたは技法が、１つまたは複数の領域での性能改善を示す場合があるが、そのシステムまたは技法が、他の領域での性能の低下を同様に示す場合がある。最後に、「最適化」が、いくつかの状況で、あるシステムまたは技法の性能を改善する場合があるが、その「最適化」が他の状況で性能を低下させることが可能である場合がある。下で説明する特定の状況では、最適化が、冗長なまたは余分なＳＴＭ命令またはログ書込の除去をもたらし、おそらくは高められた性能を提供するが、これらの最適化は、決して、すべての可能な冗長なまたは余分な命令の除去をもたらすことを暗示しない。
【００４３】
図１は、ソフトウェアトランザクショナルメモリを利用する最適化されたプログラム１２０を作成するのに使用されるコンパイラ１００の一例を示すブロック図である。図示の例では、コンパイラ１００は、入力としてソースコード１１０をとる。図示されているように、ソースコード１１０は、１つまたは複数の原子的ブロック１１５を含む。上で言及したように、一実施態様では、これらの原子的ブロックを含めることが、ＳＴＭを利用することを望むプログラマの追加のプログラミングを防ぎ、これらのブロックは、分解されたＳＴＭ命令を含むようにコンパイラによって変更され、その後、この分解されたＳＴＭ命令が最適化される。図１は、単一のソースコードを示すが、これが単に図示を単純にするためであることを理解されたい。本明細書で説明する技法およびシステムは、一緒にコンパイルされる複数のソースコードファイルならびに既にコンパイルされたコードを使用するソースコードにも適用される。さらに、様々な実施態様で、Ｃ＋＋、Ｃ＃、Ｊａｖａ（登録商標）、Ｃおよび他の言語を含む異なるコード言語が使用され、様々な実施態様で、インタープリタ型言語をも最適化することができる。図示の例では、この最適化が、ＳＴＭ最適化１５０によって実現され、ＳＴＭ最適化１５０は、コンパイラに統合され、この統合の追加の詳細は、下で述べる。コンパイルおよび最適化の後に、ソフトウェアトランザクショナルメモリを利用する最適化されたプログラム１２０が作られる。そのような最適化されたプログラムのランタイム動作の追加の詳細を、下でより詳細に説明する。さらに、図示の実施形態は、実行の前の実行可能ファイルへのコンパイルを示すが、本明細書で説明する技法の代替実施態様は、実行の直前または実行と同時にプログラムをコンパイルし、最適化することができる。
【００４４】
図２は、図１のコンパイラ１００の、例のコンポーネントを示すブロック図である。図２は、コンパイラを通る、例の動作パスを示す。図２は、特定のモジュールを別々に示すが、様々な実施態様で、これらのモジュールを、様々な組合せでマージし、または分割することができることを理解されたい。パスは、第１コンパイラモジュール２２０で始まり、第１コンパイラモジュール２２０は、ソースコード１１０を受け入れ、それから中間表現２３０を作成する。一実施態様で、このＩＲは、制御フローグラフ（「ＣＦＧ」）の形をとり、これは、本明細書で説明する最適化技法によってそのＩＲを簡単に操作できるようにする。
【００４５】
次に、ＩＲ  ２３０は、最適化モジュール２４０によって変更されて、最適化されたＩＲ  ２５０が作成される。最適化モジュール２４０の動作では、伝統的なコンパイラ最適化が、低水準および高水準のＳＴＭ固有最適化を用いて拡張される。そのような最適化の例を、下でより詳細に説明する。最後に、最適化されたＩＲ  ２５０が、第２コンパイラモジュール２６０によって、図１の最適化されたプログラム１２０などの実行可能コードにコンパイルされる。
【００４６】
図３は、ＳＴＭを使用するプログラムをコンパイルし、実行する、例のプロセス３００の流れ図である。様々な実施態様で、図示のプロセスブロックを、マージし、サブブロックに分割し、あるいは省略することができる。このプロセスは、ブロック３２０で開始され、ここで、トランザクショナルメモリブロック（図１の原子的ブロックなど）を含むソースコードを受け取る。代替実施態様では、ソースコードが、トランザクショナルメモリブロックを含まない場合があるが、ソースコードは、ワードベースの命令または上で説明した分解された命令など、個々のソフトウェアトランザクショナルメモリ命令を含む。次に、ブロック３４０で、このソースコードを実行可能プログラムにコンパイルする。コンパイルの特定の例を、下でより詳細に説明する。最後に、ブロック３６０で、実行可能プログラムを実行する。
【００４７】
図４は、トランザクショナルメモリブロックを組み込んだソースコードをコンパイルする、例のプロセス４００の流れ図である。プロセス４００は、図３のブロック３４０に対応する。様々な実施態様で、図示のプロセスブロックを、マージし、サブブロックに分割し、あるいは省略することができる。このプロセスは、ブロック４２０で開始され、ここで、ソフトウェアトランザクショナルメモリ命令を、コンパイラ１００によって各原子的ブロックに挿入する。一実施態様で、この挿入は、ブロック内の読取または書込のすべてのインスタンスの前後に正しいワードベースの読取ＳＴＭ命令および書込ＳＴＭ命令を挿入することによって実行される。もう１つの実施態様で、プログラマが、彼自身のＳＴＭ命令を挿入すると決定する場合に、ブロック４２０のプロセスを省略することができる。
【００４８】
次に、ブロック４４０で、ワードベースのＳＴＭ命令を、コンパイラ１００によって分解された命令に置換する。一実施態様で、既に分解された命令を含むソースコードがコンパイラによって受け取られた場合には、ブロック４４０のプロセスは、省略される。さらに、いくつかの実施態様で、ブロック４２０および４４０のプロセスは、特に、原子的ブロックの受取に直接に応答して、分解されたＳＴＭ命令を挿入するために組み合わせることができる。上の例２は、あるコードがブロック４４０のプロセスの動作の後にどのように見えるかを示す。
【００４９】
ブロック４４０のプロセスのもう１つの実施態様では、コンパイラは、さらに、ログ動作を分解し、複数の動作にまたがるログ管理作業のコストの割賦償却を可能にすることによって、ログ管理のコストを下げる。具体的に言うと、一実施態様で、ＤＴＭＯｐｅｎ＊動作およびＤＴＭＬｏｇ＊動作は、現在のアレイ内にスペースがあることのチェックから開始する。ＤＴＭＯｐｅｎＦｏｒＲｅａｄの場合に、これは、コードの高速パスバージョンで実行しなければならない唯一のチェックである。これらのチェックのコストを割賦償却するために、コンパイラは、所与のログ内で予約すべきスロットの個数を示す整数をとる新しい動作ＥｎｓｕｒｅＬｏｇＭｅｍｏｒｙを利用する。したがって、ＤＴＭＯｐｅｎ＊動作およびＤＴＭＬｏｇ＊動作の特殊化された分解されたバージョンは、そのスペースが存在すると仮定することができる。ランタイムブックキーピングを減らすために、一実施態様で、ＥｎｓｕｒｅＬｏｇＭｅｍｏｒｙ動作は、加法的ではなく、２つの連続する動作が、合計ではなく要求された最大値を予約する。単純にするために、一実施形態は、特殊化された動作を配置せず、この場合に、予約されたスペースは、呼出しまたはバックエッジの後で必要になる。もう１つの実施態様では、予約は、各基本ブロック内の呼出しの間のすべての動作について組み合わされる。もう１つの実施態様では、逆方向分析を使用して、できる限り早く、熱心にスペースを予約し、この予約は、すべての呼出しおよびループヘッダで強制的に停止される。これは、より多くの予約を組み合わせるという利益を有するが、予約を必要としないパスに予約動作を導入する可能性がある。
【００５０】
ブロック４６０で、コンパイラは、強い原子性のための動作の導入、不必要なＳＴＭ動作の移動および除去、ならびに新たに割り振られたオブジェクトに関するログ動作の除去を含む、高水準ＳＴＭ最適化を実行する。このプロセスは、下でより詳細に説明する。最後に、ブロック４８０で、プログラムを最適化し、この最適化にはＳＴＭ命令も含まれる。図４のプロセスは、ブロック４６０および４８０での高水準最適化およびそれに続く他の最適化を示し、最適化の反復を示さないが、いくつかの実施態様で、図４６０および４８０のプロセスまたはそのサブプロセスを、図示と異なる順序で実行することができ、繰り返すことができる。繰り返しの１つの理由は、ある種の最適化が、他の最適化の機会を明らかにする場合があることである。したがって、それらの機会が生じる可能性があるときにそれらの機会を利用するために、最適化を繰り返して実行することが望ましい可能性がある。
【００５１】
図５は、高水準最適化をＳＴＭ命令に対して実行する、例のプロセス５００の流れ図である。プロセス５００は、図４のブロック４６０に対応する。様々な実施態様で、図示のプロセスブロックを、マージし、サブブロックに分割し、あるいは省略することができる。一実施態様で、プロセス５００は、高水準最適化によって追加された命令をコンパイラによってさらに最適化できるようにするために、下で説明するプロセス６００のコンパイラ最適化の前に実行される。このプロセスは、ブロック５２０で開始され、ここで、コンパイラは、強い原子性のための動作を導入する。次に、ブロック５４０で、後続最適化中のオープン動作の、より後の除去を可能にするために、読取のためにオブジェクトをオープンする動作およびそれに続く更新のために同一オブジェクトをオープンする動作を、ｏｐｅｎ−ｆｏｒ−ｕｐｄａｔｅ動作に置換する。一実施態様で、これらのｏｐｅｎ−ｆｏｒ−ｒｅａｄ動作およびそれに続くｏｐｅｎ−ｆｏｒ−ｕｐｄａｔｅ動作を、ｒｅａｄ−ｔｏ−ｕｐｄａｔｅアップグレードと呼び、ブロック５４０のプロセスは、これらのアップグレードを除去する。次に、ブロック５６０で、図６のプロセスでのより強い最適化をもたらすために、分解されたＳＴＭ動作をプロシージャ呼出しの前後で移動する。最後に、ブロック５８０で、ログ記録される、トランザクション内で新たに割り振られたオブジェクトのログ記録動作を、不必要なログ動作呼出しを防ぐために除去する。これらのプロセスのそれぞれの特定の例を、下で図７〜１２に関してより詳細に説明する。
【００５２】
２．１．分解されたコードに対するコンパイラ最適化
図６は、ＳＴＭ命令に対して最適化を実行する、例のプロセス６００の流れ図である。プロセス６００は、図４のブロック４８０に対応する。様々な実施態様で、図示のプロセスブロックを、マージし、サブブロックに分割し、あるいは省略することができる。さらに、図示の実施態様は、各アクションが１回実行される例を与えるが、代替実施態様では、アクションを繰り返すことができる。したがって、例えば、下で説明する共通部分式除去アクションを、コード移動最適化を実行した後にもう一度実行することができる。図６には、非ＳＴＭ命令の最適化が示されていないが、これは、図を単純にするために行われたものであり、本明細書で説明するプロセスに対する限定を示すものではない。
【００５３】
このプロセスは、ブロック６２０で開始され、ここで、ＳＴＭ命令の変更に対する制約を作成する。一実施態様で、これらの制約は、少なくとも原子性に関するものであり、これは、呼出しのシーケンス内に基づく。したがって、３つのルールがある、すなわち、（ａ）位置は、読み取られるときに読取用にオープンされなければならず、（ｂ）位置は、更新されるときまたはストアがそれに関してログ記録されるときに更新用にオープンされなければならず、（ｃ）位置の古い値は、更新される前にログ記録されていなければならない。
【００５４】
これらのルールは、複数の方法を使用して実施することができる。１つの方法では、コンパイラが、コンパイル中に様々なハウスキーピング手段を介して制約を追跡する。これは、コンパイルプロセスをすぐに複雑にする可能性があるので、もう１つの実施態様では、ＣＦＧを変更して、制約に違反するのを防ぐことができる。そのような方法の１つは、後続命令の入力変数になる、命令のダミー出力変数を作ることによって、呼出し順序を強制するＳＴＭ命令の間のダミー変数を使用してデータ依存性を導入することである。したがって、次のように見えるＩＲ（ジェネリック命令を使用する）
【００５５】
【表６】
2009523271.tif 000007
【００５６】
は、
【００５７】
【表７】
2009523271.tif 000008
【００５８】
になる。
【００５９】
次に、ブロック６４０で、共通部分式除去（「ＣＳＥ」）をＳＴＭ命令に対して実行し、これに、ブロック６６０の命令に対する冗長ロードストア除去およびブロック６８０のコード移動最適化が続く。
【００６０】
一例で、これらの最適化を、ＤＴＭＧｅｔＴＭＭｇｒ動作に対して実行することができる。というのは、これが、コンスタントであり、したがってＣＳＥの機会を提供するからである。同様に、ＤＴＭＯｐｅｎＦｏｒＲｅａｄ、ＤＴＭＯｐｅｎＦｏｒＵｐｄａｔｅ、ＤＴＭＡｄｄｒＴｏＳｕｒｒｏｇａｔｅ、およびＤＴＭＬｏｇ＊動作は、トランザクション内で冪等なので、これらも、ＣＳＥまたはコード移動に適格である。この最適化に対する１つの制約は、コード移動が、一実施態様で、トランザクション境界を超えて延びることができないことである。もう１つの実施態様では、ＣＳＥが、ＤＴＭＯｐｅｎＦｏｒＵｐｄａｔｅの後に発生するＤＴＭＯｐｅｎＦｏｒＲｅａｄ命令の除去をもたらすように拡張される。この最適化を実行できるのは、更新アクセスが読取アクセスを包含するからである。
【００６１】
他の実施態様では、ＣＳＥを、ネストされたトランザクションの間の動作に対して実行することができる。したがって、一例で、ネストされたトランザクション内のＤＴＭＯｐｅｎＦｏｒＲｅａｄ動作が、外側トランザクションのＤＴＭＯｐｅｎＦｏｒＲｅａｄまたはＤＴＭＯｐｅｎＦｏｒＵｐｄａｔｅによって包含され、したがって、このＤＴＭＯｐｅｎＦｏｒＲｅａｄ動作を除去することができる。もう１つの例では、ネストされたトランザクション内のＤＴＭＯｐｅｎＦｏｒＵｐｄａｔｅが、外側のトランザクションのＤＴＭＯｐｅｎＦｏｒＵｐｄａｔｅによって包含され、除去される。
【００６２】
もう１つの実施態様で、ＤＴＭＧｅｔＴＭＭｇｒ動作を、スレッドごとのＴｈｒｅａｄオブジェクトからスレッドの現在のトランザクションマネージャをフェッチする（および、必要な場合にはトランザクションマネージャを作成する）ことによって実施することができる。したがって、Ｂａｒｔｏｋコンパイラは、ＧｅｔＣｕｒｒｅｎｔＴｈｒｅａｄ命令をも、コード移動の対象であるコンスタントな動作として扱うことができる。
【００６３】
一例として、上のプロセスの実行の後に、例２のコードは、次の、より効率的なコードに単純化される。
【００６４】
例３
【００６５】
【表８】
2009523271.tif 000009
【００６６】
２．２．高水準ＳＴＭ最適化
２．２．１  強い原子性の実施
上で説明した技法は、ある原子的ブロック内のメモリアクセスが第２の原子的ブロック内のアクセスに関して分割不能に発生する「原子的」ブロックを作成するのに使用することができる。しかし、あるスレッドによって実行される「原子的」ブロックは、第２スレッドが「原子的」ブロックを使用せずに衝突するメモリアクセスを実行するときに、分割不能に実行するように見えない場合がある。この特徴を有する設計を、「弱い原子性」を提供すると言うことができる。
【００６７】
本明細書で説明する技法の一実施態様は、原子的ブロックが、他の原子的ブロック内で行われるメモリアクセスだけではなく、すべてのメモリアクセスに関して分割不能に実行するように見える「強い原子性」をどのようにして提供するかに関する。
【００６８】
基本的な実施態様は、（ａ）すべての原子的ブロックの外部で発生する共有メモリへのすべてのアクセスを識別することと、（ｂ）それらを短い原子的ブロックとして書き直すこととによる強い原子性のサポートを用いて、上で説明したＳＴＭを拡張する。
【００６９】
例えば、あるプログラムが、フィールド「ｏ１．ｘ」の内容から読み取り、その結果をフィールド「ｏ２．ｘ」にストアすると仮定する。これは、元々は、コンパイラの中間表現（ＩＲ）内で次の２つの命令によって表される。
【００７０】
【表９】
2009523271.tif 000010
【００７１】
基本的な実施態様は、これを次のようなコードに展開する。
【００７２】
【表１０】
2009523271.tif 000011
【００７３】
（いくつかの実施態様で、記述される実際のコードは、コミット動作Ｃ１またはＣ２中に競合がある場合にＬ１またはＬ２からトランザクションを再実行するためのコードパスをも含まなければならないので、より複雑である。そのコードの正確な詳細は、ＳＭＴ動作がＩＲでどのように表現されるかに非常に依存する）。
【００７４】
この基本的な形は、強い原子性を提供するが、オリジナルのフィールドアクセスのコストを超えるトランザクション開始動作、トランザクションコミット動作、ｏｐｅｎ−ｆｏｒ−ｒｅａｄ動作、ｏｐｅｎ−ｆｏｒ−ｕｐｄａｔｅ動作、およびログ記録動作の追加コストのゆえに、性能が低い。
【００７５】
強い原子性実施態様を提供しながらも効率を高めるために、本明細書で説明する技法の一実施態様は、単一のメモリ位置だけにアクセスする短いトランザクションの性能を高めるために特殊化されたＩＲ動作を使用する。
【００７６】
考慮すべき２つのケースすなわち、単一の位置から読み取るトランザクション、および単一の位置を更新するトランザクション（単一の位置に対するｒｅａｄ−ｍｏｄｉｆｙ−ｗｒｉｔｅ動作を実行するトランザクションを含む）がある。両方のケースが、ＳＴＭワードのチェックを伴うが、これは下でより詳細に説明する。第１のケースは、拡張されたＩＲでは、（ａ）用いられるオブジェクトのＳＴＭワードを読み取ることと、（ｂ）フィールドを読み取ることと、（ｃ）ＳＴＭワードをもう一度読み取り、読み取られた値が（ａ）の値と一致し、その値が同時の衝突するアクセスがあったことを示さないことをチェックすることとによって表される。第２のケースは、拡張されたＩＲでは、（ａ）用いられるオブジェクトのＳＴＭワードを更新し、そのオブジェクトが非トランザクショナル更新の対象であることを示すことと、（ｂ）フィールドを更新することと、（ｃ）ＳＴＭワードをもう一度更新し、そのオブジェクトがもはや非トランザクショナル更新の対象ではないことを示すこととによって表される。
【００７７】
したがって、ある例のＩＲは、次のようになる。
【００７８】
【表１１】
2009523271.tif 000012
【００７９】
この実施態様は、上で説明したＳＴＭ実施態様に関する２つの相違を伴う。第１の相違は、上のＳＴＭ実施態様と異なって、一時的ストレージが、トランザクションログではなくローカル変数にあることである。これは、それらの変数をプロセッサレジスタ内で割り振って、それらの変数へのアクセスを高速にすることができることを意味する。第２の相違は、Ｌ２で始まるトランザクションが、異常終了することができず、したがって、「ｏ２．ｘ」で上書きされる値をログ記録する必要がないことである。
【００８０】
もう１つの強い原子性の実施態様では、コンパイラは、この形で展開しなければならないフィールドの個数を制限するためにさらなる最適化を実行する。一例で、コンパイラは、型ベースの分析を実行して、原子的ブロック内で書き込まれる可能性があるすべてのフィールドを識別する。他のすべてのフィールドは、原子的ブロック内でのアクセスの対象に絶対にならないことが保証されるが、直接にアクセスすることができ、したがって、強い原子性動作をその前後に挿入する必要がない。
【００８１】
図７は、強い原子性を実施する動作を導入する、例のプロセス７００の流れ図である。プロセス７００は、図５のブロック５２０に対応する。様々な実施態様で、図示のプロセスブロックを、マージし、サブブロックに分割し、あるいは省略することができる。このプロセスは、ブロック７１０で開始され、ここで、型分析を実行して、原子的ブロック内でアクセスされる可能性があるフィールドを判定する。上で説明したように、一実施態様で、これは、衝突を引き起こすことができないメモリアクセスに対する強い原子性動作の不必要な挿入を避けるために実行される。次に、ブロック７２０で、ブロック７１０で判定されたフィールドを使用して、原子的ブロックに含まれるフィールドにアクセスする可能性がある、プログラム内のメモリアクセスを突き止める。代替実施態様では、ブロック７１０のプロセスを省略することができ、ブロック７２０のプロセスが、強い原子性動作の挿入に関して原子的ブロックの外部のすべてのメモリアクセスを突き止めることができる。
【００８２】
次に、このプロセスは判断ブロック７２５に継続し、ここで、コンパイラが、ブロック７２０のアクセス位置が読取アクセスであるのか更新アクセスであるのかを判定する。アクセスが読取である場合には、このプロセスはブロック７３０に継続し、ここで、ｏｐｅｎ−ｆｏｒ−ｒｅａｄ命令をアクセスの前に挿入する。一実施態様で、この命令は、ＳＴＭワードを受け取ることができるようになるまでブロックするように構成され、したがって、メモリアクセスが、アクセスされるフィールドを正しく読み取ることができることを保証する。もう１つの実施態様では、この動作がブロックするのではなく、ループが、メモリアクセスが正確であると判明しない場合に、メモリアクセスの後に作成される。次に、ブロック７４０で、メモリアクセスの後にチェック命令を挿入して、読取アクセスの間に、ＳＴＭワードが読み取られるフィールドに対する変更を示さなかったことを保証する。上で提供した実施態様では、これは、ブロック７３０でＳＴＭワードを受け取ることと、ブロック７４０でのチェック動作にそのＳＴＭワードをわたすこととによって行われ、これは、コード最適化が強い原子性動作の順序を並べ変えるのを防ぐデータ依存性をも作成する。
【００８３】
しかし、ブロック７２５で、アクセスが更新であると判定される場合には、このプロセスは、ブロック７５０に継続し、ここで、ｏｐｅｎ−ｆｏｒ−ｕｐｄａｔｅ命令をアクセスの前に挿入する。一実施態様で、この命令は、他のアクセスを防ぐために、アクセスされるオブジェクトからのＳＴＭワードを変更するように構成され、したがって強い原子性を提供する。次に、ブロック７６０で、メモリアクセスの後にコミット命令を挿入して、メモリアクセス時に実行された更新をコミットする。一実施態様で、アクセスされたオブジェクトのバージョン番号が、変更される。別の実施態様では、それが行われない。次に、判断ブロック７６５で、コンパイラは、追加の非原子的メモリアクセスがあるかどうかを判定する。そうである場合には、このプロセスを繰り返す。そうでない場合には、このプロセスは終了する。
【００８４】
２．２．２  ｒｅａｄ−ｔｏ−ｕｐｄａｔｅアップグレードの除去
ＳＴＭコンパイラの様々な実施態様によって実行されるもう１つの高水準最適化は、ＤＴＭＯｐｅｎＦｏｒＲｅａｄ動作にＤＴＭＯｐｅｎＦｏｒＵｐｄａｔｅ動作が続くときに発生する不必要なログ記録を避けるためのものである。本明細書で説明する技法に固有の１つの設計の仮定は、読取が書込より一般的であることであり、これは、これらの技法がＤＴＭＯｐｅｎＦｏｒＵｐｄａｔｅ動作とＤＴＭＯｐｅｎＦｏｒＲｅａｄ動作とを分離する理由である、すなわち、ｏｐｅｎ−ｆｏｒ−ｒｅａｄ命令は、よりすばやく完了することができる。しかし、時々、オブジェクトが、読み取られ、その後に書き込まれる（規範的な例が「ｏｂｊ．ｆｉｅｌｄ＋＋」である）。この場合に、オープン動作を伴うＩＲは、次のようになる。
【００８５】
【表１２】
2009523271.tif 000013
【００８６】
このプログラムがｏｐｅｎ−ｆｏｒ−ｒｅａｄ点に達する場合に、当分は例外を無視すると、このプログラムがｏｐｅｎ−ｆｏｒ−ｕｐｄａｔｅ点に達することがわかる。ｏｐｅｎ−ｆｏｒ−ｕｐｄａｔｅは同一オブジェクトに対するｏｐｅｎ−ｆｏｒ−ｒｅａｄを包含するので、このｏｐｅｎ−ｆｏｒ−ｒｅａｄ動作は浪費される。これは、一実施態様で、ｒｅａｄ−ｔｏ−ｕｐｄａｔｅアップグレードとして知られる。ｏｐｅｎ−ｆｏｒ−ｕｐｄａｔｅ動作をより早期に単純に実行することが、より効率的であるはずである。
【００８７】
【表１３】
2009523271.tif 000014
【００８８】
したがって、一実施態様で、コンパイラは、ｒｅａｄ−ｔｏ−ｕｐｄａｔｅアップグレードが見つかったときに、そのｒｅａｄ−ｔｏ−ｕｐｄａｔｅアップグレードを除去する。一般に、これは、単純なデータフロー分析によって、ＤＴＭＯｐｅｎＦｏｒＵｐｄａｔｅが続く場合にＤＴＭＯｐｅｎＦｏｒＲｅａｄ動作をアップグレードすることによって、基本ブロック内でコンパイラによって処理することができる。もう１つの一般的なケースでは、ＤＴＭＯｐｅｎＦｏｒＵｐｄａｔｅ動作が、すべての非例外パスが同一のＤＴＭＯｐｅｎＦｏｒＵｐｄａｔｅを実行する（用いられる変数への介在するストアなしで）すべての基本ブロックの始めに単純に挿入される。次に、ＣＳＥは、余分なＤＴＭＯｐｅｎＦｏｒＵｐｄａｔｅ動作ならびに同一オブジェクトに対するすべての後続のＤＴＭＯｐｅｎＦｏｒＲｅａｄ動作を除去することを試みる。
【００８９】
図８は、不必要なｒｅａｄ−ｔｏ−ｕｐｄａｔｅアップグレードを除去する、例のプロセス８００の流れ図である。プロセス８００は、図５のブロック５４０に対応する。様々な実施態様で、図示のプロセスブロックをマージし、サブブロックに分割し、あるいは省略することができる。このプロセスは、ブロック８１０で開始され、ここで、コンパイラが、必ず同一参照に対するｏｐｅｎ−ｆｏｒ−ｕｐｄａｔｅ動作が続くｏｐｅｎ−ｆｏｒ−ｒｅａｄ動作を識別する。本明細書の例が、オブジェクトポインタを利用するが、不必要なｒｅａｄ−ｔｏ−ｕｐｄａｔｅアップグレードを除去する説明される技法が、インテリアポインタ（ｉｎｔｅｒｉｏｒ  ｐｏｉｎｔｅｒ）および静的フィールドの除去をも実施することに留意されたい。コンパイラは、オープンする動作が同一のオブジェクト（または静的フィールドの一実施態様の場合にサロゲートオブジェクト）に対するものであることを判定する必要がある。
【００９０】
一実施態様で、この分析は、オブジェクト参照またはインテリアポインタが同一のローカル変数であり、その変数が動作の間で更新されないことを必要とする。この実施態様は、代入に対するアップグレードの除去に失敗する可能性があるが、他の実施態様は、代入をも分析する。もう１つの実施態様で、静的フィールド（または変数）は、サロゲートオブジェクトに対するオープン動作を介して制御され、これは、単一のサロゲートオブジェクトがすべての静的フィールドを制御する場合に２つの異なる静的フィールドの間でアップグレードを除去することを可能にする。ブロック８１０のプロセスの例のプロセスを、図９に関して下でより詳細に説明する。
【００９１】
次に、ブロック８２０で、ブロック８１０で識別されたｏｐｅｎ−ｆｏｒ−ｒｅａｄ動作を、同一参照に対するｏｐｅｎ−ｆｏｒ−ｕｐｄａｔｅ動作に置換する。次に、ブロック８２０で、冗長なｏｐｅｎ−ｆｏｒ−ｕｐｄａｔｅ動作を除去する。一実施態様で、これは、ブロック８２０のプロセスの直後に実行されるのではなく、ＣＳＥなど、図６に関して説明したコンパイラ最適化によって実行される。
【００９２】
ｒｅａｄ−ｔｏ−ｕｐｇｒａｄｅ除去分析の第１の例示的な実施態様は、基本ブロック内のアップグレードを除去する。したがって、コンパイラは、プログラム全体の各基本ブロックを調べ、それぞれについてスキャンして、ｏｐｅｎ−ｆｏｒ−ｒｅａｄ動作を見つける。最初のｏｐｅｎ−ｆｏｒ−ｒｅａｄ動作が見つかったときに、コンパイラは、ｏｐｅｎ−ｆｏｒ−ｕｐｄａｔｅ動作またはオープンされたオブジェクトをポイントする変数への代入を探して前方にスキャンする。ｏｐｅｎ−ｆｏｒ−ｕｐｄａｔｅが最初に現れる場合には、コンパイラは、ｏｐｅｎ−ｆｏｒ−ｒｅａｄをｏｐｅｎ−ｆｏｒ−ｕｐｄａｔｅ動作に変換し、オリジナルのｏｐｅｎ−ｆｏｒ−ｕｐｄａｔｅを削除する。変数がアップデートされる場合には、検索をやめる。代替実施態様では、コンパイラは、ｏｐｅｎ−ｆｏｒ−ｒｅａｄ動作を検索するために、ｏｐｅｎ  ｆｏｒ  ｕｐｄａｔｅ動作から逆方向にスキャンすることができる。
【００９３】
図９は、必ずｒｅａｄ−ｔｏ−ｕｐｄａｔｅ動作によって包含されるｏｐｅｎ−ｆｏｒ−ｒｅａｄ動作を識別することを除去する第２の例のプロセス９００の流れ図である。プロセス９００は、図８のブロック８１０に対応する。様々な実施態様で、図示のプロセスブロックを、マージし、サブブロックに分割し、あるいは省略することができる。
【００９４】
図９のプロセスは、標準逆方向データフロー分析を利用する。この分析では、コンパイラは、すべてのプログラム点で、確かに将来に更新のためにオープンされるオブジェクトのセットを計算する。様々な実施態様で、図９のプロセスは、プログラムのすべての基本ブロックのそれぞれについて、または基本ブロックのサブセットについて実行される。このプロセスは、ブロック９１０で開始され、ここで、確かに更新されるオブジェクトの表示を含むセットを基本ブロック境界で作成する。ブロック９２０で、その基本ブロック内のすべての変数をそのセットに追加する。その後、ブロック９３０で、基本ブロック内の命令の分析が、ブロック内の最後の命令を点検することによって開始される。判断ブロック９３５で、コンパイラは、命令の形式を検討する。命令が代入（例えば、「ｘ＝．．．」）である場合には、ブロック９４０で、代入される変数をセットから除去する。しかし、命令がｏｐｅｎ−ｆｏｒ−ｕｐｄａｔｅ命令である場合には、ブロック９５０で、その命令によってオープンされる変数をセットに追加する。
【００９５】
どちらの場合でも、あるいは命令が別のタイプである場合には、コンパイラは、判断ブロック９５５に移り、追加の命令が基本ブロック内に存在するかどうかを判定する。そうである場合には、ブロック９６０で、コンパイラは、制御フローグラフを通って逆方向に移動し、制御フローグラフ内の次の命令を見つけ、この処理を繰り返す。判断ブロック９５５で、命令がもうないとコンパイラが判断する場合には、基本ブロックの始めに達している。コンパイラがブロックの始めに達したときには、ブロック９７０で、そのブロックの先行ブロック（すなわち、現在のブロックにジャンプすることができるブロック）を見つけ、セットを、この先行ブロックのそれぞれの終りに格納されたセットと交差させる。一実施態様で、図９のプロセスは、何も変化しなくなるまで繰り返され、各ブロックの終りで現在のセットを与える。コンパイラは、各プログラム点のセットを得るために、同一の形でセットを更新しながらブロックを通って逆方向にウォークスルーすることができる。
【００９６】
この点で、「将来に更新のためにオープンしなければならない」セットの変数が、ブロック８１０の目的のために識別されている。その後、一実施態様では、ｏｐｅｎ−ｆｏｒ−ｕｐｄａｔｅ動作が、これらの変数のそれぞれについて追加され、ＣＳＥが後に余分なｏｐｅｎ−ｆｏｒ−ｕｐｄａｔｅ動作を除去することを可能にする。もう１つの実施態様では、部分的冗長性（「ＰＲＥ」）が、ｏｐｅｎ−ｆｏｒ−ｕｐｄａｔｅ命令の積極的な追加およびそれに続くＣＳＥ最適化の代わりに使用される。これは、より一般的な解決策であり、一部のパスでより少数のオープン命令を有するコードを作ることができる。
【００９７】
一実施態様で、上で説明した分析は、例外が送出されないと仮定し、したがって例外エッジを無視し、例外が送出されないならば確かに将来に更新のためにオープンされるオブジェクトのセットを計算する。これは、例外が一般的なケースではないからである。この精度のロスは、正確さには影響しない。しかし、正確な結果を作るために、代替実施態様を、例外エッジを考慮するように拡張することができる。
【００９８】
さらに、代替実施形態では、上の分析を変更して、コードの他の部分を無視することができる。これは、無視されるコードが、分析されるコードと比較して相対的に低い頻度で実行されることを示すヒューリスティックを利用することによって行うことができる。一実施態様で、これらのヒューリスティックは、静的に決定され、別の実施態様で、これらのヒューリスティックは、プロファイル情報から決定される。
【００９９】
例として、上のプロセスの実行の後に、例３のコードは、次のより効率的なコードに単純化される。
【０１００】
例３．１
【０１０１】
【表１４】
2009523271.tif 000015
【０１０２】
２．２．３  プロシージャ呼出しの存在下での動作の移動
多数の既存のコンパイラ最適化は、その技法がプログラム全体のグラフに適用するには一般に高価に過ぎるので、関数内のコードを比較し、除去し、移動することしかできない。しかし、プロシージャ境界にまたがってＳＴＭ動作を移動する高水準ＳＴＭ最適化を介して、これらの最適化をより効率的に実行することができる。
【０１０３】
一例として、次のコードを与えられれば、
【０１０４】
【表１５】
2009523271.tif 000016
【０１０５】
Ｆｏｏが、そのパラメータによって参照されるオブジェクトを必ず更新のためにオープンすることは明白である。Ｆｏｏの呼出し側も、そのオブジェクトをオープンすることができ（上のように）、あるいは、ループ（もしくは多数の他のもの）の中でＦｏｏを呼び出している場合がある。しかし、プロシージャ呼出しは、呼出し側のコードと共にＦｏｏのアクションを分析／最適化するのを妨げる。この最適化は、呼出しバリヤにまたがってオープン動作を移動して、他の最適化のためのより多くの機会をもたらす。ＣＳＥは、明白な候補である。というのは、呼出し側が、それに移動される動作を既に行っている可能性があるからである。他の非トランザクション固有最適化も改善することができる（例えば、同一のオブジェクトが、ループ内で１つの関数に繰り返してわたされる場合に、オープンをそのループの外にホイストすることができる）。
【０１０６】
一例で、この最適化は、ＤＴＭＧｅｔＴＭＭｇｒ動作およびＤＴＭＯｐｅｎＦｏｒ＊動作について実施される。代替実施態様では、この最適化を、あるメソッドが呼び出される場合に発生しなければならない他の動作について実行することができる。さらに、代替実施態様で、健全性を失わずに一般的なケースでのよりよい性能のために一般的でないケースでの精度および性能を犠牲にして、この最適化を、あるメソッドが呼び出される場合に通常は発生する動作に対して実行することができる。一実施態様で、コンパイラは、非仮想（「直接」とも呼ばれる）呼出しに対してこの最適化を実行し、これは、「非仮想化された」（例えば、単一の呼出しターゲットだけが存在すると判定され、仮想呼出しを直接呼出しに置換された）仮想呼出しを含む。
【０１０７】
図１０は、メソッド境界にまたがってＳＭＴ動作を移動することによってＳＭＴ動作を最適化する、例のプロセス１０００の流れ図である。プロセス１０００は、図５のブロック５６０に対応する。様々な実施態様で、図示のプロセスブロックを、マージし、サブブロックに分割し、あるいは省略することができる。このプロセスは、ブロック１０１０で開始され、ここで、メソッドの外に移動できる動作を含むメソッドを突き止める。次に、ブロック１０２０で、メソッドのクローンを作成して、そのメソッドの、動作をメソッドの外部で実行できるようにするバージョンを作成する。動作が結果を与える場合には、ブロック１０２０のプロセスは、クローン化されたメソッドに引数を追加して、結果をそのメソッドにわたせるようにもする。
【０１０８】
次に、ブロック１０３０で、動作を、クローン化されたメソッドからそのメソッドの１つまたは複数の呼出しサイトに移動する。代替実施態様では、正確にメソッドのクローンを作成し、動作を移動するのではなく、クローン化されたメソッドは、移動される動作なしで作成される。その後、最後に、ブロック１０４０で、オリジナルメソッドへの呼出しをクローン化されたメソッドに置換する。置換された呼出しの一実施態様で、クローン化されたメソッドによって使用される追加の引数が、含まれる。これらの追加の引数の例を、下で示す。
【０１０９】
呼出しの置換のもう１つの実施態様で、コンパイラは、それがクローンを作成したメソッドのセットおよびこれらのメソッドからのクローン化された（特殊化された）バージョンへのマッピングを維持する。次に、コンパイラは、プログラム内のすべてのメソッドをもう一度スキャンして、呼出しを置換する。いくつかの場合に、この技法は、関数のオリジナルバージョンを完全に除去する。しかし、いくつかの場合に（例えば、関数のアドレスがとられている場合に）、特殊化されないバージョンへの呼出しがまだあり、これを除去することはできない。
【０１１０】
異なる動作は、異なる形でメソッドのクローンを作成させる。一例で、あるメソッドがＧｅｔＴｘＭｇｒを含む場合に、コンパイラは、そのメソッドのクローンを作成し、トランザクションマネージャを受け取る余分のパラメータを追加し、ＧｅｔＴｘＭｇｒのすべての出現をそのパラメータに置換する。
【０１１１】
【表１６】
2009523271.tif 000017
【０１１２】
この例では、このメソッドへの呼出しは、トランザクションマネージャを含む追加の引数を伴う、クローン化されたメソッドへの呼出しに変更される。
【０１１３】
【表１７】
2009523271.tif 000018
【０１１４】
もう１つの例では、単一の特性に、（トランザクションマネージャ）に基づく特殊化されたクローンを追跡させ、作成させるのではなく、多数の特性がある（各パラメータおよび各静的サロゲート）。例えば、
【０１１５】
【表１８】
2009523271.tif 000019
【０１１６】
この例では、コンパイラは、呼出し側がｏｂｊ１およびｏｂｊ３を適当にオープンする（しかし、必ずしもｏｂｊ２はオープンしない）ことを期待する特殊化されたバージョンを作成することを望む。一実施態様で、これは、上でブロック１０１０のプロセスの一部として説明した「将来のある時点で更新のためにオープンされなければならない」分析を実行することによって行われる。ここで、この分析は、パラメータおよび静的サロゲートだけを追跡するが、「ｏｐｅｎ−ｆｏｒ−ｒｅａｄ」動作ならびに「ｏｐｅｎ−ｆｏｒ−ｕｐｄａｔｅ」動作を行うように拡張もされる。次に、コンパイラは、関数のルートでセットを分析する。それらのセットが空ではない場合には、コンパイラは、その代わりに適当なオープン動作を前後に移動することを除いて、上と同様にメソッドのクローンを作成する。コンパイラは、他の最適化が見るために、クローン化された関数に、どのパラメータがオープンされると期待されるか（および読取または更新のどちらに関するか）をストアする。
【０１１７】
２．２．４  新たに割り振られたオブジェクトに関するログ動作の減少
最後の高水準最適化は、あるトランザクション内で新たに割り振られたオブジェクトに関する、そのトランザクション内のログ動作を除去することによって、ログ動作の個数を減らすように働く。具体的に言うと、それが作成されたトランザクションから絶対に漏れ出ないオブジェクトに関するアンドゥログ情報を維持する必要はない。これは、そのようなオブジェクトのアンドゥログ内の情報が、そのトランザクションが異常終了した場合に限って使用され、その点で、そのオブジェクトがいずれにせよ削除されるからである。
【０１１８】
本質的に、この最適化は、トランザクションの開始以降に割り振られたオブジェクトに必ず束縛される変数を識別し、次に、これらのオブジェクトに関するログ動作を削除するように働く。したがって、図１１に、新たに割り振られたオブジェクトに関するログ動作を除去する、例のプロセス１１００の流れ図を示す。プロセス１１００は、図５のブロック５８０に対応する。様々な実施態様で、図示のプロセスブロックを、マージし、サブブロックに分割し、あるいは省略することができる。
【０１１９】
このプロセスは、ブロック１１１０で開始され、ここで、コンパイラは、そのトランザクション内で新たに割り振られるオブジェクトに必ず束縛される変数を識別する。様々な実施態様で、ブロック１１１０のプロセスは、コンパイルされるプログラム内のプログラム点の異なるセットで変数に関する情報を受け取るために実行される。したがって、ブロック１１１０の分析は、特定の点、コードの短いスパン、またはトランザクション内の変数の寿命全体を通じて、参照に関する情報を習得するために実行することができる。
【０１２０】
この分析の後に、ブロック１１２０で、コンパイラは、これらの変数を介して動作するアンドゥログ動作を除去し、このプロセスは終了する。一実施態様で、コンパイラは、ヒープメモリにアクセスするＳＴＭ動作を、その分解がログ動作を含まない動作の特別に拡張されたバージョンに置換することによって、ブロック１１２０のプロセスを実行する。もう１つの実施態様で、コンパイラは、ＳＴＭ動作の分解の後に図１１のプロセスを実行して、分解されたログ動作を明示的に除去する。
【０１２１】
ブロック１１１０のプロセスは、分析されつつあるコードに依存して、単純なものから複雑なものまでの範囲にわたる。一例で、
【０１２２】
【表１９】
2009523271.tif 000020
【０１２３】
などのコードは、ｐが、原子的トランザクションブロック内の新たに割り振られるオブジェクトを参照することが必ずわかることを意味する。したがって、ｐを介して働くログ動作を除去することは、安全である。
【０１２４】
しかし、
【０１２５】
【表２０】
2009523271.tif 000021
【０１２６】
などのコードは、ｐが必ず新たに割り振られたオブジェクトを参照するかどうかに関する情報を簡単には提供しない。したがって、コンパイラは、変数がログ除去に適格であるか否かを識別するために、分析を実行しなければならない。
【０１２７】
一実施態様で、コンパイラは、各変数が新たに割り振られたオブジェクトを確かに参照することがわかるかどうかを示す、すべてのプログラム点でのベクトルを利用するビットベクトルを使用する。この実施態様は、ログ動作を除去できる参照を正しく識別するが、一般に、低速であり、大量のメモリ使用を伴う。もう１つの実施態様では、ビットベクトルが、基本ブロックなど、コードの大きいセクションに関する要約情報を提供することができる。この実施態様は、それでも、プロシージャ間分析に関して低速になる可能性がある。
【０１２８】
代替案として、一実施形態で、コンパイラは、フローセンシティブプロシージャ間分析を使用して、トランザクションの始め以降に割り振られたオブジェクトに必ず束縛される変数を識別する。図１２に、そのような例のプロセス１２００の流れ図を示す。プロセス１２００は、図１１のブロック１１１０に対応する。様々な実施態様で、図示のプロセスブロックを、マージし、サブブロックに分割し、あるいは省略することができる。図示の実施態様では、プロセス１２００は、トランザクション内の各基本ブロックに対して実行される。
【０１２９】
図１２に示されたプロセスは、依存性グラフを同時に作成し、解決するために、プログラム全体の各関数に対して実行される。関数ごとに、このプロセスは、ブロック１２１０で開始され、ここで、オブジェクト型の変数から依存性グラフ内の格子要素またはノードへのマッピングを作成する。このマップは、ブロック内の任意の点で変数に代入することができる値の種類を表すことができる。一実施態様で、格子は、その中に３つの要素すなわち、新たに割り振ることができないオブジェクトを参照する変数を表す「Ｏｌｄ」、新たに割り振らなければならないオブジェクトを参照する変数を表す「Ｎｅｗ」、および情報がない変数の「Ｕｎｋｎｏｗｎ」を有する。ブロック１２２０で、マッピング内のすべての変数に「Ｕｎｋｎｏｗｎ」をセットする。次に、ブロック１２３０で、コンパイラは、基本ブロックを通って順方向に進んで、ブロック内の最初の動作を点検する。判断ブロック１２３５で、コンパイラは、それが点検している動作のタイプが何であるかを判定する。動作がオブジェクト割振りである場合には、ブロック１２４０で、コンパイラは、割り振られる変数のマッピングに「Ｎｅｗ」を追加する。動作が代入、キャスト、またはプロシージャ呼出しである場合には、ブロック１２５０で、コンパイラは、変数の間で格子値を伝搬させる。したがって、代入およびキャストは、その抽象値を、代入される変数に伝搬させる。呼出しは、抽象値を呼出しフォーマルにおよび戻り値から伝搬させる。しかし、動作が、上のケース以外の何かである場合には、ブロック１２６０で、動作が割り当てられる変数について「Ｏｌｄ」を表すように格子を変更する。一実施態様で、この分析は、現在のトランザクションのコミットされたサブトランザクション内で割り振られるオブジェクトをも、新たに割り振られるものと考える。
【０１３０】
次に、コンパイラは、マッピングに関する情報をローカル変数から格子値またはグラフノートに順方向に伝搬させ、固定点に達するまで関数内で反復する。したがって、判断ブロック１２６５で、コンパイラは、ｉｆステートメントの終りなどの合流点に達したかどうかを判定する。合流点に達した場合には、ブロック１２７０で、先行ブロックからの格子値を、現在のブロックの既存マップに点単位で交差させる。分析のために、関数の始めは、その呼出しサイトのすべてからの合流点と考えられる。どの場合でも、このプロセスは、判断ブロック１２７５に進み、ここで、点検すべき動作がまだあるかどうかを判定する。そうである場合には、このプロセスは、判断ブロック１２３５で繰り返す。そうでない場合には、このプロセスは終了する。このプロセスは、他の関数から変数へのグラフを介する伝搬を引き起こすことができる。このプロセスが、トランザクション内のすべての基本ブロックに対して実行されたならば、「Ｎｅｗ」のラベルを付けられた変数は、そのログ動作を除去させることができる。依存性追跡は、様々な実施態様で、関数を異なる順序で処理できることを意味する。依存性追跡は、ある関数の新しい呼出し側または呼ばれる側が判定される場合に、その関数をもう一度分析する必要がないことをも意味する。
【０１３１】
３．ランタイム最適化の例
このセクションでは、分解された直接アクセスＳＴＭの実施態様を説明する。概要では、トランザクションは、更新に厳密な２フェーズロックを使用し、衝突する更新を検出できるように、そのトランザクションが読み取るオブジェクトのバージョン番号を記録する。ロールバックログは、衝突またはデッドロックの際の回復に使用される。ある最適化は、コミット動作によって使用されるバージョン番号をサポートするためにオブジェクトフォーマットを拡張することならびにこの拡張に基づいてオブジェクトに対する変更を判定する高速技法を伴う。トランザクショナルメモリのログへのエントリのランタイムフィルタリングも、説明する。
【０１３２】
３．１  原子的コミット動作
オブジェクト構造の拡張は、本明細書で説明するＳＴＭ実施態様内の原子的コミット動作の文脈で理解することができる。原子的コミットの一例で、ＤＴＭＳｔａｒｔが呼び出され、オブジェクトは、読取および更新のためにオープンされ、コミットは、これらのアクセスを原子的に実行することを試みるためにＤＴＭＣｏｍｍｉｔを呼び出すことによって終了する。
【０１３３】
内部的に、コミット動作は、読取のためにオープンされているオブジェクトの妥当性検査を試みることによって開始される。これは、それらのオブジェクトがオープンされたとき以降に他のトランザクションによってそれらのオブジェクトに対する更新が行われていないことを保証する。妥当性検査が失敗する場合には、衝突が検出されており、トランザクションの更新は、ロールバックされ、そのトランザクションが更新のためにオープンしたオブジェクトは、クローズされ、その結果、そのオブジェクトを、他のトランザクションによってオープンすることができる。妥当性検査が成功する場合には、トランザクションは、衝突なしで実行されており、そのトランザクションが更新のためにオープンしたオブジェクトは、クローズされ、更新が保持される。
【０１３４】
妥当性検査プロセスは、ＤＴＭＯｐｅｎＦｏｒＲｅａｄコマンドの呼出しから妥当性検査までのタイムスパン中にトランザクションが読み取ったオブジェクトに対する衝突する更新がなかったことをチェックする。更新のためにオブジェクトをオープンされたままにすることは、ＤＴＭＯｐｅｎＦｏｒＵｐｄａｔｅコマンドの呼出しからＳＴＭログ内のオブジェクトのクローズまでのタイムスパン中の衝突を防ぐ。その結果、このタイムスパンの交差中にオープンされているオブジェクトのいずれに対しても衝突するアクセスはなく、トランザクションは、妥当性検査が開始される直前に原子的であると考えることができる。
【０１３５】
３．２  ランタイム環境
図１３は、ランタイム環境１３００内でランタイム中にＳＴＭ性能を最適化するように動作する、オブジェクトおよびソフトウェアモジュールの例を示すブロック図である。図１３は、特定のモジュールを別々に示すが、様々な実施態様で、モジュールを、様々な組合せでマージするか分割することができ、モジュールが、図示されていない他のランタイムソフトウェア構造の一部として動作することができることを理解されたい。図１３は、膨張させられたワードヘッダ１３１５と共に、ランタイム環境内で動作するオブジェクト１３１０を示す。その膨張させられたワードヘッダを伴うオブジェクトの動作を、次のセクションで説明する。図１３には、上で説明したＳＴＭ実施態様の妥当性検査プロシージャおよびクローズプロシージャを実施する、読取妥当性検査モジュール１３２０およびオブジェクト更新クローズモジュール１３３０も示されている。ランタイム環境内のオブジェクトに関するこれらのモジュールの特定の諸面を、本明細書で説明する。図１３には、さらに、フィルタリングアソシアティブテーブル１３５０が示され、フィルタリングアソシアティブテーブル１３５０は、いくつかの実施態様で、不必要なエントリをフィルタリングし、これらがアンドゥログ１３６０、更新済みオブジェクトログ１３７０、および読取オブジェクトログ１３８０の様々な組合せにログ記録されるのを防ぐ。このフィルタリングプロセスの特定の実施態様は、下でより詳細に説明する。最後に、図１３は、ガーベジコレクションモジュール１３９０を示し、ガーベジコレクションモジュール１３９０は、オブジェクトがもはや実行中プログラム内で到達可能ではなくなったときにそれらのオブジェクトを割振り解除し、ガーベジコレクション中にＳＴＭログを圧縮するように働く。このガーベジコレクションモジュールの特定の実施態様を、下で説明する。
【０１３６】
３．３  オブジェクト構造
このセクションでは、読取専用オブジェクトの妥当性検査ならびに更新されるオブジェクトに対するオープン動作およびクローズ動作をサポートするのに使用される構造体の例を説明する。一実施態様で、ＳＴＭは、オブジェクトに対する動作のために各オブジェクトに対する２つの抽象エンティティすなわち、どのトランザクションがオブジェクトを更新のためにオープンさせたかを調整するのに使用されるＳＴＭワードと、トランザクションが読み取ったオブジェクトに対する衝突する更新を検出するのに高速パスコード内で使用されるＳＴＭスナップショットとを利用する。これらのデータ構造体を使用する動作の例は、次の通りである。
【０１３７】
【表２１】
2009523271.tif 000022
【０１３８】
オブジェクトのＳＴＭワードは、２つのフィールドを有する。一方は、そのオブジェクトがいずれかのトランザクションによって現在更新のためにオープンされているか否かを示す単一のビットである。セットされている場合に、このワードの残りは、所有するトランザクションを識別する。そうでない場合には、このワードの残りは、バージョン番号を保持する。ＯｐｅｎＳＴＭＷｏｒｄは、ＳＴＭワードに対する原子的ｃｏｍｐａｒｅ−ａｎｄ−ｓｗａｐ（前の値から次の値へ）を実行する。ＣｌｏｓｅＳＴＭＷｏｒｄは、このワードを指定された値に更新する。
【０１３９】
図１４ａおよび１４ｂに、オブジェクト内でＳＴＭワードを実施する例を示す。図示の実施態様は、Ｂａｒｔｏｋランタイムが、メモリ内でオブジェクトを表すときに単一のマルチユースヘッダワードを各オブジェクトに関連付けるという事実を利用し、これを使用して、同期ロックおよびハッシュコード（どちらもが本明細書で説明するＳＴＭ技法の構成要素ではない）をオブジェクトに関連付ける。図１４ａおよび１４ｂでは、このマルチユースヘッダワードが、トランザクション内で更新のためにオープンされているオブジェクトのＳＴＭワードを保持するために、追加の状態を伴って拡張されている。したがって、図１４ａでは、オブジェクト１４００は、マルチユースヘッダワード１４１０を含み、マルチユースヘッダワード１４１０は、それにストアされた値のタイプのインジケータ１４１３およびそれに続く実際のＳＴＭワード１４１８を含む。インジケータ１４１３の使用は、異なるインジケータ値を使用することによって、マルチユースワードをハッシュコードおよびロックに使用することを可能にする。一実施態様では、あるオブジェクトのインジケータ１４１３が、ロックまたはハッシュコードがこのワードにストアされていることを示す場合に、まだ今のところそのオブジェクトのＳＴＭワードがないと仮定する。やはり図１４ａに示されているように、ＳＴＭワード１４１８は、上で説明した２タイプの値を有することができる。例１４２０では、ＳＴＭワードは、オブジェクト１４００が更新のためにオープンされてはいないことを示すビットを含み、したがって、このワードの残りは、バージョン番号を保持する。例１４３０では、ＳＴＭワードは、オブジェクトが更新のためにオープンされていることを示すビットを含み、したがって、ＳＴＭワードは、更新のためにこのオブジェクトをオープンしたトランザクションを識別した。
【０１４０】
もう１つの実施態様では、マルチユースワードがこれらの目的のうちの複数（例えば、ハッシュコードおよびＳＴＭワード）のために必要な場合に、マルチユースワードは、膨張させられ、外部構造体が、オブジェクトのロックワード、ハッシュコード、およびＳＴＭワードを保持する。したがって、図１４ｂでは、オブジェクト１４５０が、膨張させられたヘッダワードを使用して図示されている。このオブジェクトのマルチユースワードのインジケータ１４６５は、ヘッダワードが膨張させられていることを示す値を含み、マルチユースワードの残りの値１４６０は、膨張させられたヘッダワード構造体のメモリアドレスを含む。したがって、図１４ｂでは、マルチユースワードは、膨張させられたヘッダワード構造体１４７０をポイントし、膨張させられたヘッダワード構造体１４７０は、ロックワード、ハッシュコード、およびＳＴＭワードを含む。
【０１４１】
ＳＴＭワードと異なって、オブジェクトのＳＴＭスナップショットは、オブジェクトのトランザクショナル状態に関するヒントを提供する。一実施態様で、ランタイム環境は、ＣｌｏｓｅＳＴＭＷｏｒｄがオブジェクトに対して呼び出されるときに、すなわち、スレッドがオブジェクトへの更新アクセスを解放するときに、必ずスナップショットが変化することを保証する。これは、衝突を検出するのに十分な情報を与える。
【０１４２】
この条件を保証する１つの方法は、オブジェクトのマルチユースワードの値としてＳＴＭスナップショットを実施することである。明らかに、この実施態様は、ＳＴＭワードがマルチユースワードに直接にストアされるときに、スナップショットが変化することを意味する。しかし、スナップショットは、膨張させられたヘッダワードが使用されるときには、必ずしも変化しない。一実施態様では、膨張させられたヘッダワードを使用するオブジェクトのスナップショットが、各オブジェクトの膨張させられたヘッダワードを見つけ出し、探査することができる。しかし、これは、高速スナップショット命令を作るという目標と一致しない非効率的な実践である。したがって、もう１つの実施態様では、マルチユースワードが膨張させられる場合に、ＣｌｏｓｅＳＴＭＷｏｒｄが、新しい膨張させられた構造体を作成し、以前の構造体の内容をそれにコピーする。これは、高速のままでありながら、ＳＴＭスナップショットを常にオブジェクトのマルチユースワードの値として実施することを可能にする。
【０１４３】
図１５ａおよび１５ｂに、ＣｌｏｓｅＳＴＭＷｏｒｄのそのような実施態様の効果を示す。図１５ａには、ＣｌｏｓｅＳＴＭＷｏｒｄの実行の前のオブジェクト１５００が示されている。オブジェクト１５００は、膨張させられたヘッダワード１５２０を使用し、膨張させられたヘッダワード１５２０のアドレスをそのマルチユースヘッダワード１５１０にストアする。図１５ｂは、ＣｌｏｓｅＳＴＭＷｏｒｄの実行の後のオブジェクトおよびランタイムメモリに対する変化を示す。実行の後に、新しい膨張させられたヘッダワードデータ構造体１５４０が作成されており、マルチユースヘッダワード１５１０にストアされたアドレスが変化している。これは、マルチユースワード１５１０の値を含むスナップショットが、クローズの結果として変化したことを意味する。
【０１４４】
図１６は、オブジェクトスナップショットを使用して妥当性検査を実行する、例のプロセス１６００の流れ図である。様々な実施態様で、図示のプロセスブロックを、マージし、サブブロックに分割し、あるいは省略することができる。このプロセスは、ブロック１６２０で開始され、ここで、オブジェクトのスナップショットデータを記録する。一実施態様で、この記録は、オブジェクトが読取のためにオープンされるときに実行される。次に、ブロック１６４０で、読取妥当性検査モジュール１３２０が、コミット動作中の妥当性検査時にオブジェクトの第２のスナップショットを記録する。判断ブロック１６６０で、このモジュールが、２つのスナップショットを比較して、それらが同一であるかどうかを調べる。それらが一致する場合には、このプロセスはブロック１６７０に継続し、ここで、トランザクションは、スナップショットが変化していないという事実を利用して高速パステストを実行するコミット／異常終了プロシージャに継続することを許可される。スナップショットが一致しない場合には、ブロック１６８０で、読取妥当性検査モジュール１３２０が、トランザクションがコミットできるのか異常終了するのかを判定するのに一致するスナップショットの存在を利用できないコミット／異常終了プロシージャを実行し、このプロセスは終了する。一実施態様で、プロシージャのこの２つの異なるセットは、高速パスプロシージャおよび低速パスプロシージャとして知られる。
【０１４５】
ブロック１６７０のプロセスとブロック１６８０のプロセスとの間の主要な相違は、ブロック１６７０のプロセスが、スナップショットが変化していないことの知識のゆえに不必要なテストまたはメモリアクセスを回避でき、したがって、ブロック１６８０のテストよりすばやく実行できることである。様々な実施態様で、これらのテストの正確な性質は、基礎になるトランザクショナルメモリ実施態様の性質に依存する可能性がある。例えば、下でコードの例６で説明する一実施態様では、妥当性検査を実行するコードは、２つのスナップショットが一致する場合に、単一のＳＴＭワードをチェックして、それがトランザクションによって所有されるかどうか、およびそのトランザクションが現在妥当性検査を行っているトランザクションと同一であるかどうかを判定するだけでよい。対照的に、この例でスナップショットが一致しない場合には、第２のＳＴＭワードならびにある種の状況で更新エントリをルックアップしなければならない。これらの追加のメモリアクセスならびにそれらに対して実行される追加の比較は、ブロック１６８０のこの実施態様が、一般にブロック１６７０の対応する実施態様より低速であることを意味する。
【０１４６】
図１７は、膨張させられたヘッダワードを使用してオブジェクトを変更する、例のプロセス１７００の流れ図である。様々な実施態様で、図示のプロセスブロックを、マージし、サブブロックに分割し、あるいは省略することができる。このプロセスは、ブロック１７２０で開始され、ここで、オブジェクトを変更する。一実施態様で、これは、ＳＴＭ更新命令のゆえとすることができる。もう１つの実施態様で、オブジェクトの膨張させられたヘッダワード自体を、ロックワードまたはハッシュコードのいずれかにおいて変更することができる。次に、ブロック１７４０で、オブジェクト更新クローズモジュール１３３０が、クローズ命令に応答して、新しい膨張させられたヘッダワードを作成する。このプロセスは、ブロック１７６０に継続し、ここで、そのモジュールが、情報を古いヘッダワードから新しいヘッダワードにコピーする。次に、ブロック１７８０で、オブジェクト更新クローズモジュール６３０が、新しい膨張させられたヘッダワードをポイントするようにオブジェクトのマルチユースヘッダワードを変更する。
【０１４７】
最後に、ブロック１７９０で、ガーベジコレクションが行われようとしている場合に、古い膨張させられたヘッダワードは、ガーベジコレクタ１３９０による再利用まで、その位置に残される。オブジェクト更新クローズモジュールは、第２の変化が異なるスレッド内でオブジェクトに対して行われ、第３の膨張させられたヘッダワードが第１の膨張させられたヘッダワードから再利用されるメモリに書き込まれるシナリオを防ぐために、これを行う。オブジェクトを読み取るトランザクションがオープンされている間にこれが発生する場合には、オブジェクトのスナップショットは、２回変更されているにもかかわらず、コミット時に変化していないように見える可能性がある。これは、読取を行うトランザクションが、オブジェクトの２回の変更に起因して異常終了しなければならないときにコミットすることを可能にする可能性がある。一実施態様で、ブロック１７９０のプロセスは、オブジェクトを再利用することが安全なときまでオブジェクトをその位置に残すことによって実行され、一例で、オブジェクトのこの再利用は、オブジェクトを読取のためにオープンしているトランザクションがないときに行われる。
【０１４８】
４．ＳＴＭログ記録およびコミットの例
４．１．ＳＴＭログ構造の例
各スレッドは、３つのログと共に別々のトランザクションマネージャを有する。読取オブジェクトログおよび更新済みオブジェクトログは、トランザクションが読取または更新のためにオープンしたオブジェクトを追跡する。アンドゥログは、異常終了時にアンドゥされなければならない更新を追跡する。すべてのログが、シーケンシャルに書き込まれ、絶対に検索されない。別々のログが使用されるのは、それらの中のエントリが、異なるフォーマットを有するからであり、また、コミット中に、システムが異なる種類のエントリにまたがって反復する必要があるからである。各ログは、エントリのアレイのリストに編成され、したがって、コピーなしで大きくなることができる。
【０１４９】
図１８ａ、１８ｂ、および１９ａ〜ｃに、例２ａからのリストの例を使用するログの構造を示す。図１８ａに、値１０を有する単一のノードを保持するリストの初期状態を示す。オブジェクトのマルチユースワードが、両方ともＳＴＭワードを保持するのに使用されると仮定する。このケースでは、オブジェクトは、バージョン９０および１００である。図１８ａ、１８ｂ、および１９ａ〜ｃの図示の例では、ＳＴＭワードの右側の２桁の値は、図１４ａ、１４ｂ、１５ａ、および１５ｂのインジケータに対応する。
【０１５０】
例３からの１つの動作が、バージョン番号を更新済みオブジェクトログ内の新しいエントリへのポインタに原子的に置換するのにＯｐｅｎＳＴＭＷｏｒｄを使用して、ｔｈｉｓを更新のためにオープンする。擬似コードの１つの例は、例４のようになる。
【０１５１】
例４
【０１５２】
【表２２】
2009523271.tif 000023
【０１５３】
図１８ｂにこの結果を示す。図示の実施態様で、「ログチャンク内のオフセット」フィールドが、ガーベジコレクション中にログ（図１８ｂのＬｉｓｔノードからのログなど）へのインテリアポインタを、それを保持するログエントリのアレイへの参照にマッピングする高速の形として使用されることに留意されたい。
【０１５４】
リスト合計の例は、読取のために各リストノードをオープンするために進行する。ＤＴＭは、これを単純にし、オブジェクトごとに、オブジェクト参照およびその現在のＳＴＭスナップショットがログ記録される。例５に、これの例を擬似コードで示す。
【０１５５】
例５
【０１５６】
【表２３】
2009523271.tif 000024
【０１５７】
図１９ａに、これが作成するログエントリを示す。競合がまれであり、したがって、競合を早期に発見することの利益より、チェックのコストが優るという設計の仮定に従って、衝突を検出する試みは行われない。
【０１５８】
リストノードを読み取った後に、最終ステップは、Ｓｕｍフィールドの更新である。ＤＴＭＬｏｇＦｉｅｌｄＳｔｏｒｅは、図１９ｂに示されたアンドゥログ内のエントリに、上書きされた値を記録する。これの擬似コードは省略する。使用される特定のレコードは、一実施形態で使用されるＢａｒｔｏｋシステム内のガーベジコレクションサポートによって影響され、他の設計が、他のシステムで適当であるからである。アンドゥログエントリは、上書きされた値のアドレスを（オブジェクト，オフセット）対として記録する。これは、いくつかのガーベジコレクタで処理するのが高価なインテリアポインタの使用を回避する。エントリは、スカラまたは参照型ストアの間で区別もする。この型情報は、一部のガーベジコレクタで必要である。最後に、上書きされた値が記録される。もう１つの実施態様では、ガーベジコレクション中のより多くの作業を犠牲にして、アドレスおよび上書きされるワードだけを保持する、より短い２ワードログエントリを使用することができる。
【０１５９】
４．２  コミットプロシージャの例
本明細書で説明する実施態様のＤＴＭＣｏｍｍｉｔには２つのフェーズがあり、第１のフェーズは、読取のためにオープンされるオブジェクトに対する衝突する更新をチェックし、第２のフェーズは、更新のためにオープンされたオブジェクトをクローズする。明示的に読取のためにオープンされたオブジェクトをクローズする必要はない。というのは、その事実が、スレッドプライベートトランザクションログだけに記録されるからである。
【０１６０】
例６は、次のように、ＶａｌｉｄａｔｅＲｅａｄＯｂｊｅｃｔの構造を示す。この擬似コードには多数のケースがあるが、全体的な設計は、ＤＴＭインターフェースでの動作に関するケースの分離として考えるならば、より明瞭になる。下のケースＶ１、Ｖ２、およびＶ３は、衝突が発生していないことを示す。
【０１６１】
・  Ｖ１  オブジェクトは、トランザクションの持続時間内のどの点でも更新のためにオープンされなかった。
・  Ｖ２  オブジェクトは、持続時間全体について現在のトランザクションによって更新のためにオープンされた。
・  Ｖ３  オブジェクトは、最初は更新のためにオープンされず、現在のトランザクションは、更新のためにそのオブジェクトをオープンする次のトランザクションであった。
・  Ｖ４  オブジェクトは、持続時間全体について別のトランザクションによって更新のためにオープンされた。
・  Ｖ５  オブジェクトは、最初は更新のためにオープンされず、別のトランザクションが、更新のためにそのオブジェクトをオープンした次のトランザクションであった。
【０１６２】
これらのケースは、例の擬似コードでマークされている。いくつかのケースは、複数回発生する。というのは、ＳＴＭスナップショットに対して行われるテストが実際の衝突のゆえに不合格になる場合と、衝突なしで不合格になる（例えば、オブジェクトのマルチユースワードが膨張させられるのでＳＴＭスナップショットが変化したので）場合との間で区別することが有用であるからである。
【０１６３】
例６
【０１６４】
【表２４−１】
2009523271.tif 000025
【０１６５】
【表２４−２】
2009523271.tif 000026
【０１６６】
例７に、更新のためにオープンされたオブジェクトをクローズするのに使用されるＣｌｏｓｅＵｐｄａｔｅｄＯｂｊｅｃｔ動作を示す。
【０１６７】
例７
【０１６８】
【表２５】
2009523271.tif 000027
【０１６９】
図１９ｃに、新しいバージョン番号９１がリストオブジェクトのヘッダに置かれている、リスト構造に対する結果の更新を示す。
【０１７０】
バージョン番号に２９ビットが使用可能な状態で、約５００Ｍ個の別個のバージョンを入手できることを観察することができる。示された設計は、実行中のトランザクションがオブジェクトを読取のためにオープンさせている間に、あるバージョン番号が同一オブジェクトに再利用されない限り（読み取るトランザクションが、その数に対する５００Ｍ回程度の更新があった可能性があることを検出せずに成功してコミットすることを可能にするＡ−Ｂ−Ａ問題）、バージョン番号がオーバーフローすることを安全にする。
【０１７１】
正確さのために、一実施態様で、これは、（ａ）少なくとも５００Ｍトランザクションおきに１回ガーベジコレクションを実行することと、（ｂ）すべてのガーベジコレクションで動作中のトランザクションを妥当性検査することとによって防がれる。読取オブジェクトログ内のレコードは、ログ記録されたバージョン番号が現在のバージョン番号と一致する場合に限って有効であり、その結果は、各ガーベジコレクションが、バージョン番号を更新するために各オブジェクトを訪れることを必要とせずに、５００Ｍトランザクションの「クロックをリセットする」ことである。
【０１７２】
５．ランタイムログフィルタリング
このセクションでは、読取オブジェクトログおよびアンドゥログから重複をフィルタリングするのに確率的ハッシング方式を利用する、重複をフィルタリングするランタイム技法を説明する。ログフィルタリングは、一般に、ａ）ログがかなりのスペースを占め、システムリソースを奪い去る可能性があり、ｂ）特定のメモリ位置が書き込まれたか読み取られたものとしてログ記録されたならば、さらにログ記録する必要がないので、有用である。これは、妥当性検査中に、読取オブジェクトログから必要な唯一の情報が、トランザクションの前のそのオブジェクトのＳＴＭスナップショットであり、アンドゥログから必要な唯一の情報が、トランザクションの前の更新されたメモリ位置の値であるからである。これは、トランザクション内で変化しないので、トランザクションごとに、所与のメモリ位置について１つのログエントリだけが必要である。
【０１７３】
セクション４の実施態様では、更新済みオブジェクトログのエントリをフィルタリングする必要はない。これは、ＤＴＭＯｐｅｎＦｏｒＵｐｄａｔｅが、同一トランザクション内で同一の更新されたオブジェクトヘッダについて重複したログエントリの作成を許容しないからである。他の実施態様では、そのような重複が作成される可能性があり、したがって、これをフィルタリングすることができる。
【０１７４】
一般に、フィルタは、２つの動作をサポートする。第１の「フィルタ」動作は、指定されたワードがフィルタに存在しなければならない場合に真を返す。この動作は、指定されたワードがフィルタに存在しない可能性がある場合に偽を返し、それを行う際にそのワードをフィルタに追加する。したがって、そのようなフィルタは、検索時に偽陰性を許す確率的集合として働く（すなわち、ワードが実際にはフィルタ内にあるときにそのワードがフィルタ内にないと主張することはできるが、ワードが実際にはないときにそのワードがフィルタ内にあると主張してはならない）。第２の動作「クリア」は、フィルタ内のすべてのワードを除去する。
【０１７５】
ソフトウェアトランザクショナルメモリ（ＳＴＭ）の文脈では、フィルタは、同一ワードの内容が、ＳＴＭが維持するトランザクションログのうちの１つに書き込まれる回数を減らすのに使用することができる。
【０１７６】
５．２  ハッシュテーブルフィルタリングの例
本明細書で説明するフィルタリング方式は、読取オブジェクトログおよびアンドゥログへの重複するログ記録要求を、アソシアティブテーブルを使用して確率的に検出する。本明細書で説明する実施態様は、ハッシュテーブルへの参照を用いるが、代替実施態様で、フィルタリングの技法およびシステムが、アソシアティブテーブルの異なる実施態様を使用できることを理解されたい。一実施態様は、アドレスのハッシュを、そのハッシュを有するアドレスに関連する最も最近のログ記録動作の詳細にマッピングするスレッドごとのテーブルを使用する。
【０１７７】
一実施態様で、１つのアソシアティブテーブルだけが、読取オブジェクトログとアンドゥログとの両方をフィルタリングするのに必要であることに留意されたい。読取オブジェクトログへのストアは、オブジェクトのヘッダワードのアドレスを使用するが、アンドゥログへのストアは、ログ記録されるワードのアドレスを使用する。アドレスのこれらのセットは、互いに素なので、単一のテーブルが、読取オブジェクトアクセスと更新アクセスとの間の衝突を示さず、したがって、この単一のテーブルを両方のログに使用することができる。
【０１７８】
図２０に、テーブルの設計を示す。図２０には、ハッシュテーブル２０００として実施されたアソシアティブテーブルが示されている。図２０に示されているように、ハッシュテーブル２０００の各エントリは、メモリアドレス２０２０およびトランザクション番号２０３０を含む。エントリは、一連のスロット番号２０１０によって編成される。
【０１７９】
一実施態様で、特定のメモリアドレスのスロット番号を識別するハッシュコードには、アドレスをハッシュインデックスおよびタグに分割することによって達する。したがって、そのような実施態様で、ハッシュ関数は、単純にワードＷからのいくつかの最下位ビットを使用して、テーブル内で使用されるスロットＳを選択する。したがって、ワードＷ内のビットは、２つの部分に分割されると考えることができ、最下位ビットは、使用されるスロットを識別するように働くハッシュコードであり、残りは、アドレスを一意に識別するタグとして働く。例えば、ワード０ｘ１０００は、タグ−１  スロット−０を有し、ワード０ｘ１００１は、タグ−１  スロット−１を有し、ワード０ｘ２０００は、タグ−２  スロット−０を有し、ワード０ｘ２００１は、タグ−２  スロット−１を有するなどである。代替実施態様では、異なるハッシング方式が使用される。
【０１８０】
さらに、ハッシュテーブル２０００は、メモリアドレスと別々にトランザクション番号を示すが、様々な実施態様では、トランザクション番号は、ＸＯＲ演算の使用を用いるなど、メモリアドレスと組み合わされる。ＸＯＲ演算は、相対的に高速な演算であり、連続するＸＯＲによって元に戻すことができるので、一実施態様で使用される。代替実施態様では、メモリアドレスの下位ビットをトランザクション番号に置換すること、またはＸＯＲ演算ではなく加算演算を使用することなど、トランザクション番号を記録する異なる方法が使用される。これらは、それぞれが、同一のハッシュコードにハッシュ化される２つのアドレスａ１およびａ２と２つのトランザクション番号ｔ１およびｔ２とに関して、ａ１＝ａ２かつｔ１＝ｔ２である場合に限ってｏｐ（ａ１，ｔ１）がｏｐ（ａ２，ｔ２）と等しいという特性を共有するという点で有用である。この特性は、挿入される組み合わされた値が、その値がそれから作成された特定のアドレスおよびトランザクション番号に一意であることの信頼をもたらす。
【０１８１】
スレッドローカルであるトランザクション番号の使用は、より以前のトランザクションによって記録されたエントリが現在のトランザクションに関連するエントリと混同されるのを防ぐ。トランザクション番号の識別は、トランザクション番号のシーケンスに使用されるビットがオーバーフローするときに限ってテーブルをクリアすることを可能にする。一実施態様で、テーブルは、トランザクション番号のシーケンスがオーバーフローするたびに１回クリアされ、これは、異なるトランザクションから生成された２つのエントリが同一のトランザクション番号を使用するのを防ぐことによって、テーブル内の衝突を防ぐ。もう１つの実施態様では、テーブル内の１つのスロットが、トランザクションごとにクリアされ、いくつかの実施態様では、すべてのトランザクションに小さいオーバーヘッドを追加することが、時折の大きいオーバーヘッドの追加より好ましい場合がある。他の実施形態では、すべてのテーブルのクリアを一時に実行することが好ましい。
【０１８２】
図２１は、ログエントリをフィルタリングする、例のプロセス２１００の流れ図である。様々な実施態様で、図示のプロセスブロックを、マージし、サブブロックに分割し、あるいは省略することができる。このプロセスは、ブロック２１１０で開始され、ここで、トランザクションカウントを、現在のトランザクションの始めに更新する。このカウントは、ハッシュテーブル内で使用されるトランザクション番号を提供する。次に、判断ブロック２１１５で、トランザクションカウント限度に達したかどうかを判定する。一実施態様で、この限度は、カウントに割り振られたビット数をオーバーフローさせることによって判定される。もう１つの実施態様で、この限度は、メモリ制限に基づくものとすることができ、あるいは、ハッシュテーブルの性能を微調整するために選択することができる。限度に達していない場合には、ブロック２１４０で、ログ記録されるアドレスを、ハッシュテーブルを介してフィルタリングする。そうではなく、限度に達している場合には、ブロック２１２０でカウントをリセットし、ブロック２１３０でテーブルをクリアする。その後、ブロック２１４０で、ログ記録されるアドレスを、ハッシュテーブルを介してフィルタリングする。
【０１８３】
図２２は、ログエントリをフィルタリングする、例のプロセス２２００の流れ図である。様々な実施態様で、図示のプロセスブロックを、マージし、サブブロックに分割し、あるいは省略することができる。様々な実施態様で、プロセス２２００は、プロセス２１００のブロック２１４０のプロセスに対応する。プロセス２２００は、ブロック２２１０で開始され、ここで、アドレスをハッシュ化して、正しいハッシュテーブルエントリを見つける。次に、ブロック２２２０で、フィルタリングされるアドレスの、現在のトランザクション番号（トランザクションカウントから受け取られる）とのＸＯＲをとる。一実施態様で、ハッシュ化は、上で説明したように、アドレスをハッシュコードおよびタグ値に分割することによって実行される。
【０１８４】
次に、このプロセスは、判断ブロック２２２５に進み、ここで、ハッシュエントリの値をＸＯＲ結果に対してチェックする。この２つが一致する場合には、メモリアクセスをもう一度ログ記録する必要はなく、ブロック２２３０で、ログに書き込まない。しかし、この２つが一致しない場合には、ブロック２２４０で、ＸＯＲ結果をハッシュテーブルエントリに書き込み、ブロック２２５０で、エントリをログに書き込む。
【０１８５】
５．３  新たに割り振られたオブジェクトのランタイムログフィルタリング
一実施態様で、本明細書で説明するＳＴＭのシステムおよび技法は、現在のトランザクションによって割り振られたオブジェクトに関するすべてのアンドゥログエントリの書込を避けるために、それらのオブジェクトを識別する。これは、上で説明した静的コンパイルタイム分析が、新たに割り振られたオブジェクトの特定のログ動作を見逃すか除去できない場合のバックアップを提供する。このランタイム技法は、現在のトランザクションが異常終了する場合にオブジェクトが死ぬので、安全である。一実施態様で、これは、新たに割り振られたオブジェクトに作用するように特殊化されたバージョンのＤＴＭＯｐｅｎＦｏｒＵｐｄａｔｅを使用し、この動作に、トランザクショナルに割り振られるものとしてオブジェクトをマークするために指定されたＳＴＭワード値を書き込ませることによって行われる。
【０１８６】
６．ガーベジコレクションの例
一般に、ガーベジコレクション（「ＧＣ」）は、メモリオブジェクトがもはやプログラム内のどのスレッドによっても要求されないのでそのメモリオブジェクトを安全に割振り解除できるときを自動的に判定する機構を提供する。ガーベジコレクションは、多数の近代プログラミング言語に組み込まれ、Ｍｉｃｒｏｓｏｆｔ  ．ＮＥＴフレームワークの一部を形成する。
【０１８７】
このセクションでは、ＧＣを上で説明したＳＴＭ技法に統合する様々な実施態様を説明する。しかし、そのような統合は、簡単ではない。その問題を示すために、次の例を検討されたい。
【０１８８】
【表２６】
2009523271.tif 000028
【０１８９】
この例において、Ｅ１およびＥ２で実行される計算の両方が、メモリを使い果たさずに完了するためにＧＣが必要であるのに十分に複雑であると仮定する。さらに、ｔ１に束縛されたＬａｒｇｅＴｅｍｐｏｒａｒｙＯｂｊｅｃｔが、Ｅ１でのみ使用され、同様に、ｔ２に束縛されたＬａｒｇｅＴｅｍｐｏｒａｒｙＯｂｊｅｃｔが、Ｅ２でのみ使用されると仮定する。「原子的」ブロックなしで実行される場合に、ｔ１によって占められるスペースは、Ｅ１が終了したならば再利用することができる。
【０１９０】
この例は、既存のトランザクショナルメモリシステムおよびＧＣを用いて実行することができない。これらのシステムでは、次の２つの問題のうちの１つが発生する。
【０１９１】
１．いくつかの非ＴＭ対応ＧＣは、ＧＣが発生するときにすべてのメモリトランザクションを強制的に異常終了させる。これらのシステムでは、Ｅ１およびＥ２などの計算は、絶対に原子的ブロック内で実行することができない。
【０１９２】
２．他の非ＴＭ対応ＧＣは、我々のＴＭ対応ＧＣより長い間、オブジェクトを強制的に保持させる。これらのシステムでは、この例は、成功して実行することができるが、ｔ１およびｔ２は、ＧＣがＥ２中に発生し、その間にｔ１が後に不必要になることがわかる場合であっても、原子的ブロックの終りまで保持される。
【０１９３】
一実施態様で、これらの問題は、（ａ）スレッドが原子的ブロックの実行の途中である間にＧＣが発生することを可能にし、（ｂ）原子的ブロックが成功して完了する場合であれ、再実行される場合であれ、プログラムによって必要とされないことを保証できるオブジェクトをＧＣが回復することを可能にする、ＴＭ対応ＧＣによって対処される。
【０１９４】
様々な実施態様で、ガーベジコレクション技法は、原子的トランザクションブロックの実施態様内で、現在の原子的ブロック内で割り振られるオブジェクトを識別するのに使用される技法を含む。諸実施態様は、ＳＴＭのデータ構造によって参照されるオブジェクトのどれが、プログラムによって必要とされないことを保証されるかを識別する技法をも含む。最後に、ＧＣ実施態様は、ＴＭのデータ構造内のエントリのどれが、プログラムの将来の実行に不必要であるかを識別する技法を含む。
【０１９５】
次の説明は、特に上で説明したシステムに頼るが、本明細書で説明する実施態様は、そのセッティングに限定はされず、おそらくはハードウェアトランザクショナルメモリを含む他の形のトランザクショナルメモリと共に使用することができる。
【０１９６】
本明細書で説明する実施態様は、ｓｔｏｐ−ｔｈｅ−ｗｏｒｌｄ  ｔｒａｃｉｎｇガーベジコレクタ、例えばｍａｒｋ−ｓｗｅｅｐガーベジコレクタまたはｃｏｐｙｉｎｇガーベジコレクタを参照して説明される。しかし、これは説明を単純にするためであり、諸実施態様は、そのセッティングに限定されるのではなく、既知の手法を使用して、ＳＴＭをｇｅｎｅｒａｔｉｏｎａｌガーベジコレクション、並行ガーベジコレクション、または並列ガーベジコレクションなど、他のガーベジコレクション技法と統合することができる。一実施態様で、ＳＴＭは、ｇｅｎｅｒａｔｉｏｎａｌガーベジコレクションと統合される。
【０１９７】
高水準では、ｓｔｏｐ−ｔｈｅ−ｗｏｒｌｄ  ｔｒａｃｉｎｇ  ＧＣの動作を、次のプロシージャとして要約することができる。まず、アプリケーション内のすべてのアプリケーションスレッドを停止する（時々「ｍｕｔａｔｏｒ  ｔｈｒｅａｄｓ」として知られる）。次に、ｍｕｔａｔｏｒ  ｔｈｒｅａｄｓが当初にオブジェクトにそれによってアクセスする「ルート」のそれぞれを訪れ、これらのルートから参照されるオブジェクトが、コレクション後に保持されることを保証する（ルートは、プロセッサの実行中ｍｕｔａｔｏｒ  ｔｈｒｅａｄｓの保存されたレジスタ内容、スレッドのスタック上のオブジェクト参照、およびプログラムのスタティックフィールドを介してこれらのスレッドに可視のオブジェクト参照を含む）。そのように保持されるオブジェクトを、しばしば、「グレイ」と称し、残りのオブジェクトを、当初は「ホワイト」と称する。次に、グレイオブジェクトのそれぞれについて、それが含むオブジェクト参照を訪れる。これらの参照が識別するすべてのホワイトオブジェクトを、グレイとマークし、グレイオブジェクト内の参照のすべてを訪れたならば、そのオブジェクトをブラックとマークする。グレイオブジェクトがなくなるまで、このステップを繰り返す。残っているすべてのホワイトオブジェクトは、ガーベジと考えられ、それらが占めるスペースは、再割振りのためにｍｕｔａｔｏｒ  ｔｈｒｅａｄｓから使用可能にすることができる。最後に、ｍｕｔａｔｏｒ  ｔｈｒｅａｄｓを再始動する。下の例では、グレイオブジェクトを、「訪問済み」オブジェクトと称し、既知のホワイトオブジェクトを、「到達不能」と称する。
【０１９８】
ＳＴＭをＧＣと統合する一実施態様で、すべてのトランザクションは、ＧＣを開始するときに異常終了される。これは、明白な不利益を有する。もう１つの実施態様では、ＧＣは、ＳＴＭのデータ構造をｍｕｔａｔｏｒ  ｔｈｒｅａｄｓのルートの一部と考え、したがって、オブジェクトがログ内のエントリによって参照されることに基づいて、それらのオブジェクトを訪れる。そのような実施態様では、あるログからのオブジェクトへの参照は、ＧＣがそれらを介して到達可能なメモリを保護することを要求する「強い参照」と考えられる。
【０１９９】
この実施態様は、ＳＴＭシステムとＧＣとの間のある度合の統合を可能にするが、もう１つの実施態様では、より高い度合の統合がある。図２３は、ＳＴＭシステムでガーベジコレクションを実行するガーベジコレクティングモジュール１３９０によって実行される例のプロセス２３００の流れ図である。様々な実施態様で、図示のプロセスブロックを、マージし、サブブロックに分割し、あるいは省略することができる。下の図示のプロシージャでは、ＧＣは、オブジェクトおよびログエントリを使用することがもはや不可能であるときにそれらのオブジェクトおよびログエントリを割振り解除し、冗長エントリを除去することによってログを圧縮するのに、ＳＴＭの特別な知識を使用することができる。一実施態様で、図２３のプロセスは、訪問済みオブジェクトのオブジェクト参照のそれぞれを訪れる、上の通常のＧＣプロシージャのステップの代わりに実行される。代替実施態様では、図２３のプロセスを、他の一般的なＧＣプロシージャに統合することができる。
【０２００】
いくつかの実施態様で、図２３のプロセスは、ＳＴＭシステム内のログ上の２つの質を認識する。第１は、現在のトランザクションがアクセスを試みたオブジェクトを識別するログである。この種類のログは、様々な実施態様で、ＰＬＤＩ論文に記載の実施態様の読取オブジェクトログ、更新済みオブジェクトログ、およびアンドゥログに、アクセスされたオブジェクトへの参照を含む。１つの用語法で、これらのログからのオブジェクトへのいくつかの参照は、「弱い参照」と考えられ、これは、ＧＣが、これらの弱い参照を除いて到達不能なオブジェクトによって使用されるメモリを再利用することを意味する。このプロセスを実行する際にＧＣによって認識されるもう１つの質は、トランザクションのコミットまたは異常終了の際にメモリに復元されるオブジェクト参照を識別するログである。この種類のログは、アンドゥログ内の古い値を含む。これらのログからのこれらの参照は、いくつかの用語法で「強い参照」と称する。上で述べたように、「強い参照」は、ＧＣがこれらを介して到達可能なメモリを保護することを必要とする。
【０２０１】
このプロセスは、ブロック２３１０で開始され、ここで、ＧＣモジュール１３９０は、アンドゥログ１３６０内の各エントリの「前の値」フィールドによって参照されるオブジェクトを訪れ、したがって、これらのオブジェクトが到達不能と考えられるのを防ぎ、現在のトランザクションが異常終了する場合のこれらのオブジェクトの再利用を防ぐ。次に、ブロック２３２０で、ある種のスペシャルケースエントリをログから除去する。そのような除去プロセスの例を、下で図２４に関してより詳細に説明する。
【０２０２】
このプロセスは、ブロック２３２５に継続し、ここで、ＧＣモジュールは、すべての到達可能なオブジェクトを訪れ、到達不能オブジェクトの最終的なセットに達するために、各既に訪問済みのオブジェクトに含まれるオブジェクト参照を訪れる。次に、ブロック２３３０で、ＧＣモジュールは、到達不能オブジェクトを参照する読取オブジェクトログ１３８０内のエントリを再検討する。判断ブロック２３３５で、ＧＣモジュールは、エントリごとに、そのエントリによって参照されるオブジェクトへの衝突する並行アクセスがあるかどうかを判定する。一実施態様では、ＧＣは、エントリごとに、エントリのバージョン番号がオブジェクトのバージョン番号と一致するかどうかを判定することによってこれを行う。そうである場合には、そのエントリが最新であり、オブジェクトが到達不能なので、ブロック２３５０で、そのエントリをログから単純に割振り解除する。しかし、バージョン番号が一致しない場合には、現在のトランザクションが無効である。この点で、ＧＣモジュール自体が、ブロック２３４０でそのトランザクションを異常終了させ、そのトランザクションのすべてのログエントリを削除する。代替実施態様では、ブロック２３３５、２３４０、および２３５０の特定のチェックおよびプロセスを省略することができ、既知の到達不能オブジェクトのエントリは、再検討なしで読取オブジェクトログから割振り解除され、ＳＴＭの他のランタイムシステムに頼って、トランザクションを異常終了させるか否かを判定する。
【０２０３】
次に、ブロック２３６０で、ＧＣモジュールは、更新済みオブジェクトログ１３７０内のエントリを再検討し、到達不能であるオブジェクトを参照するすべてのエントリを割振り解除する。次に、ブロック２３７０で、同一のプロセスを、アンドゥログ１３６０内のエントリについて実行する。最後に、ブロック２３８０で、ＧＣモジュールは、すべての残りの到達不能オブジェクトの割振り解除に進む。
【０２０４】
拡張実施態様は、ＳＴＭログから追加エントリを除去するのに、スペシャルケースを利用する。図２４は、スペシャルケースログエントリを除去する、ガーベジコレクティングモジュール１３９０によって実行される１つのそのような例のプロセス２４００を示す流れ図である。図２４のプロセスは、図２３のブロック２３２０に対応する。様々な実施態様で、図示のプロセスブロックを、マージし、サブブロックに分割し、あるいは省略することができる。本明細書での説明は、プロセス２４００およびブロック２３２０のプロセスの一部である連続するステップとしてとしてこれらの拡張を説明するが、ある種の状況で、図２４のプロセスを、互いに独立に使用することができ、いくつかの場合に、基本実施態様と独立に使用することができ（例えば、ＧＣ以外のときにログを圧縮するために）、高速実施態様が、ログ内のエントリを訪問しなければならない回数を減らすためにこれらのステップのうちの１つまたは複数の諸部分を組み合わせることができることを理解されたい。
【０２０５】
プロセス２４００は、ブロック２４１０で開始され、ここで、１つのトランザクションだけがアクティブである場合に、ＧＣモジュール１３９０は、即座にロールバックし、到達不能オブジェクトを参照するエントリをアンドゥログ１３６０から除去する。ブロック２４２０で、ＧＣモジュールは、読取オブジェクトログ１３８０およびアンドゥログ１３６０を再検討し、エントリが現在のトランザクションブロック内で作成された到達不能オブジェクトを参照する場合に、そのエントリをこれらのログから除去する。ＧＣモジュール１３９０は、オブジェクトがトランザクション開始の後に割り振られ、現在は到達不能である場合に、そのオブジェクトが、トランザクションがコミットするか否かに関わりなく失われるので、これを行う。一実施態様で、現在のトランザクションのサブトランザクション内で割り振られた到達不能オブジェクトのログエントリも、除去される。
【０２０６】
ブロック２４３０で、読取オブジェクトログ内のエントリごとに、そのエントリが参照するオブジェクトを検査し、そのオブジェクトが既に更新済みオブジェクトログにあり、読取オブジェクトログおよび更新済みオブジェクトログのバージョニング番号がそのオブジェクトについて一致する場合に、読取オブジェクトログエントリを除去することができる。このプロセスは、オブジェクトが最初に読取オブジェクトログに追加されたときと、オブジェクトが最初に更新済みオブジェクトログに追加されたときとの両方を識別することができる。どちらの場合でも、ＧＣは、包含される読取オブジェクトログエントリを除去するように働く。
【０２０７】
ブロック２４４０で、ＧＣモジュール１３９０は、重複エントリを可能にするＳＴＭ実施態様で、読取オブジェクトログから重複エントリを除去する。重複読取オブジェクトログエントリ除去の例のプロセスを、下で図２５を参照して説明する。次に、ブロック２４５０で、ＧＣモジュール１３９０は、アンドゥログ内のエントリを再検討し、このログ内の「前の値」をログ記録されたメモリ位置の現在の値と比較する。これらが一致する場合には、値は変化しておらず、アンドゥログエントリを維持する理由はなく、したがって、ＧＣモジュール１３９０は、これらのエントリを除去する。
【０２０８】
図２５は、重複する読取オブジェクトログエントリを除去する、ガーベジコレクティングモジュール１３９０によって実行される１つのそのような例のプロセス２５００を示す流れ図である。図２５のプロセスは、図２４のブロック２４４０に対応する。様々な実施態様で、図示のプロセスブロックを、マージし、サブブロックに分割し、あるいは省略することができる。図２５のプロセスは、読取オブジェクトログエントリが、オブジェクトが現在のトランザクション内で読取のためにオープンされたことを記録するのみであるという事実を利用する。これは、単一のオブジェクトの複数のエントリを余分なものにし、したがって、これらのエントリをＧＣ中に除去することが有益である。
【０２０９】
図２５のプロセスは、ガーベジコレクション中にオブジェクトごとに維持される単一の読取ビットフラグを利用する。一実施態様で、このフラグは、ＳＴＭワードが保たれる形に似て、ランタイムシステムによって保たれる。もう１つの実施態様では、ＧＣモジュール１３９０が、ＧＣ時にオブジェクトごとにフラグを維持する。このプロセスは、ブロック２５１０で開始され、ここで、ＧＣモジュール１３９０が、ログ内の最初のエントリで読取オブジェクトログの圧縮を開始する。次に、ブロック２５２０で、現在再検討されているエントリによって参照されるオブジェクトを再検討する。ブロック２５２５で、ＧＣモジュール１３９０は、オブジェクトがその読取ビットをセットされているかどうかを判定する。そうでない場合には、現在のエントリは、そのオブジェクトの最初のエントリであると仮定される。したがって、ブロック２５３０で、読取ビットをセットし、そのエントリをそのままにしておく。しかし、ＧＣモジュール１３９０が、読取ビットが以前にセットされていると判定する場合には、ブロック２５４０で、このモジュールは、現在のエントリがそのオブジェクトの以前のエントリに対して余分なので、現在のエントリを除去する。一実施態様で、この除去は、保たれるエントリを、除去されるエントリの位置にコピーすることによって、その位置で行われる。他の実施態様では、エントリは、除去されず、単にそれがある場所で割振り解除される。その後、このプロセスは、判断ブロック２５４５に継続し、ここで、このモジュールが、追加のエントリが読取オブジェクトログに存在するかどうかを判定する。そうである場合には、このプロセスが継続する。そうでない場合には、このプロセスは終了する。
【０２１０】
７．コンピューティング環境
上のソフトウェアトランザクショナルメモリ技法は、様々なコンピューティングデバイスのいずれにおいても実行することができる。これらの技法は、ハードウェア回路で、ならびに図１６に示されたものなどのコンピュータもしくは他のコンピューティング環境内で実行されるソフトウェアで実施することができる。
【０２１１】
図２６に、説明した実施形態を実施できる、適切なコンピューティング環境（２６００）の一般化された例を示す。コンピューティング環境（２６００）は、本発明の使用または機能性の範囲に関する限定を暗示することを意図されたものではない。というのは、本発明を、別個の汎用のまたは特殊目的のコンピューティング環境で実施することができるからである。
【０２１２】
図２６を参照すると、コンピューティング環境（２６００）は、少なくとも１つの処理ユニット（２６１０）およびメモリ（２６２０）を含む。図２６では、この最も基本的な構成（２６３０）が、破線の中に含まれる。処理ユニット（２６１０）は、コンピュータ実行可能命令を実行し、実プロセッサまたは仮想プロセッサとすることができる。マルチプロセッシングシステムでは、処理能力を高めるために、複数の処理ユニットが、コンピュータ実行可能命令を実行する。メモリ（２６２０）は、揮発性メモリ（例えば、レジスタ、キャッシュ、ＲＡＭ）、不揮発性メモリ（例えば、ＲＯＭ、ＥＥＰＲＯＭ、フラッシュメモリなど）、またはこの２つのある組合せとすることができる。メモリ（２６２０）は、説明された技法を実施するソフトウェア（２６８０）を記憶する。
【０２１３】
コンピューティング環境は、追加の特徴を有することができる。例えば、コンピューティング環境（２６００）は、ストレージ（２６４０）、１つまたは複数の入力デバイス（２６５０）、１つまたは複数の出力デバイス（２６６０）、および１つまたは複数の通信接続（２６７０）を含む。バス、コントローラ、またはネットワークなどの相互接続機構（図示せず）が、コンピューティング環境（２６００）の構成要素を相互接続する。通常、オペレーティングシステムソフトウェア（図示せず）が、コンピューティング環境（２６００）内で実行される他のソフトウェアのオペレーティング環境を提供し、コンピューティング環境（２６００）の構成要素のアクティビティを調整する。
【０２１４】
ストレージ（２６４０）は、取り外し可能または取り外し不能とすることができ、磁気ディスク、磁気テープまたは磁気カセット、ＣＤ−ＲＯＭ、ＣＤ−ＲＷ、ＤＶＤ、あるいは情報を記憶するのに使用でき、コンピューティング環境（２６００）内でアクセスできる任意の他の媒体を含む。ストレージ（２６４０）は、説明した技法を実施するソフトウェア（２６８０）の命令を記憶する。
【０２１５】
入力デバイス（２６５０）は、キーボード、マウス、ペン、またはトラックボールなどのタッチ入力デバイス、音声入力デバイス、スキャニングデバイス、あるいはコンピューティング環境（２６００）に入力を供給する別のデバイスとすることができる。オーディオに関して、入力デバイス（２６５０）を、サウンドカードまたはアナログ形式もしくはデジタル形式でオーディオ入力を受け入れる類似するデバイス、あるいはコンピューティング環境にオーディオサンプルを供給するＣＤ−ＲＯＭリーダーとすることができる。出力デバイス（２６６０）は、ディスプレイ、プリンタ、スピーカ、ＣＤライタ、またはコンピューティング環境（２６００）から出力を供給する別のデバイスとすることができる。
【０２１６】
通信接続（２６７０）は、通信媒体を介する別のコンピューティングエンティティへの通信を可能にする。通信媒体は、コンピュータ実行可能命令、圧縮されたオーディオ情報またはビデオ情報、あるいは他のデータなどの情報を変調されたデータ信号内で伝える。変調されたデータ信号とは、信号内で情報をエンコードする形でその特性のうちの１つまたは複数をセットされまたは変更された信号である。限定ではなく例として、通信媒体は、電気、光、ＲＦ、赤外線、音響、または他の搬送波を用いて実施される有線または無線の技法を含む。
【０２１７】
本明細書で説明した技法を、コンピュータ可読媒体の全般的な文脈で説明することができる。コンピュータ可読媒体は、コンピューティング環境内でアクセスできる任意の使用可能な媒体である。限定ではなく例として、コンピューティング環境（２６００）に関して、コンピュータ可読媒体は、メモリ（２６２０）、ストレージ（２６４０）、通信媒体、および上記のいずれかの組合せを含む。
【０２１８】
本明細書の技法を、プログラムモジュールに含まれるものなど、コンピューティング環境内でターゲットの実プロセッサまたは仮想プロセッサ上で実行される、コンピュータ実行可能命令の全般的な文脈で説明することができる。一般に、プログラムモジュールは、特定のタスクを実行するか特定の抽象データ型を実施する、ルーチン、プログラム、ライブラリ、オブジェクト、クラス、コンポーネント、データ構造などを含む。プログラムモジュールの機能性を、様々な実施形態で、望み通りに組み合わせ、またはプログラムモジュールの間で分割することができる。プログラムモジュールのコンピュータ実行可能命令を、ローカルコンピューティング環境内または分散コンピューティング環境内で実行することができる。
【０２１９】
提示のために、詳細な説明は、「判定する」、「生成する」、「比較する」、および「書き込む」などの用語を使用して、コンピューティング環境内のコンピュータ動作を記述する。これらの用語は、コンピュータによって実行される動作の高水準の抽象であり、人間によって実行される行為と混同してはならない。これらの用語に対応する実際のコンピュータ動作は、実施態様に依存して変化する。
【０２２０】
本明細書で説明した主題の多数の可能な変形形態に鑑みて、我々は、本発明として、添付の特許請求の範囲およびその同等物の範囲に含まれるすべての実施形態を請求する。
【図面の簡単な説明】
【０２２１】
【図１】原子的メモリトランザクションブロックを含むソースコードをコンパイルするのに使用されるコンパイラを示すブロック図である。
【図２】図１のコンパイラのコンポーネントを示すブロック図である。
【図３】トランザクショナルメモリを使用するプログラムをコンパイルし、実行する、例のプロセスを示す流れ図である。
【図４】トランザクショナルメモリを用いるプログラムをコンパイルするために図１のコンパイラによって実行される、例のプロセスを示す流れ図である。
【図５】高水準ソフトウェアトランザクショナルメモリ最適化を実行するために図１のコンパイラによって実行される、例のプロセスを示す流れ図である。
【図６】分解されたソフトウェアトランザクショナルメモリ命令をコンパイル中に最適化するために図１のコンパイラによって実行される、例のプロセスを示す流れ図である。
【図７】強い原子性を実施する動作を導入するために図１のコンパイラによって実行される、例のプロセスを示す流れ図である。
【図８】ｒｅａｄ−ｔｏ−ｕｐｄａｔｅアップグレードを除去するために図１のコンパイラによって実行される、例のプロセスを示す流れ図である。
【図９】ｒｅａｄ−ｔｏ−ｕｐｄａｔｅアップグレードを除去するために図１のコンパイラによって実行されるもう１つの例のプロセスを示す流れ図である。
【図１０】プロシージャ呼出しの前後で動作を移動するために図１のコンパイラによって実行される、例のプロセスを示す流れ図である。
【図１１】新たに割り振られたオブジェクトに関するログ動作を除去するために図１のコンパイラによって実行される、例のプロセスを示す流れ図である。
【図１２】新たに割り振られたオブジェクトに関するログ動作を除去するために図１のコンパイラによって実行されるもう１つの例のプロセスを示す流れ図である。
【図１３】ソフトウェアトランザクショナルメモリシステムのランタイム環境内でランタイム中に使用されるソフトウェアモジュールを含むブロック図である。
【図１４ａ】マルチユースヘッダワードを使用する例示的オブジェクトを示すブロック図である。
【図１４ｂ】マルチユースヘッダワードを使用する例示的オブジェクトを示すブロック図である。
【図１５ａ】変化するスナップショットを有する例示的オブジェクトを示すブロック図である。
【図１５ｂ】変化するスナップショットを有する例示的オブジェクトを示すブロック図である。
【図１６】スナップショットを使用してオブジェクトを妥当性検査する、図６のランタイム環境の、例のプロセスを示す流れ図である。
【図１７】膨張させられたヘッダワードを使用してオブジェクトのスナップショットを変更する、図６のランタイム環境の、例のプロセスを示す流れ図である。
【図１８ａ】トランザクション実行の例を示すブロック図である。
【図１８ｂ】トランザクション実行の例を示すブロック図である。
【図１９ａ】トランザクション実行のもう１つの例を示すブロック図である。
【図１９ｂ】トランザクション実行のもう１つの例を示すブロック図である。
【図１９ｃ】トランザクション実行のもう１つの例を示すブロック図である。
【図２０】ログフィルタリングのために図６のランタイム環境で使用される、例のアソシアティブテーブルを示すブロック図である。
【図２１】図１３のアソシアティブテーブルを使用してログエントリをフィルタリングする、図６のランタイム環境の、例のプロセスを示す流れ図である。
【図２２】図１３のアソシアティブテーブルを使用してログエントリをフィルタリングする、図６のランタイム環境のもう１つの例のプロセスを示す流れ図である。
【図２３】ガーベジコレクション中にログを圧縮する、図６のランタイム環境の実行される例のプロセスを示す流れ図である。
【図２４】ガーベジコレクション中にログを圧縮する、図６のランタイム環境の実行されるもう１つの例のプロセスを示す流れ図である。
【図２５】ガーベジコレクション中にログを圧縮する、図６のランタイム環境の実行されるもう１つの例のプロセスを示す流れ図である。
【図２６】本明細書の技法を実施するのに適するコンピューティング環境を示すブロック図である。
【図１】
2009523271.tif 000029
【図２】
2009523271.tif 000030
【図３】
2009523271.tif 000031
【図４】
2009523271.tif 000032
【図５】
2009523271.tif 000033
【図６】
2009523271.tif 000034
【図７】
2009523271.tif 000035
【図８】
2009523271.tif 000036
【図９】
2009523271.tif 000037
【図１０】
2009523271.tif 000038
【図１１】
2009523271.tif 000039
【図１２】
2009523271.tif 000040
【図１３】
2009523271.tif 000041
【図１４ａ】
2009523271.tif 000042
【図１４ｂ】
2009523271.tif 000043
【図１５ａ】
2009523271.tif 000044
【図１５ｂ】
2009523271.tif 000045
【図１６】
2009523271.tif 000046
【図１７】
2009523271.tif 000047
【図１８ａ】
2009523271.tif 000048
【図１８ｂ】
2009523271.tif 000049
【図１９ａ】
2009523271.tif 000050
【図１９ｂ】
2009523271.tif 000051
【図１９ｃ】
2009523271.tif 000052
【図２０】
2009523271.tif 000053
【図２１】
2009523271.tif 000054
【図２２】
2009523271.tif 000055
【図２３】
2009523271.tif 000056
【図２４】
2009523271.tif 000057
【図２５】
2009523271.tif 000058
【図２６】
2009523271.tif 000059