プロセッサはRAMが提供できるものよりもはるかに高速であるため、キャッシュが必要です。キャッシュは引き続き固定サイズのキャッシュラインで構成されます。また、メインメモリはページ単位で提供され、ページはトランスレーションルックアサイドバッファを使用してアクセスされます。このバッファにも、固定サイズのキャッシュがあります。
これは、空間的および時間的局所性の両方が非常に重要であることを意味します(つまり、荷物をどのように梱包し、どのようにアクセスするか)。構造を無計画な順序で梱包するのではなく、構造を適切に梱包すると(パディング/位置合わせの要件でソート)、通常、構造のサイズが小さくなります。
大量のデータがある場合、構造体のサイズが小さいということは、次のことを意味します。
- より多くの構造が1つのキャッシュラインに収まります(キャッシュミス= 50〜200サイクル)
- 必要なページ数が少なくなります(ページフォールト= 1,000〜2,000万CPUサイクル)
- 必要なTLBエントリが少なくなり、TLBミスが少なくなります(TLBミス= 50〜500サイクル)
密にパックされた数ギガバイトのSoAデータを直線的に処理することは、レイアウトやパッキングが不適切な単純な方法で同じことを行うよりも3桁速くなります(ページフォールトが関係している場合は8〜10桁速くなります)。
個々の4バイトまたは2バイトの値(たとえば、標準int
または)を2バイトまたは4バイトに手動で調整するかどうかはshort
、最近のIntel CPUではごくわずかな違いになります(ほとんど目立たない)。これまでのところ、それを「最適化」したくなるかもしれませんが、そうしないことを強くお勧めします。
これは通常、最も心配する必要のないものであり、コンパイラに任せて理解します。他の理由がない場合、ゲインはせいぜいわずかであるためですが、他のいくつかのプロセッサアーキテクチャでは、間違った場合に例外が発生します。したがって、賢くなりすぎた場合、他のアーキテクチャでコンパイルすると、突然、説明のつかないクラッシュが発生します。それが起こったとき、あなたは気の毒に思うでしょう。
もちろん、処理するデータが少なくとも数十メガバイトない場合は、まったく気にする必要はありません。