4

これは繰り返しの質問かもしれません。そのため、必要に応じて気軽にフラグを立ててください。C++で、配列の次元がメモリに連続して格納されることを学びました C では3D 配列はどのように格納されますか? そこで、サイズ 1600000000x1 と 1x1600000000 の行列に自然数を割り当てる実験を少し行いました (matsizeメモリに応じて、コードをより小さな値に変更してください)。以下のコードは、1 から 1600000000 までの自然数を行列a(次元は 1x1600000000) に割り当て、すべての要素の立方体の合計を計算します。xdim反対のケースは、1 に変更しmatsizeydimコードを再コンパイルして再度実行することで、行列の次元を逆にするだけです。行列は[xdim][ydim]

#include <iostream>
#include <time.h>
using namespace std;
int main()
{
long int matsize, i, j, xdim, ydim;
long double ss;
double** a;
double time1, time2, time3;
clock_t starttime = clock();    
matsize=1600000000;
xdim=1;
ydim=matsize;   
ss=0.0;    
a= new double *[xdim];
for(i=0;i<xdim;i++)
{
    a[i]= new double[ydim];
}

time1= (double)( clock() - starttime ) / (double)CLOCKS_PER_SEC;    
cout << "allocated. time taken for allocation was " << time1 <<" seconds. computation started" << endl;    
for(i=0;i<xdim;i++)
{
    for(j=0;j<ydim;j++)
    {
        a[i][j]=(i+1)*(j+1);
        ss=ss+a[i][j]*a[i][j]*a[i][j];
    }
}
cout << "last number is " << a[xdim-1][ydim-1] << " . sum is " << ss << endl;
time2= ((double)( clock() - starttime ) / (double)CLOCKS_PER_SEC) - time1;
cout << "computation done. time taken for computation was " << time2 << " seconds" << endl;    
for(i=0;i<xdim;i++)
{
    delete [] a[i];
}
delete [] a;   
time3= ((double)( clock() - starttime ) / (double)CLOCKS_PER_SEC) - time2;
cout << "deallocated. time taken for deallocation was " << time3 << " seconds" << endl;    
cout << "the total time taken is " << (double)( clock() - starttime ) / (double)CLOCKS_PER_SEC << endl;
cout << "or " << time1+time2+time3 << " seconds" << endl; 
return 0;
}

2つのケースの私の結果は -

ケース 1: xdim=1 および ydim=1600000000

割り当てられます。割り当てにかかった時間は 4.5e-05 秒でした。計算が開始された最後の番号は 1.6e+09 です。sum は 1.6384e+36 計算済みです。計算にかかった時間は 14.7475 秒で、割り当てが解除されました。割り当て解除にかかった時間は 0.875754 秒でした かかった合計時間は 15.6233 または 15.6233 秒です

ケース 2: xdim=1600000000 および ydim=1

割り当てられます。割り当てにかかった時間は 56.1583 秒でした。計算が開始された最後の番号は 1.6e+09 です。sum は 1.6384e+36 計算済みです。計算にかかった時間は 50.7347 秒で、割り当てが解除されました。割り当て解除にかかった時間は 270.038 秒でした かかった合計時間は 320.773 または 376.931 秒です

出力合計はどちらの場合も同じです。どちらの場合もメモリの割り当てと解放にかかる時間が異なることは理解できますが、メモリの割り当てが連続している場合、計算時間もなぜそれほど異なるのでしょうか? このコードのどこが間違っていますか?

問題があれば、Mountain Lion で g++ を使用しており、g++ -std=c++11、i7 クアッド コア プロセッサ、16 GB RAM を使用してコンパイルしています。

4

2 に答える 2