1

Collection を反復処理して、オブジェクト全体をキャッシュにロード/アンロードせずに、属性のサブセットのみを取得する方法はありますか? 特にオブジェクトが大きい場合、一部の属性のみが必要な場合に、オブジェクト全体 (おそらく大きい) をロード/アンロードするのは無駄に思えます。そのような不要なデータをロードすると、不要なキャッシュ競合が発生する可能性がありますよね?

「キャッシュにロード」するつもりだったとき、プロセッサを介してそのオブジェクトを「処理」することを意味します。したがって、ex: 10 属性のオブジェクトがあります。反復ループでは、そのうちの 1 つだけを使用します。このようなシナリオでは、他の 9 つの属性をすべてメモリからプロセッサにロードするのはもったいないと思います。完全なオブジェクトをロードせずに属性のみを抽出するソリューションはありませんか?

また、Google の Guava のようなものは内部的に問題を解決しますか?

ありがとう!

4

2 に答える 2

3

通常、最初に確認する場所ではありませんが、キャッシュ共有の問題が発生している可能性がまったくないわけではありません。(現実的なプロファイリングまたはハードウェア カウンターの分析から) これが対処する価値のあるボトルネックであると本当に確信している場合は、データ構造を変更してプリミティブの並列配列を使用することを検討してください (一部の DB アーキテクチャにおける列ベースのデータベース ストレージに似ています)。 . たとえば、1 つの「列」を としてfloat[]、別の「列」を としてshort[]、3 番目の列を としてString[]、すべて同じ識別子でインデックス付けされます。この構造により、現在必要のない列をキャッシュにロードすることなく、個々の列を「クエリ」することができます。

私は、C から本当に恩恵を受けるいくつかの低レベルのアルゴリズム コードを持っていますstruct。さまざまな代替案でいくつかのマイクロベンチマークを実行したところ、並列配列が私のアルゴリズムにとって最も効果的なオプションであることがわかりました (これは、自分のアルゴリズムに当てはまる場合と当てはまらない場合があります)。

java.util並列配列構造は、コレクションでオブジェクトを使用するよりも維持および変更がかなり複雑になることに注意してください。繰り返しますが、私がこのアプローチを取るのは、痛みに見合うだけのメリットがあると確信した後でのみです。

于 2013-02-19T23:09:44.920 に答える
2

Java ではプロセッサ キャッシュへのロードを管理する方法はなく、JVM がオブジェクトを処理する方法を変更する方法もないため、答えはノーです。Java は低水準言語ではないため、そのような詳細をプログラマーから隠します。

JVM は、ロードするオブジェクトの量を決定します。ある種の先読み最適化としてオブジェクト全体をロードするか、実際にアクセスするフィールドのみをロードするか、JIT コンパイル中にコードを分析して両方を組み合わせて実行します。

また、オブジェクトがどのくらい大きいか心配ですか? いくつかのフィールドを持つクラスはめったに見たことがないので、それほど大きくはないと思います。

于 2013-02-19T06:32:02.213 に答える