ホームページ  >  記事  >  Java  >  JAVA での JVM 並べ替えの詳細な紹介

JAVA での JVM 並べ替えの詳細な紹介

高洛峰
高洛峰オリジナル
2017-01-23 10:20:571414ブラウズ

並行プログラムでは、プログラマは、異なるプロセスまたはスレッド間のデータの同期に特別な注意を払います。特に、複数のスレッドが同じ変数を同時に変更する場合、データが正しく変更されることを保証するために、信頼性の高い同期またはその他の措置を講じる必要があります。重要な原則は、命令が実行される順序を想定しないことです。異なるスレッド間の命令が実行される順序は予測できません。

しかし、シングルスレッドプログラムでは、命令が順番に実行されると想定するのが一般的ですが、そうでない場合、プログラムにどんなひどい変化が起こるか想像することができます。理想的なモデルは、さまざまな命令が実行される順序が一意であり、その順序が、プロセッサーやその他の要因に関係なく、コードに記述された順序であるということです。このモデルは、逐次一貫性モデルと呼ばれます。フォン・ノイマンシステムに基づいたモデルです。もちろん、この仮定自体は合理的であり、実際には異常が発生することはほとんどありません。しかし、実際には、このモデルは非効率すぎるため、現代のマルチプロセッサ アーキテクチャはこのモデルを採用していません。コンパイルの最適化と CPU パイプラインでは、ほとんどすべてに命令の並べ替えが含まれます。

コンパイル時の並べ替え

一般的なコンパイル時の並べ替えは、プログラムのセマンティクスを変更せずにレジスタの読み取りと格納の数をできる限り減らすように命令の順序を調整し、格納されている値を完全に再利用することです。レジスター。

最初の命令が値を計算して変数 A に代入し、レジスタに格納するとします。2 番目の命令は A とは関係ありませんが、レジスタを占有する必要があります (A が配置されているレジスタを占有すると仮定します)。 3 番目の命令は A の値を使用し、2 番目の命令とは関係がありません。次に、逐次一貫性モデルに従って、最初の命令が実行された後に A がレジスタに入れられ、2 番目の命令が実行されると A が存在しなくなり、3 番目の命令が実行されると A が再びレジスタに読み込まれるとします。このプロセスでは、A の値は変化しません。通常、コンパイラは 2 番目と 3 番目の命令の位置を交換して、最初の命令の終わりに A がレジスタに存在するようにします。その後、A の値をレジスタから直接読み取ることができるため、繰り返し読み取るオーバーヘッドが軽減されます。

パイプラインへの並べ替えの重要性

現代の CPU はほとんどすべて、命令の処理を高速化するためにパイプライン メカニズムを使用していますが、命令の処理には数 CPU クロック サイクルが必要ですが、パイプラインを介した並列実行により、これを実現できます。複数の命令を実行するための具体的な方法は、命令を読み取り、アドレス指定、解析、実行、その他のステップなどの異なる実行サイクルに分割し、それらを異なるコンポーネントに配置して処理するだけです。同時に、実行ユニット EU では、関数ユニットが加算要素、乗算要素、ロード要素、記憶要素などの異なる要素に分割され、異なる計算の並列実行をさらに実現できます。

パイプライン アーキテクチャは、シーケンシャル モデルで考慮されるのではなく、命令が並列で実行されるべきであることを決定します。並べ替えはパイプラインを最大限に活用するのに役立ち、それによってスーパースカラー効果を実現します。

シーケンスの確保

命令は作成した順序で実行される必要はありませんが、シングルスレッド環境では、命令実行の最終的な効果がシーケンシャル実行の効果と一致する必要があることは間違いありません。それ以外の場合は、この最適化が行われます。無意味になります。

通常、命令の並べ替えがコンパイル時または実行時に実行されるかどうかに関係なく、上記の原則が満たされます。

Java ストレージ モデルでの並べ替え

Java メモリ モデル (JMM) では、並べ替えは、特に同時プログラミングにおいて非常に重要なセクションです。 JMM は、操作 B を実行するスレッドが操作 A を実行する結果を監視するようにするには、事前発生ルールによって順次実行セマンティクスを保証します。そうでない場合、JVM は任意の実行を行うことができます。プログラムのパフォーマンスを向上させるための並べ替え操作。

volatile キーワードは変数の可視性を確保できます。これは、volatile に対する操作がすべてメイン メモリ内にあり、メイン メモリがすべてのスレッドによって共有されるためです。その代償として、パフォーマンスが犠牲になり、レジスタやキャッシュが使用できないことになります。グローバルの場合、可視性は保証できず、ダーティ リードが発生する可能性があります。

volatile のもう 1 つの機能は、再順序付けをローカルで防止することです。再順序付けすると、可視性の問題が発生する可能性があるため、volatile 変数の操作命令は再順序付けされません。

可視性の確保という点では、ロック (明示的ロック、オブジェクト ロックを含む) とアトミック変数の読み書きにより、変数の可視性を確保できます。ただし、実装方法は若干異なります。たとえば、同期ロックでは、ロックが解放されると、データがメモリに書き戻されてキャッシュが更新されます。データは可視ですが、揮発性変数は単にメモリを読み書きするだけです。

JAVA での JVM 並べ替えの詳細と関連記事については、PHP 中国語 Web サイトに注目してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。