web-dev-qa-db-ja.com

アレイのパフォーマンスにとってキャッシュの局所性が重要なのはなぜですか?

次の blog には、リンクリストに対する配列の利点に関する記述があります。

配列のキャッシュの局所性が向上しているため、パフォーマンスが大幅に向上します。

どういう意味ですか?キャッシュの局所性がパフォーマンスの大きなメリットをどのように提供できるのか理解できません。

55
Vaibhav Mishra

私の答えを参照してください 空間的および時間的局所性について

特に、配列は連続したメモリブロックであるため、配列の大部分は最初のアクセス時にキャッシュにロードされます。これにより、配列の将来の要素に比較的すばやくアクセスできます。一方、リンクリストは必ずしも連続したメモリブロックにあるとは限らず、キャッシュミスが多くなる可能性があり、アクセスに時間がかかります。

大きな構造体の配列dataおよびリンクリストl_dataの次のメモリレイアウトを検討してください。

Address      Contents       | Address      Contents
ffff 0000    data[0]        | ffff 1000    l_data
ffff 0040    data[1]        |   ....
ffff 0080    data[2]        | ffff 3460    l_data->next
ffff 00c0    data[3]        |   ....
ffff 0100    data[4]        | ffff 8dc0    l_data->next->next
                            | ffff 8e00    l_data->next->next->next
                            |   ....
                            | ffff 8f00    l_data->next->next->next->next

この配列をループする場合、ffff 0000への最初のアクセスでは、メモリにアクセスして取得する必要があります(CPUサイクルでの非常に遅い操作)。ただし、最初のアクセス後、アレイの残りの部分はキャッシュ内にあり、後続のアクセスははるかに高速になります。リンクリストを使用すると、ffff 1000への最初のアクセスでもメモリにアクセスする必要があります。残念ながら、プロセッサはこの場所を直接囲むメモリをキャッシュします。つまり、ffff 2000まで続きます。ご覧のとおり、これはリストの他の要素を実際にはキャプチャしません。つまり、l_data->nextにアクセスするときは、再びメモリに移動する必要があります。

81
brc

通常、配列を使用する場合、互いに近いアイテムにアクセスします。これは、配列に順番にアクセスする場合に特に当てはまります。

メモリにアクセスすると、そのチャンクがさまざまなレベルでキャッシュされます。 キャッシュの局所性は、連続した操作がキャッシュ内に存在する可能性が高いため、高速になることを意味します。配列では、キャッシュ内にシーケンシャル要素アクセスの可能性を最大化します。

リストでは、反例として、リストに順番に表示されるアイテムがメモリ内で互いに近くに実際に配置されるという保証はありません。これは、キャッシュヒットが少なくなり、パフォーマンスが低下することを意味します。

7
paddy