dポイントプレゼントキャンペーン実施中!

以下のプログラムのサイズを変えて消費時間を測定しました。
ユーザバッファを使用した場合としなかった場合では(特にサイズが小さい場合)消費時間に差が出たのですが何故でしょうか?
プログラムの高速化に対してのユーザバッファの役割を教えていただきたいです。
よろしくお願いします。


測定結果
W_BYTE(サイズ)___ユーザバッファ使用(秒)___ユーザバッファ使用なし(秒)

10_______________0:02.75_____________________2:54.40
100______________0:01.55_____________________0:18.75
1000_____________0:01.40_____________________0:03.11
10000____________0:01.27_____________________0:01.33
100000___________0:01.12_____________________0:01.13
1000000__________0:01.11_____________________0:01.11
3000000__________0:01.10_____________________0:01.10



#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/time.h>
#include <unistd.h>

typedef unsigned char UCHAR;

#define DIM1 1000
#define DIM2 1000
#define DIM3 3

#define MAX_REPEAT 100 //出力繰り返し回数

void write_ppm_cip(UCHAR [][DIM2][DIM3],char *,int ,int );

UCHAR org[DIM1][DIM2][DIM3];

int main(void)
{
int i;
int dim1,dim2,dim3;

/***** 配列の初期化 *****/
for(dim1=0;dim1<DIM1;dim1++)
for(dim2=0;dim2<DIM2;dim2++)
for(dim3=0;dim3<DIM3;dim3++)
org[dim1][dim2][dim3]=(UCHAR)((dim1*200+dim2*dim2+dim3*dim3)%256);

for(i=0;i<MAX_REPEAT;i++)
{
write_ppm_cip(org,"/tmp/img.ppm",DIM1,DIM2);
// sleep(1); /* 一定時間待つ */
//system("/bin/sync"); /* ディスク上のデータをメモリと同期 */
}

return 0;
}

/* 一度に書き込むサイズ(バイト) */
//#define W_BYTE DIM1*DIM2*DIM3
#define W_BYTE 10

/* CIP形式の画像データよりPPMファイル作成 */
void write_ppm_cip(UCHAR data_buf[][DIM2][DIM3],char *fname,int
width,int height)
{
FILE *fp;

/* ファイルを開く */
if((fp = fopen(fname, "wb")) == NULL) {
fprintf(stderr, "file(%s) can't open\n", fname) ;
exit(1) ;
}

setvbuf(fp,NULL,_IONBF,0); /* ユーザバッファを使用しない場合,有効にする */

fprintf(fp, "P6\n") ; /* カラー画像かつバイナリーデータの記号 */
fprintf(fp, "%d %d\n", width, height) ; /* 画像の幅(列数)と高さ(行数) */
fprintf(fp, "255\n") ; /* 最大値 */


{ /* 画像データをrepeat(+1)個に分割して書き込み */
int i;
int repeat=(DIM1*DIM2*DIM3)/(W_BYTE); /* 分割数 */
int rest=DIM1*DIM2*DIM3-repeat*(W_BYTE); /* 余りデータ量 */
UCHAR *pt=(UCHAR *)&data_buf[0][0][0]; /* 書き込むデータの位置を持つポイ
ンタ */

for(i=0;i<repeat;i++)
{
fwrite(pt, sizeof(UCHAR), W_BYTE, fp);
pt += W_BYTE;
}
if(rest > 0)
fwrite(pt, sizeof(UCHAR), rest, fp);
}

fclose(fp); /* ファイルを閉じる.fflush()と同じ効果がある. */
}

A 回答 (1件)

fwrite関数は、何も指定しないと一度バッファ(メモリ)に貯めて、バッファが一杯になったらファイルを書き出します。


これは、メモリに比べて低速なハードディスクにアクセスする回数を減らすためにバッファリングしているわけです。
アクセス回数が増えるとどういう問題があるかというと、ハードディスクにアクセスしている間、プログラムは低速な処理が終わるのを待たされることになります。例えばアクセスで10ms待たされるとすると、10バイトx100回で1000バイトを書き出した場合1秒かかります。
これが100バイトx10回だと0.1秒しか必要ありません。

ですので、setvbufでバッファを無効にするとfwriteの毎にファイルを書き出すので小さいサイズほど遅くなります。
    • good
    • 0
この回答へのお礼

大変参考になりました。ありがとうございます。

お礼日時:2007/06/17 12:43

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!