私はこれが例で最もよく説明されていると思います。これらの地域の原則は、物を最適化するためによく使われます。現代のCPUの可能なコンポーネントはメモリプリフェッチャです。メモリプリフェッチャは、使用するメモリを推測し、必要なときにキャッシュに格納します。これは、地域の原則に大きく依存しています。あなたは、この(C++の例)のような何かを行う場合
は、例えば配列を取る:
#include <iostream>
#include <vector>
int main()
{
std::vector<int> test = { 1, 2, 3, 4, 5};
for(int& i: test)
{
std::cout << i << std::endl;
}
}
ベクトルで
(または配列を他の言語で)要素は、固定された進歩と連続したブロックにパックされています。したがって、test
の最初の要素がアドレスX
にある場合、2番目の要素はX+Y
になり、3番目の要素はX+2Y
,...
になります。したがって、ベクトルそのものは空間的局所性の非常に基本的な例であり、局所性は非常に予測可能です。 次に、エレメントがタイトループでアクセスされるため、良い時間的空間性も持っています。要素は順次アクセスされるため、「時空」には等間隔の空間性があります。これは、CPUがX+Y, X+2Y, X+3Y
パターンのintを認識するとすぐに、キャッシュ内の将来の要素を引き出すことを開始できることを意味します。
あなたは、たとえばでこれを対比することができます
#include <iostream>
#include <list>
int main()
{
std::list<int> test = { 1, 2, 3, 4, 5};
for(int& i: test)
{
std::cout << i << std::endl;
}
}
をリンクリストでは、要素がお互いを参照してください、そして、あなたの空間的局所性を失うので、個々の要素は、メモリ内の任意の場所ですることができます。しかし、ループ内の要素にアクセスするので、あなたは一時的な空間性を保ちます。このようなものは、プリフェッチを検出して最適化するのが非常に難しくなります(ただし不可能ではありません)。
最後に、複合時空空間性が重要である理由指標として、この(少し不自然)の例を検討:あなたは純粋にtest
コンテナを見れば
#include <iostream>
#include <vector>
#include <algorithm>
#include <random>
#include <iterator>
int main()
{
std::vector<int> test = { 1, 2, 3, 4, 5 };
std::vector<unsigned int> indices = { 0, 1, 2, 3, 4 };
std::random_device rd;
std::shuffle(std::begin(indices), std::end(indices), std::mt19937 { rd() });
for (unsigned int& i : indices)
{
std::cout << test[i] << std::endl;
}
}
を、それは再び良い空間的局所性を持っていた(のようなストライド最初の例)。ループ内のtest
アクセスを見ると、ルックアップに時間的局所性があることがわかります。しかし、「タイムスペース」では、配列のある部分から別の部分にジャンプするときにルックアップが等距離にならず、アクセスは順次的ではないので、空間と時間の両方に等間隔の空間性はありません。これは最適化することはほとんど不可能です。
私の最高の推測:誰かが小便を取っていた。 –
if(answer_found)edit(wiki_page); else edit(wiki_talk_page); – thecoshman
私はこれを見つけました:http://cs.gmu.edu/cne/pjd/PUBS/CACMcols/cacmJul05.pdf –