このアプリケーションの目的は、TCPを介して800の同時クライアントを処理することです。各クライアントは、毎秒3.5kb xmlを送信します。これらのリクエストのそれぞれを解析する必要があります(コードを参照)。これは、異なるスレッドで発生します。Raspberry PiのJavaのスレッドパフォーマンスの問題
このプロジェクトの制限は、小さなRaspberry Pi3(1.2GHzのクアッドコア、1GBのRAM)で動作することです。 150台以上のクライアント(80%のCPU使用率)を超える負荷を増やすと、私は使用率の問題に遭遇します。
このプログラムを私の開発マシンで実行すると、非常にうまく動作しているようです。 (0-1%使用、150未満)。開発マシンがRPIよりも強力であることが分かりました。しかし、その違いは大きすぎるようです。
私の現在の設定では、すべての着信接続を処理/読み込むためにJava nioを使用しています。次に、私は複数のスレッドを使用してデータを読み込みます。
これは、現在処理スレッド上で動作する簡単なコードです。また、単純なバイト[]配列を1バイトずつ読み込もうとしました。 StaXストリームを読むことさえできます。 私が試した読書のすべてのバリエーション、操作の '読書のタイプ'は、最悪のパフォーマンスを与えます。
BufferedInputStream input = new BufferedInputStream(new ByteArrayInputStream(buffer.array(), 0, bytecount));
int current;
/* In this snippet input.read() is the cause of performance issues
Reading directly from byte[] gives similar poor performance.
*/
while ((current = input.read()) != -1) {
continue;
}
私のプロファイラによればInput.read()呼び出しは、PIに処理能力の膨大な量を使用し、総CPU時間の97%を占めます。残りの3%は接続を処理するメインスレッドです。
私の開発マシンでは、これはほとんど反転されており、メインスレッドはCPU使用量のほとんどを占めています(93%)。そして7%は処理スレッドに行きます。
この大きな違いが生じる原因は何ですか?なぜ私の他のマシンと比較して、このread()呼び出しが非常に高価なのですか?メモリと何か関係がありますか?
注:
- PiはraspbianのLinuxを実行します - OpenJDKの1.8.0_40-内部 Devのマシンの実行が勝つ
- 10 - ジャワ(TM)SEランタイム環境(ビルド1.8.0_121-B13)
- 両方のマシンで-Xms -Xmxフラグを指定して実行しようとしましたが、同じ結果です。
Piは**絶対に最悪のIOを持っている**。お使いのPCには巨大なスピンディスク、おそらくはSSDがあります。これは厄介なSDカードよりも**速いです**。 CPUアーキテクチャ、コア数、ハイパースレッディングなどで始まったことさえありません。 –
私はこれをイーサネット経由で実行しているとしますか?この記事では、https://www.jeffgeerlingという興味深い情報を紹介します。「実際には多くの場合、Piの他のサブシステム(CPUとディスクI/Oは特にI/Oが1つのシステム上にあるので、com/blogs/jeff-geerling/getting-gigabit-共有USB 2.0バス)は利用可能な帯域幅を制限します。私はまた、あなたが十分なパワーを得ることを確認する必要があることを読んだが、あまりにもパフォーマンスを低下させる(最大描画は約1,100mAhでなければならないが、これはモデルによって異なるかもしれない) –
アプリケーションは、 piは(処理なしで)ちょうど良いソケットIOを扱うことができます。メインスレッドでは、ソケットは読み込まれてバイトバッファに格納されます。私は正しく処理スレッドは、RAMから読み取る必要があります。 – Georggroenendaal