インテル® C++ コンパイラー 19.0 デベロッパー・ガイドおよびリファレンス
Hardware Lock Elision (HLE) 組込み関数は、Windows* 向けの C/C++ アプリケーションにのみ適用されます。
Hardware Lock Elision (HLE) には、従来のプロセッサーと互換性のある、トランザクション実行用の命令セット・インターフェイスがあります。HLE は、XACQUIRE および XRELEASE の 2 つの新しい命令プリフィクス・ヒントを提供します。
プログラマーは、クリティカル・セクションを保護するロックの取得に使用する命令の前に XACQUIRE プリフィクスを使用します。プロセッサーは、ロック取得操作と関連付けられている書き込みを無効にするヒントとしてこれを使用します。ロック取得にロックに関連付けられている書き込み操作が含まれていても、プロセッサーは、トランザクション領域の書き込みセットにロックのアドレスを追加せず、ロックに対する書き込み操作を要求しません。代わりに、ロックのアドレスが読み取りセットに追加され、論理プロセッサーがトランザクション実行に入ります。XACQUIRE プリフィクスが付加された命令の前にロックが利用可能であれば、命令の後にほかのすべてのプロセッサーはそのロックを利用可能なものとして扱います。トランザクション実行する論理プロセッサーは、書き込みセットにロックのアドレスを追加せず、外部に明確な書き込み操作を行わないため、ほかの論理プロセッサーは、データ競合を引き起こすことなくロックを読み取ることができます。つまり、ほかの論理プロセッサーがロックで保護されたセクションに入り、同時実行できることになります。プロセッサーは、トランザクション実行中に引き起こされるデータ競合を自動的に検出し、必要な場合はトランザクションをアボートします。
ハードウェアは、トランザクションを実行するプロセッサーがロックに対する外部書き込み操作を行わないにもかかわらず、ロックに対する操作のプログラム順を保証します。トランザクション実行中のプロセッサーがクリティカル・セクションでロックの値を読み取ると、プロセッサーがロックを取得したように見えます (トランザクション実行のものではない値が返されます)。この動作により、HLE 実行と HLE プリフィクスなしの実行が機能的に同じになります。
プログラマーは、クリティカル・セクションを保護するロックの解放に使用する命令の前に XRELEASE プリフィクスを使用します。この命令にはロックに対する書き込みも含まれます。この命令により、同じロックの XACQUIRE プリフィクスが付加されたロック取得操作の前の値にロックの値が戻された場合、プロセッサーはロックの解放に関連付けられている外部書き込み要求を無視し、書き込みセットにロックのアドレスを追加しません。次に、プロセッサーはトランザクション実行をコミットしようとします。
複数のスレッドが同じロックで保護されたクリティカル・セクションを実行する場合でも、データ競合が発生する操作を行わないのであれば、スレッドをシリアル化することなく同時に実行できます。ソフトウェアが共通のロックでロック取得操作を行った場合でも、ハードウェアはこの処理を認識し、ロックを無効にして、ロック間で通信を行うことなく、2 つのスレッドでクリティカル・セクションを実行します (通信が動的に不要だった場合)。
プロセッサーが領域をトランザクション実行できない場合、領域は非トランザクションに、無視されることなく実行されます。HLE 対応のソフトウェアは、基本となる非 HLE のロックベースの実行と同じように処理が進むことが保証されます。HLE 実行を成功させるには、ロックおよびクリティカル・セクションのコードが特定のガイドラインに従う必要があります。これらのガイドラインはパフォーマンスにのみ影響します。これらのガイドラインに従わなかった場合でも機能的な問題は起こりません。
HLE をサポートしていないハードウェアは、XACQUIRE および XRELEASE プリフィクス・ヒントを無視するだけで、ロックそのものを無効にすることはありません。これらのプリフィクスは、XACQUIRE および XRELEASE が有効な場合に命令で無視される REPNE/REPE IA-32 アーキテクチャー・プリフィクスに対応しています。重要な点は、HLE は既存のロックベースのプログラミング・モデルと互換性があるということです。ヒントを不適切に使用しても機能的なバグは起こりませんが、コードに含まれている潜在的なバグが表面化する可能性があります。