C言語関係掲示板

過去ログ

No738 数百MBの大規模な配列を使いたい

[戻る] [ホームページ]
No.9114

数百MBの大規模な配列を使いたいのですが
投稿者---v__v(2003/08/29 14:26:03)


はじめまして、よろしくお願いします。
C言語は経験年数は長いのですが、それほど詳しくなく、ここ数日悩んでおり、お助け頂けないでしょうか。

 本題ですが、500MB、200MBなどの大きな配列(メモリ領域)を確保し、データを入れてソート等をした後、ファイル出力をしてデータファイルを完成させたいのですが、スタテック領域で18MBほどしか確保できず、困っております。何か良い方法はありますでしょうか?
 マロックも試しましたが、ダメで18MB程度まで。
開発環境かOSの設定が悪いのかとも思っています。

 現状は、HDD上にファイルを書き出し、この操作で実現を検討しておりますが、ものすごい処理時間を要すと見られ、できればPCのメモリ上で実現したいのですが。 
環境は、WIN2000,メモリ1GB、C++ビルダー5です。

初心者的な基本が分かっていない質問かもしれませんがよろしくお願いします。

No.9115

Re:数百MBの大規模な配列を使いたいのですが
投稿者---ひかる1977(2003/08/29 16:01:07)


ポインタのポインタを利用すれば、もっといけると思います。
各データ項目毎に領域を確保してから、ソートを行えば良いと思います。

ただ、200MB〜500MBまで行けるかどうかは不明ですが、
以前にmallocのみでは失敗する領域のとき、
1行毎に領域を確保したら何とかなりました。



No.9116

Re:数百MBの大規模な配列を使いたいのですが
投稿者---あかま(2003/08/29 16:33:15)


>1行毎に領域を確保したら何とかなりました。
たぶんこれでいけると思いますが、200Mものメモリを確保すると、
まず間違いなくHDD上に仮想メモリとして確保してしまいますので
高速処理のためにメモリ上だけで…というのは多分無理です。
前にハッシュを使いソートしたときにメモリを確保しすぎて逆に遅くなったことがあります。

メモリの消費を抑えるために、元のファイルを分割してはどうでしょうか?
例えば要素をアルファベット順に並べる時、
元ファイルから要素を読み出して、その頭文字が'a'のファイル、'b'のファイル…'z'のファイルと作っていきます。
その後ファイルごとにソートして、全てのファイルをアルファベット順にマージすれば元ファイルのソートができあがります。



No.9154

Re:数百MBの大規模な配列を使いたいのですが
投稿者---v__v(2003/09/02 12:47:21)


>メモリの消費を抑えるために、元のファイルを分割してはどうでしょうか?
>例えば要素をアルファベット順に並べる時、
>元ファイルから要素を読み出して、その頭文字が'a'のファイル、'b'のファイル…'z'のファイルと作っていきます。
>その後ファイルごとにソートして、全てのファイルをアルファベット順にマージすれば元ファイルのソートができあがります。

返事が遅れましたが、皆さん、アドバイスありがとうございます。
結局、分割して100個の個々にソートされたファイルを作成し、これを少しずつバッファリングして、大小比較をして、1つの統合ファイルに書き込むことで
目的を達成できました。
この時、何故かファイルは同時に22個までしか開けない問題にあたりました
が、順次バッファリングすることで回避しました。

ありがとうございました。


No.9169

Re:数百MBの大規模な配列を使いたいのですが
投稿者---たか(2003/09/02 20:38:12)


マージソートというのをご存じでしょうか?
これなら同時に開くファイル数を3個に抑えられます。(入力2個、
出力1個もしくは入力1個、出力2個)

バッファを全部ファイルに置くので速度的には遅くなるとお思いでしょ
うが、これが結構速くてnlog(n)、つまりクイックソートと同程度の
オーダーです。もちろんファイルの入出力によるオーバーヘッドが大きい
ので小さいデータですとメモリ上のバブルソートにも負けるでしょうが、
Nが大きくなるとかなり高速であることを私の所で実験して確かめてい
ます。

No.9177

Re:数百MBの大規模な配列を使いたいのですが
投稿者---ともじ(2003/09/03 00:41:14)


こんばんは。

>この時、何故かファイルは同時に22個までしか開けない問題にあたりました

同時にオープンできるファイルの数には上限があります。この数は
処理系により異なり、stdio.hのFOPEN_MAXで知ることができます。