いつも利用させてもらって助かっています。
あるプログラムを作成しているのですが、ファイル入力の部分がネックとなってしまって、全体が使いものにならない状況に陥っています。
たくさんのデータをfread1回で読み込むことにより、読み込み速度はずいぶんと改善されましたが、まだ圧倒的に遅い状況です。システムコールを使いましたが、ほとんど改善されませんでした。
読み込み/書き込みの速度を改善する方法として,SSDメモリを使ったりする方法があると思いますが,プログラムの観点から改善できるところはないでしょうか?
下に、ファイル読み込みの部分だけ記述したコードを添付させて頂いたので、改善できる点があれば、御指摘頂けると助かります。
なお、前提として,
(1)データはスタック領域だと不足するので、ヒープ領域に確保
(2)データファイルは改行無しの一連のデータ
とします。
ちなみに、環境は
OS : CentOS5.3
memory : 6GB
コンパイラ : gcc
です。
よろしくお願いします。
//-----------------------------------------------------
//通常バージョン
#include <stdio.h>
#include <stdlib.h>
#define SIZE (512*1024*1024) //500MB
int main(void)
{
unsigned long int i;
unsigned char *data;
FILE *fp;
data = (unsigned char *)malloc(SIZE);
if(data == NULL) {
printf("メモリが確保できません\n");
exit(EXIT_FAILURE);
}
fp = fopen("filein.dat", "rb");
fread( data, sizeof( unsigned char), (int)SIZE, fp );
fclose(fp);
/*
//表示
for( i=0; i<SIZE; i++ ){
printf("%2x", data[i]);
}
puts("");
*/
fp = fopen("fileout.dat", "w");
fwrite( data, sizeof( unsigned char), (int)SIZE, fp);
fclose(fp);
free(data);
return 0;
}
//-----------------------------------------------------
//readシステムコールを使ったバージョン
#include <stdio.h>
#include <stdlib.h>
#define SIZE (512*1024*1024) //500MB
int main(void)
{
unsigned long int i;
unsigned char *data;
data = (unsigned char *)malloc(SIZE);
if(data == NULL) {
printf("メモリが確保できません\n");
exit(EXIT_FAILURE);
}
int fd;
fd = open( "filein.dat" );
read( fd, data, sizeof(unsigned char)*SIZE);
close(fd);
/*
//表示
for( i=0; i<SIZE; i++ ){
printf("%2x", data[i]);
}
puts("");
*/
FILE *fp;
fp = fopen("fileout.dat", "w");
fwrite( data, sizeof( unsigned char), (int)SIZE, fp);
fclose(fp);
free(data);
return 0;
}
No.3ベストアンサー
- 回答日時:
>「まだ圧倒的に遅い状況」と申し上げましたのは、
>全体の処理に対してファイルの読み書きが占める割合が
>50%以上を占めてしまっている、ということです。
ディスク入出力処理に時間がかかるコト、そんなにおかしいですかね。
入出力に時間がかかるのは、常識だと思うのですが。
入出力性能要件を全体処理に対する割合で算出することがナンセンスに思えます。
確認なんですが、質問タイトルは「読み書きを早くしたい」、
本文は「ファイル入力の部分がネックとなってしまって」
とありますが、問題視されているのは、読み込みですか?
>500MB / 0.256s = 1953MB/s ≒ 1.9GB/s
500MBを0.256秒で読み込めているのが異常に速くて、にわかには信じがたいです。
OSがファイルをキャッシュして、メモリ上に蓄えてるんじゃないですか?
>ちなみに、RAMディスク
キャッシュ vs RAMディスクだとすると、どちらも同じRAM上なので、
速度は同程度になるような気がします。
PCを再起動して1回目の計測だと10秒ぐらいかかったりしませんか?
読み込み速度の基準は、デバイスのベンチマークテストなどを行って、
それを基準にしたほうがいいと思います。
No.6
- 回答日時:
んで結局入力情報をどうしたいのでしょう?
サンプルを見た限りでは特に問題点はなさそうですね。
ロジック的に効率の悪い処理をしていませんかね。
ファイルIO関係で遅くなるケースの良くあるパターンは
1. バッファリングなしで少しずつ読み書きしている
2. ファイルのオープンクローズ回数が多い
3. ロック待ち
それぞれの解決方法は
1.は read/write を fread/fwrite に変更して setvbuf にて大きなバッファリング領域を確保してあげる
変更後はフラッシュのタイミングに注意が必要です。dsyncとかね
2.はロジックの見直しもありますし、オープンしたファイルハンドルをキャッシュするなんていう手もあります
プロセスごとオープンできるファイル数には限界があるので超えないようにする必要があります
特にファイルのクローズはコストが大きいです。
3.はどうしようもないですね。
おそい、おそい、いうだけじゃなんの解決もできませんよ。
物量的な統計情報をださないと、おそいのがどのくらい遅いのかわからないです。
たとえば、30分以内に終わるべきものが2時間かかってしまうとか
#まぁここまでくるとさすがにIOじゃなくでアルゴリズムが悪いのでしょうけど。
No.5
- 回答日時:
mmap (ないし MapViewOfFile) というのは既に提案してるんだけどね>#4.
あるいは, バッファリングを禁止してから fread なり read でいいのかもしれない.
参考URL:http://oshiete1.goo.ne.jp/qa5563519.html
No.2
- 回答日時:
>まだ圧倒的に遅い状況
抽象的な表現ですな。
ハードの限界点を見極めてからソフトがそれに近づくというのが基本ではないですかな。
今、貴方のソフトはハードの力を何%ぐらい引き出せているのでしょう。
100%近く引き出しているなら、ソフトの力でそれを引き上げるのは無理です。
http://www.cc.u-tokyo.ac.jp/publication/news/VOL …
この回答への補足
「まだ圧倒的に遅い状況」と申し上げましたのは、
全体の処理に対してファイルの読み書きが占める割合が50%以上を占めてしまっている、ということです。
ちなみにファイル読み書きの部分のみ取り出して実行時間を調べてみたら約500MBのデータに対し、0.256sで、
I/Oスピードは
500MB / 0.256s = 1953MB/s ≒ 1.9GB/s
でした。
ちなみに、RAMディスク
http://itpro.nikkeibp.co.jp/article/Keyword/2007 …
を使ってメモリ領域にファイルを置いてアクセスしてみても上記のI/Oスピードとほとんど変わりませんでした(こうなった理由がさっぱりわかりません)。
ちなみに、紹介して頂いたページのpdfも参考にして、
setvbuf(fp,NULL,_IOFBF, 512*1024*1024);
のようにバッファサイズを変えてみたりしたのですが、まったく変わりませんでした。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- C言語・C++・C# c言語の問題の説明、各所ごとに 5 2023/07/26 11:03
- C言語・C++・C# このプログラミング誰か教えてくれませんか 1 2022/06/02 15:27
- C言語・C++・C# プログラミングの授業の課題です 1 2023/01/17 22:15
- C言語・C++・C# 10個の実数に対する降順ソート結果を出力するプログラムを作りたいのですが、以下のプログラムをどう直せ 1 2022/07/09 22:16
- C言語・C++・C# バイナリファイルをコピーするのにかかる時間を測りたいのですが実行するとFatel error:gli 2 2022/11/03 01:10
- C言語・C++・C# c言語の問題です 課題1 (二分探索木とセット) 大きさ size の配列 array を考える。す 2 2023/01/10 21:08
- C言語・C++・C# 宣言する関数の形が決まっている状態で、 str1とstr2の文字列をこの順に引っ付けてstrに保存し 2 2022/05/30 18:21
- C言語・C++・C# leetcode 155 minstack 1 2022/05/07 16:43
- C言語・C++・C# カードシャッフルのブログラムを使ってc言語でブラックジャックをしたい 2 2022/04/12 15:13
- C言語・C++・C# アセンブラ指令 3 2023/06/17 14:47
このQ&Aを見た人はこんなQ&Aも見ています
-
プロが教えるわが家の防犯対策術!
ホームセキュリティのプロが、家庭の防犯対策を真剣に考える 2組のご夫婦へ実際の防犯対策術をご紹介!どうすれば家と家族を守れるのかを教えます!
-
ファイルへの書込み処理が異常に遅い
C言語・C++・C#
-
C言語におけるファイル読み込みor書き込みの高速化がうまくいかない
C言語・C++・C#
-
1行ずつではなくまとめてファイル出力したいのですが
C言語・C++・C#
-
-
4
CStringのFindで文字列検索を行いたいのですが
C言語・C++・C#
-
5
fopenでのパス指定
C言語・C++・C#
-
6
fopne で失敗する原因
C言語・C++・C#
-
7
C言語 配列の長さの上限
C言語・C++・C#
-
8
C言語で、メモリを解放しないで終わるプログラム
C言語・C++・C#
-
9
<unistd.h>をVisualStudioでつかえるようにする
C言語・C++・C#
-
10
C言語のfopenについて教えてください。
C言語・C++・C#
-
11
CString型 全角半角を意識せずに「1文字」ずつ取り出す
C言語・C++・C#
-
12
大量のデータを読み込んで表示する速度を改善したい
C言語・C++・C#
-
13
画面を強制的に再描画させる方法
C言語・C++・C#
-
14
ラジオボタンのグループ化
C言語・C++・C#
-
15
fopenで別ディレクトリにファイルをオープンしたい
C言語・C++・C#
-
16
WaitForSingleObjectの使い方について
C言語・C++・C#
-
17
ファイル内のデータを1行削除する方法
C言語・C++・C#
-
18
Enterキーを押されたら次の処理に移るという事をしたい。
C言語・C++・C#
-
19
c言語でcsvファイルの処理で、処理速度が速いプログラムを書こうと思っ
C言語・C++・C#
-
20
配列の要素数に変数を入れたいときには
C言語・C++・C#
関連するカテゴリからQ&Aを探す
このQ&Aを見た人がよく見るQ&A
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
C言語でファイル読み書きを早く...
-
複数ファイルの同時読み込みの...
-
ファイル出力で改行を入れたい!
-
【C言語について】ファイル名の...
-
C言語でセグメンテーションエ...
-
テキストファイル内に対して, ...
-
fread()エラー
-
C言語におけるファイル読み込み...
-
初心者のc言語
-
音声データを出力するCプログラ...
-
急!【数列のヒストグラム作成...
-
c言語による画像処理について
-
CSVファイルの内容を構造体に格...
-
ファイルに行番号を追加
-
fopenの追記モードについて
-
test.csvの内容
-
C言語でファイルの内容を strto...
-
VisualStudioでのファイルの入...
-
c言語でのfscanfについて
-
同時にファイル読み込み 書き込み
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
ガンマ変換 C言語でプログラ...
-
c言語でのfscanfについて
-
なぜCSQとCIP形式ではコ...
-
複数ファイルの同時読み込みの...
-
fopenでファイル名に、変数を使...
-
ファイル出力で改行を入れたい!
-
ファイルへの書込み処理が異常...
-
【C言語】ファイルを読み込んで...
-
エラーがわかりません、、
-
C言語でセグメンテーションエ...
-
C言語でファイル読み書きを早く...
-
テキストファイル内に対して, ...
-
fgets( ) の返り値は何?
-
ファイルに行番号を追加
-
OpenGLによる描画内容をBMP出力
-
fscanfでループしてしまう。
-
c言語 ファイルから数字を読み...
-
ファイルが読み込めない・・・
-
CRC32の計算方法
-
CSVファイルの内容を構造体に格...
おすすめ情報