0
#include <windows.h>

double PCFreq = 0.0;
__int64 CounterStart = 0;

void StartCounter()
{
    LARGE_INTEGER li;
    if(!QueryPerformanceFrequency(&li))
    cout << "QueryPerformanceFrequency failed!\n";

    PCFreq = double(li.QuadPart)/1000.0;

    QueryPerformanceCounter(&li);
    CounterStart = li.QuadPart;
}
double GetCounter()
{
    LARGE_INTEGER li;
    QueryPerformanceCounter(&li);
    return double(li.QuadPart-CounterStart)/PCFreq;
}

int main()
{
    StartCounter();
int i,j;
    static int x[4000][4000];
#if 1 //Version 1
    for (i = 0; i < 4000; i++) 
    {
        for (j = 0; j < 4000; j++) 
        {
            x[j][i] = i + j; 
        }
    }
#else //Version 2
    for (j = 0; j < 4000; j++) 
    {
        for (i = 0; i < 4000; i++) 
        {
            x[j][i] = i + j; 
        }
    }
#endif    
    cout << GetCounter() <<"\n";
    return 0;
}

Win7-32​​ビットマシンのVS2012で上記のコードを試しました。

バージョン 1 の実行時間は 0.200 秒で、バージョン 2 の実行時間は 0.071 秒です。

配列はメモリの連続した領域であり、C++ は配列を行優先方式で格納します。配列内の要素を要求すると、OS はおそらくその要素を含むメモリ ページをキャッシュに取り込みます。ただし、次のいくつかの要素もそのページにあるため (連続しているため)、次のアクセスはすでにVersion-1 のキャッシュに入っています。

したがって、バージョン 1 は高速でなければなりません。

しかし、結果は、バージョン 2 が高速であることを示しています。

結果が矛盾する理由を説明してください。

4

0 に答える 0