2017-01-31 16 views
4

このアプリケーションの目的は、TCPを介して800の同時クライアントを処理することです。各クライアントは、毎秒3.5kb xmlを送信します。これらのリクエストのそれぞれを解析する必要があります(コードを参照)。これは、異なるスレッドで発生します。Raspberry PiのJavaのスレッドパフォーマンスの問題

このプロジェクトの制限は、小さなRaspberry Pi3(1.2GHzのクアッドコア、1GBのRAM)で動作することです。 150台以上のクライアント(80%のCPU使用率)を超える負荷を増やすと、私は使用率の問題に遭遇します。

このプログラムを私の開発マシンで実行すると、非常にうまく動作しているようです。 (0-1%使用、150未満)。開発マシンがRPIよりも強力であることが分かりました。しかし、その違いは大きすぎるようです。

私の現在の設定では、すべての着信接続を処理/読み込むためにJava nioを使用しています。次に、私は複数のスレッドを使用してデータを読み込みます。

Current Setup

これは、現在処理スレッド上で動作する簡単なコードです。また、単純なバイト[]配列を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フラグを指定して実行しようとしましたが、同じ結果です。
+3

Piは**絶対に最悪のIOを持っている**。お使いのPCには巨大なスピンディスク、おそらくはSSDがあります。これは厄介なSDカードよりも**速いです**。 CPUアーキテクチャ、コア数、ハイパースレッディングなどで始まったことさえありません。 –

+0

私はこれをイーサネット経由で実行しているとしますか?この記事では、https://www.jeffgeerlingという興味深い情報を紹介します。「実際には多くの場合、Piの他のサブシステム(CPUとディスクI/Oは特にI/Oが1つのシステム上にあるので、com/blogs/jeff-geerling/getting-gigabit-共有USB 2.0バス)は利用可能な帯域幅を制限します。私はまた、あなたが十分なパワーを得ることを確認する必要があることを読んだが、あまりにもパフォーマンスを低下させる(最大描画は約1,100mAhでなければならないが、これはモデルによって異なるかもしれない) –

+1

アプリケーションは、 piは(処理なしで)ちょうど良いソケットIOを扱うことができます。メインスレッドでは、ソケットは読み込まれてバイトバッファに格納されます。私は正しく処理スレッドは、RAMから読み取る必要があります。 – Georggroenendaal

答えて

0

問題は、Raspberry Pi 3のJVMと32ビットOSの両方の組み合わせであることが判明しました。32bit raspbianをOpenJDKで実行すると、アプリケーションのパフォーマンスが非常に悪くなりました(特に 'read'コール)。 Oracle JVMに切り替えると、「より良い」予測パフォーマンスが得られました。

しかし、64ビットOS(私の場合はOpensSuse)に切り替えると、OpenJDKとOracle JVMの両方でパフォーマンスが向上しました。

(クレジットは、64ビットOSに切り替えることを示唆しているため、コメントで@jwwする)