14

私はライブラリを書いています:

  • さまざまなプラットフォーム/Java 実装で実行する必要があります(一般的なケースは、Windows または Linux を搭載した Intel 64 ビット マシン上の OpenJDK または Oracle Java である可能性があります)。
  • オブジェクトアクセスのCPUキャッシュライン効率を気にするほど、高性能化が優先
  • 一部の領域では、小さなオブジェクトの非常に大きなグラフがトラバース/処理されます (約 1 GB スケールとしましょう)。
  • 主なワークロードはほぼ独占的に読み取りです
  • 読み取りはオブジェクト グラフ全体に分散されますが、完全にランダムではありません (つまり、頻繁にアクセスされない領域への読み取りが時折行われる大きなホットスポットが存在します)。
  • オブジェクト グラフは、複数のスレッドによって同時にアクセスされます (変更はされません)。同時変更が発生しないという前提で、ロックはありません。

この種の環境で CPU キャッシュ ラインを効果的に利用できるように、小さなオブジェクトを設計するための経験則やガイドラインはありますか?

オブジェクトのサイズと構造を正しく設定することに特に関心があります。たとえば、最も頻繁にアクセスされるフィールドが最初のキャッシュ ラインに収まるようにするなどです。

注:これは実装に依存すること、ベンチマークを行う必要があること、時期尚早の最適化の一般的なリスクを十分に認識しています。これを指摘するために帯域幅を無駄にする必要はありません。:-)

4

2 に答える 2

11

キャッシュ ラインの効率化に向けた最初のステップは、参照の局所性を提供することです (つまり、データを相互に近づけます)。ほとんどすべてがシステムによって割り当てられ、参照によってアクセスされる Java では、これを行うのは困難です。

参照を避けるために、次のことが明らかな場合があります。

  1. オブジェクトのフィールドとして非参照型 (つまり、int、char など) を持つ
  2. オブジェクトを配列に保持する
  3. オブジェクトを小さく保つ

これらのルールは、単一のオブジェクトで作業するとき、およびオブジェクト グラフ内のオブジェクト参照をトラバースするときに、少なくともある程度の参照局所性を保証します。

別のアプローチとして、データにオブジェクトをまったく使用せず、通常はクラスのフィールドである各項目に (同じサイズの) グローバルな非 ref 型付き配列を使用し、各インスタンスを共通のインデックスで識別することもできます。これらの配列に。

次に、配列またはそのチャンクのサイズを最適化するには、MMU の特性 (ページ/キャッシュ サイズ、キャッシュ ライン数など) を知る必要があります。JAVA がこれをシステム クラスまたはランタイム クラスで提供するかどうかはわかりませんが、起動時にこの情報をシステム プロパティとして渡すことができます。

もちろん、これはJAVAで通常行うべきこととは完全に直交しています:)

よろしくお願いします

于 2012-12-31T03:31:04.287 に答える
2

CPU のさまざまなキャッシュに関する情報が必要になる場合があります。Java からCachesize (現在サポートされている Intel CPU) を使用してアクセスできます。これは、キャッシュ対応アルゴリズムの開発に役立ちます。

免責事項:ライブラリの作者。

于 2014-01-12T17:26:42.290 に答える