2

三角行列を表す非常に大きな配列にメモリを割り当てる必要があります。私は次のコードを書きました:

const int max_number_of_particles=20000;
float **dis_vec;

dis_vec = new float **[max_number_of_particles];

for (i = 0; i<max_number_of_particles; i++)
  dis_vec[i] = new float *[i];

for (i = 0; i<max_number_of_particles; i++)
  for (j = 0; j<i; j++)
    dis_vec[i][j] = new float[2];

問題は、マトリックスのサイズが大きくなると、(メモリを割り当てるために)それを実行するのに必要な時間が急速に長くなることです。誰かがこの問題のより良い解決策を知っていますか?

ありがとう。

4

2 に答える 2

5

1 次元配列を割り当て、インデックスを添え字に、またはその逆に変換します。割り当てと比較して、1 つの割り当てO(N)ははるかに高速です。

編集

具体的には要素を割り付けて、本来N(N+1)/2アクセスしたいときは代わりにアクセスするだけ。[r][c][r*(r+1)/2 + c]

于 2010-11-23T14:35:26.877 に答える
0

はい。

まず...内側のループから始めます。

「新しいフロート[2]」

それは配列を割り当てますが、たまたま2つのフロートを持つ固定サイズのオブジェクトよりも割り当てが遅いと思います。

struct Float2D { float a; フロート b; };

x = 新しい Float2D;

その方が良さそうです。

しかし、本当に、それをすべて忘れてください。速くしたい場合は...たくさんのフロートをmallocするだけです。

私は言いたい...いくつかのフロートを無駄にしましょう。単純な古い 2D 配列を割り当てるだけです。

float* f = (float*)malloc( max_number_of_particles*max_number_of_particles*2*sizeof(float) );

これを克服できる唯一のサイズ節約は、正方形の代わりに三角形を使用することによる 2 倍のサイズ節約です。

しかし、「new float[2]」と「new float *[i];」を使用して、「サイズの節約」全体をすでに殺したに違いありません。「new」のオーバーヘッドがどれくらいかはわかりませんが、malloc のようなものだと思います。また、ほとんどの malloc には、割り当てごとに約 8 バイトのオーバーヘッドがあると思います。

したがって、あなたがすでに持っているものは、正方形を割り当てることによって失われた 2 倍のサイズよりも悪いです。

また、それは数学をより簡単にします。ポインターを取得するには、奇妙な「三角数」の計算を行う必要があります。(n+1)*n/2 のようなものか、それが何であれ :)

于 2010-11-23T14:38:54.250 に答える