NIO:ScyllaとCharybdisの間ですか?

java.NIOフレームワークで広く公開されているプロパティの1つはノンブロッキングです。これは、I / Oと計算操作を並行して実行する機能を意味します。 ファイルの読み取りを要求したアプリケーションに、ファイルからデータを受信する前に処理できる計算タスクがある場合、これらの操作を同時に実行することが可能になります。 遅延記録の場合、並列処理の可能性はさらに大きくなります。これは、読み取り時とは異なり、書き込み時にはアプリケーションがデータの到着を期待しないためです。



ご注意 この記事「NIO:パフォーマンスまたは互換性?」を読みたいと思いますが、既知の制限により、これらの古代ギリシャの老婦人の名前を引用する必要があります。



ここでの成功要因は、ハードウェアサポートです。 SATA AHCI(Advanced Host Controller Interface)やNVMe(PCI Expressの不揮発性メモリインターフェイス)などのデバイスの大容量ストレージコントローラーは、かなり長いシーケンスの入出力操作を処理し、バスマスターモードでメインメモリとドライブ間でデータを移動できます。中央処理装置によって実行されるプログラムの参加なし。



 ,   AHCI






図1 RAMのAHCIドライバーによって生成され、ハードウェアのコントローラーによって解釈されるコマンド リストには、最大32個のI / O操作記述子を含めることができます。 AHCI仕様の図



矛盾と決定



ここでは、2つの相互に矛盾する基準に基づいた、NIOフレームワークの別の、それほど明白ではないが、非常に重要な特性について説明します。



  1. 一方では、Javaはクロスプラットフォームプログラミング言語として、コンピューティングシステムのハードウェア特性、アーキテクチャ、さらにはCPU容量からも抽象化されています。 互換性には、アプリケーションプログラマを低レベルの詳細から確実に分離する一連の抽象化が必要です。 Javaでのポインターの不足を思い出すだけで十分です。
  2. 一方、パフォーマンスには、コードの詳細な最適化、特定の実行環境の仕様への適応、および使用するハードウェアのタイプが必要です。




Javaネイティブインターフェイス



1つの代替ソリューションは、Cまたはアセンブラーで記述されたJavaクラスとライブラリーをペアにすることです。 各オペレーティングシステムに対して標準化され、JVMとネイティブコード間の相互作用を提供するメカニズムによって補完される、従来の呼び出し規約に基づいて、 Java Native InterfaceJNI )を実装するネイティブクラスに言及するしかありません。 ちなみに、JNIテクノロジーを習得すると、ポインターにアクセスできますが、Javaにポインターがないと、不便な場合があります。



同時に、ネイティブコードの統合などの過激な方法を使用すると、Javaのクロスプラットフォームの利点がなくなり、アプリケーション開発の複雑さとエラーの可能性が劇的に増加します。 JNIソリューションでの複数のプラットフォームのサポートは、必然的に、サポートされるシステムの数に等しい数のライブラリのセットを作成および維持する必要があるforkコンストラクトを意味します。



確かに、JNIの使用が必要な状況があります。 たとえば、ハードウェア乱数ジェネレーターなどの一部の特別なデバイスのサポート。



NIO



結局のところ、プラットフォームのハードウェアリソースをカプセル化する抽象化システムを最適に設計すれば、Javaで高性能コードを開発することもできます。



ディスクからファイルを読み取る操作を検討してください。 プロセスには、データソース(ドライブまたはファイル)とレシーバー(RAMのバッファー)の2つの参加者がいることは明らかです。 以下はすべて、ファイルをディスクに書き込む場合に当てはまります。情報転送の方向のみが異なり、ソースと受信者は入れ替わります。



カスタムアプリケーションの場合、 ドライブまたはファイルはディスクI / O API関数で表されます。 互換性とセキュリティの明らかな理由により、MS-DOSの時代から過去から姿を消したユーザーアプリケーションを使用して、ディスクコントローラーのレジスタを直接プログラミングする可能性は考慮しません。



バッファは、アプリケーションのアドレス空間内の指定された範囲のメモリです。 多くの高レベルプラットフォームでは、 退屈なことに、レシーババッファは物理的に中央プロセッサのキャッシュに配置できますが、指定された範囲のRAMアドレスとの関連付けを失うことなく、従来のキャッシングルールに準拠します。



したがって、ハードウェアプラットフォームの対象オブジェクトは次のとおりです。





「客観的現実」の2つの名前付きコンポーネントに直接対応するJavaクラスを実装することにより、 チャネルとバッファーの概念に基づいたNIOフレームワークの開発者によって行われた補助操作の数を最小限に抑えることで、高性能ソリューションを得ることができます



もちろん、このようなツールは、低レベルのハードウェア依存プログラミングなしでは実装できません。 このツールを使用することで、アプリケーションプログラマがそのような必要性から救われると言うだけです。



NIOBenchユーティリティ



IC Book Labsによって開発され、マスストレージサブシステムのパフォーマンスを測定するように設計されたNIOBenchユーティリティは、ファイル操作を実行するときにチャネルとバッファを使用して言われたことを示しています。



 NIOBench,     ,






図2 NIOBenchユーティリティ、ASUS N750JKラップトップハードドライブでファイルの読み取り、書き込み、コピーの速度を測定した結果を表示(データ処理には中央値と算術平均が使用されます)



   NIOBench






図3 結果の詳細なログを記録したNIOBenchユーティリティテキストレポート:キャッシュの効果は明ら​​かです



入出力メソッド、特にベンチマークの対象となるファイルの読み取り、書き込み、コピー操作は、次のアーキテクチャ要素に基づいています。





この推奨事項に従わないと、Java抽象化を処理のためにAPI関数に渡されるネイティブオブジェクトに変換する必要があるため、パフォーマンスが低下する可能性があります。 JNIインターフェースは、NIOBenchプロジェクトでも使用され、RDRANDプロセッサ命令に基づいたハードウェア乱数ジェネレーターのサポートライブラリを接続します(この記事は 、執筆中の「Javaベンチマーク:ランダムパターンと通常の結果」です)。



まとめ



NIOテクノロジーの基礎であるチャネルとバッファの概念は、データストレージサブシステムのアーキテクチャに正確に対応しており、その主な機能はメインメモリ(バッファ)とさまざまなドライブ(チャネル)間の情報の移動に限定されます。



同時に、奇跡は起こらず、フレームワークを適用したプログラマーを解放する低レベルの作業は、フレームワークとシステムプログラマーの開発者にのみ譲渡されます...



参照資料






All Articles