画像処理プログラムと、処理速度について。

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
いちこ
記事: 62
登録日時: 13年前
連絡を取る:

画像処理プログラムと、処理速度について。

#1

投稿記事 by いちこ » 12年前

こんにちは。
本日もよろしくおねがいします。

今、1600*1600画素のRAW画像を読み込み、補正を行って書き出すプログラムを作成しています。
画像を読み込む配列の宣言、読み込み、処理、書き出しの速度の合計を測定しているのですが、疑問に思うことがあります。


1画素ずつ読み込んで、書き出す方式は、とても処理速度が遅かったので…
1600*1600画素の画像を、1600*1600個要素を持つ配列に、1枚いっきに読み込む方法の方が
1600画素を、1600個要素を持つ配列に、1600回読み込む方法よりも、処理速度が速いと予想していたのですが

gettimeofday関数を用いて、速度の測定を行ったところ、
前者は10回実行した平均が 16980マイクロ秒
後者は10回実行した平均は 15532マイクロ秒
となりました。
ほとんど差はありませんが、少し、1600回に分けて読み込んだ方が速いです。

これが、なぜだかわかりません。
なぜ
1600回<1回<1600*1600回 (読み込み)
となってしまうのでしょうか。

また、下のプログラムでは、buf,buf2をstaticの領域に確保していますが、
staticをはずして、stack領域に確保したところ、少しだけ速度が落ちてしまいました。
これも、stackのほうが速いと思っていたので、予想外の結果でした。

曖昧な質問で申し訳ありませんが、どなたか詳しい方がおられましたら、ご教示お願い致します。

下にソースコードを記します。
(コード全体は長いので、速度を測っている部分以外は割愛します。見たい部分がありましたらご指摘ください)

1600画素を1600回読み込み

コード:

  time_a=get_dtime();

  static unsigned char buf[1600];
  static unsigned char buf2[1600];


  for(i=0; i<1600; i++){ 
     fread(buf,1,1600,fp);
    
     for(j=0; j<1600; j++) buf2[j]=table[buf[j]];
    
    fwrite(buf2,1,1600,fp_adjusted);
  }

  
 time_b=get_dtime();

1600*1600画素を1回読み込み

コード:

  time_a=get_dtime();

  static unsigned char buf[1600*1600];
  static unsigned char buf2[1600*1600];


  fread(buf,1,1600*1600,fp);

  for(i=0; i<1600*1600; i++)  buf2[i]=table[buf[i]];

  fwrite(buf2,1,1600*1600,fp_adjusted);
  
  time_b=get_dtime();

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 15年前
住所: 東海地方
連絡を取る:

Re: 画像処理プログラムと、処理速度について。

#2

投稿記事 by softya(ソフト屋) » 12年前

ここらへんはOSやらCPUのアーキテクチャやらCPUキャッシュの性能で決まりますので、PCが変わる毎に計測結果が変わる可能性があります。
※ x86系CPUはCori7やら色々ありますが同じx86でもクロック以外に中身違うバージョンが色々とありますので多少の差では優位な方のが同じという計測結果は期待できません。

それとWindowsの場合は他プロセスの影響を受けますので、数十ms単位の誤差は当然のように生まれます。たぶん、何時間も測定しないと正しい結果は得られないです。

ちゃんと計測したいなら、
1.他のプロセスを出来るだけ止めること。
2.ネットも切断すること。
3.ウィルス対策ソフトも一時的に停止。
4.PCに触らす何時間も計測すること。
5.必ずリリースビルドすること。
あたりは最低限やってみてください。
ぜんぜん違う結果になる可能性があります。

【訂正】
gettimeofdayはLinuxですかね?
Linuxでも他のプロセスの影響を受けるので同じ事が言えます。

あとgettimeofdayの精度についても調べてみてください。
信頼度を調べるために標準偏差も取ってみたほうが良いでしょう。 ばらつきが大きいとあまり信用できません。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

いちこ
記事: 62
登録日時: 13年前
連絡を取る:

Re: 画像処理プログラムと、処理速度について。

#3

投稿記事 by いちこ » 12年前

>>softyaさん
返信ありがとうございます。
なるほどです。
今使っているのはUnixなのですが、1ミリ秒くらいの差は、いつもあるとは考えないほうがよさそうですね。
ということは、今、できるだけ速いプログラムを作りたいと思っているのですが
この処理の場合、どちらの方法で読み込んでも、メモリの領域がstackでもstaticでも大差ないということ、ですよね(><;)

ただ、一般にはstaticよりもstackのほうが、アクセス速度は速いということでいいのでしょうか。

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 15年前
住所: 東海地方
連絡を取る:

Re: 画像処理プログラムと、処理速度について。

#4

投稿記事 by softya(ソフト屋) » 12年前

>ただ、一般にはstaticよりもstackのほうが、アクセス速度は速いということでいいのでしょうか。

変わらないはずですが、アクセス頻度によりCPUのデータキャッシュの動作が変わっている可能性があります。
特定のCPUだけの個性かもしれませんので、何とも言えません。

【補足】
上にも書きましたが標準偏差も調べて見ることをオススメします。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

いちこ
記事: 62
登録日時: 13年前
連絡を取る:

Re: 画像処理プログラムと、処理速度について。

#5

投稿記事 by いちこ » 12年前

>>softyaさん
返信ありがとうございます。
そうなんですか!
てっきりstackのほうが速いものなのだと思い込んでおりました。気をつけます。

2つ前の返信も、詳しくしてくださってありがとうございます。
gettimeofdayはマイクロ秒の精度ですが、プログラムを実行して速度を測ったときのばらつきは大きかったです。
やはり、結果が欲しいなら厳密にしなければいけませんね。
標準偏差もとってみようと思います。

いちこ
記事: 62
登録日時: 13年前
連絡を取る:

Re: 画像処理プログラムと、処理速度について。

#6

投稿記事 by いちこ » 12年前

これでこのトピックは解決済みとさせていただきます。
softyaさん、ありがとうございました。

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 15年前
住所: 東海地方
連絡を取る:

Re: 画像処理プログラムと、処理速度について。

#7

投稿記事 by softya(ソフト屋) » 12年前

何処でも通用する高速化の方法として思いつくのは

・出来るだけOSに近い低水準な関数を使う。
・非同期で最適な頻度でファイルアクセスを行う。
・コンパイル・リンク時の最適化をスピード優先で最適化する。
・メモリに出来るだけランダムアクセスが発生しないように連続なアクセスを心がける。
・CPUキャッシュに収まる用に出来るだけデータバッファはコンパクト化する。
・バイトアクセスよりも4バイト単位のメモリアクセスを行う。
・コンパイラの出すアセンブラコードを眺めて無駄がないか検討する。

あたりででしょうか。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

いちこ
記事: 62
登録日時: 13年前
連絡を取る:

Re: 画像処理プログラムと、処理速度について。

#8

投稿記事 by いちこ » 12年前

>>softyaさん
返信ありがとうございます。

たくさんのアドバイスをありがとうございます!
参考にさせていただきます…!
またわからないことがあったとき、よろしくおねがいします。

閉鎖

“C言語何でも質問掲示板” へ戻る