問題
ミューテックスのないステートレスで副作用のない関数を実装するJavaコード(関連する場合はJDK 1.6.0._22)があります。ただし、大量のメモリを使用します(それが関連しているかどうかはわかりません)。
過去に、私は Sun Laboratories を訪れ、標準的な「パフォーマンスとスレッド数」の曲線を集めました。この関数にはミューテックスがないため、スレッドの数が増えるとガベージ コレクションが開始されますが、グラフは良好です。ガベージ コレクションの調整を行った後、この曲線をほぼフラットにすることができました。
現在、Intel ハードウェアで同じ実験を行っています。ハードウェアには、それぞれ 8 コアの 4 つの CPU とハイパースレッディングが搭載されています。これにより、64 個の availableProcessors() が得られます。残念ながら、「パフォーマンス対スレッド数」の曲線は、1、2、3 スレッドで適切にスケーリングされ、3 スレッドでキャップされます。3 つのスレッドの後、タスクに必要な数のスレッドを配置できますが、パフォーマンスは向上しません。
問題を解決する試み
私の最初の考えは、私が愚かで、同期されたコードをどこかに導入したということでした。通常、この問題を解決するには、JConsole または JVisualVM を実行し、スレッドのスタック トレースを調べます。速度 3 で 64 個のスレッドを実行している場合、そのうち 61 個のスレッドがミューテックスに入るのを待っていると予想されます。私はこれを見つけませんでした。代わりに、すべてのスレッドが実行されていることがわかりました。非常にゆっくりです。
2 番目の考えは、おそらくタイミング フレームワークが問題を引き起こしているということでした。関数を、AtomicLong を使用して 10 億までカウントするダミー関数に置き換えました。これはスレッド数に応じて美しくスケーリングされました。1 スレッドよりも 64 スレッドの方が 64 倍速く、10,000 倍までカウントすることができました。
おそらくガベージ コレクションに非常に長い時間がかかっているのではないかと考えたので (必死になって)、ガベージ コレクションのパラメーターを微調整しました。これによりレイテンシーの変動は改善されましたが、スループットには影響しませんでした。3 つ実行すると予想される速度で、まだ 64 個のスレッドが実行されています。
インテル ツール VTunes をダウンロードしましたが、スキルが弱く、複雑なツールであり、まだ理解できていません。私は注文書を持っています: 自分自身への楽しいクリスマスプレゼントですが、それは私の現在の問題を解決するには少し遅すぎます.
質問
- 何が起こっているのかについての理解を深めるために、どのようなツール (メンタルまたはソフトウェア) を使用できますか?
- ミューテックスまたはガベージ コレクション以外のどのメカニズムがコードの速度を低下させている可能性がありますか?