プロが教える店舗&オフィスのセキュリティ対策術

以下のプログラムは値を3倍し、また画像サイズを変えてコピーする時間を測定するというものです。
測定方法はgcc -Wall -o2 -DCSQ(DCIP) ファイル名でコンパイルし、time a.outで消費時間を測定しました。

画像サイズは10,20,50,100,200,500,1000,2000,5000,10000と変えていきました。

データ形式をCSQ(Channel Sequential)とCIP(Channel Interleaved)のそれぞれについて実行してみたのですが、
なぜ実行結果に違いがでたのか解りません。ネットで調べてみましたが、見つかりませんでした。
キャッシュ(書き換え)やスワップ領域などが関係しているのでしょうか?また他にも疑問がありますので回答してくだされば幸いです。

(1)CSQとCIP形式ではなぜ違いが出るのか?
(2)ループの順番を最も内側(k)のfor文を一番外側に移動(k,i,j)した場合はなぜ違いが出るのか?
(3)ポインタを利用したコピーではなぜ違いが出るのか?



#include <stdio.h>
#include <stdlib.h>
#include <math.h> //mathライブラリを利用する場合はコンパイル時に -lm

#define MAX_REPEAT 1000 //コピー繰り返し回数
#define SIZE 500 //画像サイズ(行=列)

#ifdef CSQ
#define DIM1 3
#define DIM2 SIZE
#define DIM3 SIZE
#endif
#ifdef CIP
#define DIM1 SIZE
#define DIM2 SIZE
#define DIM3 3
#endif

typedef unsigned char UCHAR;

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


/* 画像のコピー */
void copy3dimg(UCHAR res[][DIM2][DIM3],UCHAR org[][DIM2][DIM3],int dim1,int
dim2,int dim3)
{
int i,j,k;

for(i=0;i<dim1;i++)
for(j=0;j<dim2;j++)
for(k=0;k<dim3;k++)
res[i][j][k]=org[i][j][k]*3;
}


int main(void)
{
int repeat;

UCHAR org[DIM1][DIM2][DIM3]; /* 作成画像 */
UCHAR res[DIM1][DIM2][DIM3]; /* コピー先画像 */

/* 画像の作成 */
{
int i,j,k;

for(i=0;i<DIM1;i++)
for(j=0;j<DIM2;j++)
for(k=0;k<DIM3;k++)
org[i][j][k]=(UCHAR)((i*j+10*j+k*k)%256);
}

/* 画像のコピー */
for(repeat=0;repeat<MAX_REPEAT;repeat++)
copy3dimg(res,org,DIM1,DIM2,DIM3);

/* ファイルへの出力 */
#ifdef CSQ
write_ppm_csq(res,"./tmp.ppm",DIM3,DIM2);
#endif
#ifdef CIP
write_ppm_cip(res,"./tmp.ppm",DIM2,DIM1);
#endif

return 0;
}


/* ファイルへの出力(CSQ) */
void write_ppm_csq(UCHAR data_buf[][DIM2][DIM3],char *fname,int width,int
height)
{
FILE *fp;
int m, n;

if((fp = fopen(fname, "wb")) == NULL) {
fprintf(stderr, "file(%s) can't open\n", fname) ;
exit(1) ;
}

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

for(m=0;m<height;m++)
for(n=0;n<width;n++)
{
fwrite(&data_buf[0][m][n], sizeof(UCHAR), 1, fp);
fwrite(&data_buf[1][m][n], sizeof(UCHAR), 1, fp);
fwrite(&data_buf[2][m][n], sizeof(UCHAR), 1, fp);
}

fclose(fp) ;
}

/* ファイルへの出力(CIP) */
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) ;
}

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

fwrite(&data_buf[0][0][0], sizeof(UCHAR), width*height*3, fp);

fclose(fp) ;
}

/* エラー処理 */
void error1(char *message)
{
printf("%s\n",message);
exit(1);
}


/***ポインタ利用コピーの場合***/

/* 画像のコピー */
void copy3dimg_point(UCHAR res[][DIM2][DIM3],UCHAR org[][DIM2][DIM3],int
dim1,int dim2,int dim3)
{
int i;
int imax=dim1 * dim2 * dim3;
UCHAR *pres=&res[0][0][0];
UCHAR *porg=&org[0][0][0];

for(i=0;i<imax;i++)
 *pres++ = *porg++;

}
/* 画像のコピー */
for(repeat=0;repeat<MAX_REPEAT;repeat++)
copy3dimg_point(res,org,DIM1,DIM2,DIM3);

A 回答 (2件)

> よろしければ、CSQとCIP形式とは何か教えていただけませんか?


> 仕組みの違いが解りません。

え~~~~,それも知らないまま質問してたんですか?
私も初耳だったからさっき調べて知ったばかりなんですが.

VHDLによる画像フィルタ回路の設計
http://www.kochi-tech.ac.jp/library/ron/2001/ele …
→ 画像のデータ表現 (pp.15~16)
    • good
    • 0
この回答へのお礼

大変参考になりました。ありがとう御座いました。

お礼日時:2007/06/09 14:39

> time a.outで消費時間を測定しました。


> なぜ実行結果に違いがでたのか解りません。

実行結果も書かないと,誰も説明できません.
(思いこみでどっちがなぜ速いかを説明しても,実際の結果は逆だった,
 というオチもありえますし.(笑))

また,今の測定方法だと,画像の作成・コピー・ファイル出力の時間配分が
わからないので,time(7) ではなく,getrusage(2) や gettimeofday(2)
などでそれぞれの時間を測定した方がいいと思います.


> データ形式をCSQ(Channel Sequential)とCIP(Channel Interleaved)
> のそれぞれについて実行してみたのですが、なぜ実行結果に違いがでたのか解りません。

ディスクアクセスまで含めた実行時間ということであれば,
CSQ と CIP のどちらを先に実行したかによって異なる可能性もあります.
初回と2回目以降では,"./tmp.ppm" の情報がディスクキャッシュに
入っているか否かにより違いが出ると思われるので.

それを防ぐには,(CSQ または CIP) → CIP → CSQ と実行させて,
最初の結果を無視するのも1つの手だと思います.

この回答への補足

解説ありがとう御座います。
よろしければ、CSQとCIP形式とは何か教えていただけませんか?
仕組みの違いが解りません。

補足日時:2007/06/03 18:05
    • good
    • 0

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