OpenCVのatとポインタと最適化に関する議論

誰しもが1度は通るアクセス速度に関する議論
4
Minagawa Takuya @takmin

色々なところで実験している人いるみたいだけど、僕も手元でOpenCVのMat::at()による画素アクセスとポインタによるアクセス比較してみたら、ほとんど処理時間に違いがなかった。デバッグモードだとat()は遅くなるけどね。

2011-08-07 00:13:27
無駄にツイッターIDが長い人 @ChaoticActivity

@takmin まさかとは思うけど「だからReleaseビルドだったらMat::at()でも十分高速だ」とか結論付けていないよね?

2011-08-07 00:30:32
無駄にツイッターIDが長い人 @ChaoticActivity

@takmin もしその実験結果だけから判断するならば「Mat::at()は本質的には遅いのだが,場合によっては最適化が効いてけっこう早くなることもある」という話にしか見えないけど?

2011-08-07 00:40:33
Minagawa Takuya @takmin

@ChaoticActivity あ、そういう意味ならそうです。この環境で早ければよいので。

2011-08-07 00:46:16
無駄にツイッターIDが長い人 @ChaoticActivity

@takmin いや,それ実行環境じゃなくてコードの内容依存なんだけど.

2011-08-07 00:47:03
Minagawa Takuya @takmin

@ChaoticActivity すんません、どういうことでしょう。

2011-08-07 00:50:53
無駄にツイッターIDが長い人 @ChaoticActivity

@takmin 同じVGA画像の処理でも「VGA画像を読んでheight,widthでループ」と「640x480でハードコーディング」だと,後者はビルドの時点で最適化でループ展開されて実行時のアドレス計算が無くなってる可能性があるけど,前者はそういう高速化ができない

2011-08-07 00:51:15
Minagawa Takuya @takmin

@ChaoticActivity なるほど。僕のコードがどのようにその関数を呼び出しているかに依存しそうですね。確かに。

2011-08-07 00:55:56
無駄にツイッターIDが長い人 @ChaoticActivity

@takmin そもそも一般的に「最適化で早くなる」ことを前提にコードを書くのは危険な思想だと思うし,そういう前提でやるなら実際に使うコード自体で最適化後の速度を調べないと意味が無いことはわかったよね?そう考えると,速度を気にするコードであれば最初からポインタを使うのが筋かと.

2011-08-07 01:00:12
Norishige Fukushima @fukushima1981

@takmin さすがに*pImg++;なコードはatよりも速くないですか?*(pImg + width*j + I)は変わらないと思いますが...

2011-08-07 00:55:09
Minagawa Takuya @takmin

@fukushima1981 はい、後者で比較してました。

2011-08-07 00:56:43
Norishige Fukushima @fukushima1981

俺式OpenCVの画素全操作ループのテンプレートhttp://ow.ly/d/iFQ OpenMPつかって並列化すると自然とこうなる気がするんですがどうでしょう?

2011-08-07 01:05:16
Norishige Fukushima @fukushima1981

@takmin でもまぁ超マルチコアになってきたら,ポインタの++とかまったくいらんですよねw cudaで書いてると,(foo*j)*bar+i 見たいな部分だらけになって後からまったく読めないw

2011-08-07 01:09:41
Minagawa Takuya @takmin

@fukushima1981 cudaとかまったく詳しくないんですが、超マルチコアの時代というのは画素毎にコアがあるようなイメージでしょうか。(どんな時代だ?)

2011-08-07 01:15:01
Norishige Fukushima @fukushima1981

@takmin そんな時代ですw cudaの画像処理コーディングとかはそんなスタイルです.イメージ的には,ある1画素にどんな処理をするかを書いてあとは,全画素並列にやってくれ.詳しい分配は計算機に任せた.なスタイルですw

2011-08-07 01:20:16
Minagawa Takuya @takmin

@fukushima1981 確か、ヒストグラム計算みたいな全画素集計してとか、GPU上のメモリに画像持ってくのがネックになるとか色々めんどくさいと聞いた気が。そこまで全部最適化してくれる超賢いコンパイラとか早くできないかな(いや、いつかは勉強せなと思ってるけど)

2011-08-07 01:26:49
Norishige Fukushima @fukushima1981

@takmin GPU→メモリは遅いですねぇ.まぁコピーするだけなので書くのは簡単.並列化しようがない演算はCPUでやるしかw(非対称なCELLとかこういう設計ですよね.推測ですが)最近のは,ハード周りで面倒な処は結構自動でやってくれますよ!アルゴリズムは考えてくれないですがw

2011-08-07 01:31:47
Minagawa Takuya @takmin

@fukushima1981 アルゴリズムまで考えられたらお仕事がなくなってしまいます!そうだ。自分でハカソン企画して、分かる人に教えてもらえばいいんだw

2011-08-07 01:36:37
Norishige Fukushima @fukushima1981

@takmin 並列化のアルゴリズムという意味でしたw並列化前提だとクイックソートよりもマージソート系のほうが速い時代ですからねぇ。

2011-08-07 01:45:01
idojun @idojun

@takmin Mat::atは内部でポインタを計算して返しているメソッドinline展開もされるので,ポインタ計算するのと同じです.デバッグ時は,DbgAssertがあるので変わりますが.ただし,Gapに依存しない計算なので,データ連続を仮定してポインタ使うと少し速いかな.

2011-08-07 00:57:18
Minagawa Takuya @takmin

@idojun なるほど。連続アクセスならポインタ、ランダムアクセスだったらat()ってことですね。そういえば誰かが以前同じ事を議論していたような。。。

2011-08-07 00:59:14