いつも利用させてもらって助かっています。
あるプログラムを作成しているのですが、ファイル入力の部分がネックとなってしまって、全体が使いものにならない状況に陥っています。
たくさんのデータを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も見ています
-
新NISA制度は今までと何が変わる?非課税枠の拡大や投資対象の変更などを解説!
少額から投資を行う人のための非課税制度であるNISAが、2024年に改正される。おすすめの銘柄や投資額の目安について教えてもらった。
-
ファイルへの書込み処理が異常に遅い
C言語・C++・C#
-
C言語におけるファイル読み込みor書き込みの高速化がうまくいかない
C言語・C++・C#
-
1行ずつではなくまとめてファイル出力したいのですが
C言語・C++・C#
-
-
4
fopne で失敗する原因
C言語・C++・C#
-
5
C言語 配列の長さの上限
C言語・C++・C#
-
6
CStringのFindで文字列検索を行いたいのですが
C言語・C++・C#
-
7
<unistd.h>をVisualStudioでつかえるようにする
C言語・C++・C#
-
8
fopenでのパス指定
C言語・C++・C#
-
9
C言語で、メモリを解放しないで終わるプログラム
C言語・C++・C#
-
10
C言語 ファイルの指定された行を表示
C言語・C++・C#
-
11
WaitForSingleObjectの使い方について
C言語・C++・C#
-
12
DWORDの実際の型は何でしょうか
C言語・C++・C#
-
13
C++ 構造体の一括初期化 {0}
C言語・C++・C#
-
14
c言語でcsvファイルの処理で、処理速度が速いプログラムを書こうと思っ
C言語・C++・C#
-
15
C言語のfopenについて教えてください。
C言語・C++・C#
-
16
ファイル書込みで一行もしくは部分的に上書きする
PHP
-
17
大量のデータを読み込んで表示する速度を改善したい
C言語・C++・C#
-
18
C言語---ファイルに出力したデータをすべて消去する方法
C言語・C++・C#
-
19
ファイルの結合
C言語・C++・C#
-
20
fopenで別ディレクトリにファイルをオープンしたい
C言語・C++・C#
関連するカテゴリからQ&Aを探す
おすすめ情報
このQ&Aを見た人がよく見るQ&A
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
c言語でのfscanfについて
-
複数ファイルの同時読み込みの...
-
C言語にてXMLファイルから任意...
-
ファイルへの書込み処理が異常...
-
datファイルの読み込み
-
【C言語】ファイルを読み込んで...
-
fscanfで格納された変数がおか...
-
VisualStudioでのファイルの入...
-
ファイル出力で改行を入れたい!
-
同時にファイル読み込み 書き込み
-
差分ファイルを読み込んで解析する
-
テキストファイル内に対して, ...
-
ガンマ変換 C言語でプログラ...
-
C言語でファイル名を変数にした...
-
C言語でのCSVソートとデータ抽...
-
ファイル読み込み EOF 判定
-
fopenでファイル名に、変数を使...
-
テキストを一文字以上ずつ読み...
-
自己相関関数を求めるプログラ...
-
C言語のファイル入出力の問題です
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
複数ファイルの同時読み込みの...
-
ファイルへの書込み処理が異常...
-
C言語でファイル読み書きを早く...
-
c言語でのfscanfについて
-
fopenでファイル名に、変数を使...
-
ファイル出力で改行を入れたい!
-
C言語にてXMLファイルから任意...
-
CRC32の計算方法
-
fgets( ) の返り値は何?
-
InternetReadFileを使ったファ...
-
【C言語】ファイルを読み込んで...
-
VisualStudioでのファイルの入...
-
commons-netでのFTP送信について
-
日本語ファイル名のFTPについて
-
fgets関数の利用 c言語
-
C言語でコマンドmvを実行
-
「コマンドライン引数チェック...
-
C言語でセグメンテーションエ...
-
構造体のメンバにファイルポイ...
-
エラー C2664
おすすめ情報