OpenCV 2.3以降のSSE2最適化について

fukushima1981さんのつぶやきをきっかけにOpenCVのSSE2最適化処理について疑問を感じたOpenCVクラスタのつぶやきをまとめました.
4
Norishige Fukushima @fukushima1981

普段IPP使ってるので気付かなかったんですが,OpenCVのSSE最適化の関数は,cv::setUseOptimized(true);を始めにコールしないと有効化しないかもしれません.(自分の環境だとそうなってます).

2011-12-10 16:54:23
dandelion @dandelion1124

@fukushima1981 IPP持ってませんがsetUseOptimized呼ばなくてもSSE使用関数は動いてました.setUseOptimizedがHAVE_IPPのON/OFFで挙動が変わるみたいなのでコードちょっと読んでみます.

2011-12-10 16:59:56
dandelion @dandelion1124

@fukushima1981 (続きです)ソースをざっと読んでみました.setUseOptimized関数を呼ぶ処理がOpenCV内部に見当たらないので,CPUがSSEサポートしてて,CMakeで有効にしていればSSE使った処理は走るような気がします.

2011-12-10 17:16:44
Norishige Fukushima @fukushima1981

@dandelion1124 2.2とSVNを比較してみたら,これ最近の変更っぽいです.USE_SSE2がtrueじゃないとSSEの関数を使ってくれないように仕様変更されてますorzこのフラグはIPPが入ってないとデフォルトがfalseという...

2011-12-10 17:39:13
dandelion @dandelion1124

@fukushima1981 なるほど,USE_SSE2がOFFの場合の処理でしたか!2.2からその処理変わってたの気付いてませんでした.

2011-12-10 17:52:53
ゆるふわUnaさん@A判定 @UnaNancyOwen

@dandelion1124 @fukushima1981 core/system.cppや他を見てみるとそうなってますねwww > volatile bool USE_SSE2 = false; , #if CV_SSE2 if( USE_SSE2 ){ ~

2011-12-10 18:08:04
Norishige Fukushima @fukushima1981

@UnaNancyOwen @dandelion1124 ippとだいたい同じ速度です。ipp はスレッドうまく使ってくれない。

2011-12-10 18:14:16
dandelion @dandelion1124

@UnaNancyOwen @fukushima1981 CV_SSE2がONなら処理する部分とCV_SSE2,USE_SSE2どちらもONなら処理する部分があるからややこしいことになっているんですね!ようやく現象を完全に把握しました。。。

2011-12-10 18:18:24
ゆるふわUnaさん@A判定 @UnaNancyOwen

useOptimizedFlagがUSE_SSE2による最適化の有無を表すならば,初期値はfalseにしておくべきなのにtrueになってる件について(´・ω・`)これcv::useOptimized()が初期状態でtrueを返すので騙されるような…

2011-12-10 18:35:41
ゆるふわUnaさん@A判定 @UnaNancyOwen

正確にはUSE_SSE2による最適化の有効/無効を確認するための状態を表すフラグがuseOptimizedFlagだと思うんだけど…

2011-12-10 18:41:36
ゆるふわUnaさん@A判定 @UnaNancyOwen

@dandelion1124 あれ?USE_SSE2って初期値falseなので#if CV_SSE2 if( USE_SSE2 ) { ~の最適化部分は無効ってことですよね?

2011-12-10 18:51:02
dandelion @dandelion1124

@UnaNancyOwen おっしゃるような条件文のところは確かにSSE2無効だと思います.例えばthresh.cppのthresh_8u関数なんかはCV_SSE2しかチェックしてません.なんでこんなことになってるのは不明ですが(苦笑)

2011-12-10 18:54:20
ゆるふわUnaさん@A判定 @UnaNancyOwen

@dandelion1124 system.cppのuseOptimizedFlagはcv::setUseOptimized()やcv::useOptimizedを読む限りだとUSE_SSE2の有効/無効を表してると思うんです.USE_SSE2の初期値がfalseなら…(続く)

2011-12-10 18:58:58
ゆるふわUnaさん@A判定 @UnaNancyOwen

@dandelion1124 (続き)useOptimizedFlagも初期値はfalseじゃないとおかしいようなって思ったんですが…(´・ω・`)

2011-12-10 19:00:56
ゆるふわUnaさん@A判定 @UnaNancyOwen

そもそもuseOptimizedFlagの存在意義がわからない.USE_SSE2返せばいいような…やっぱり俺の勘違いなのかも(´・ω・`)

2011-12-10 19:03:05
dandelion @dandelion1124

@UnaNancyOwen 私もあのflagの存在意義がよくわかりません(苦笑) この指摘によってコード変更があったのかも? http://t.co/BcWq3pEY

2011-12-10 19:07:47
ゆるふわUnaさん@A判定 @UnaNancyOwen

useOptimizedFlagが全体の最適化の状態を表してるなら別に問題ないのか…でもcv::setUseOptimized(false)でoffにしても#if CV_SSE2は変わらないのでuseOptimizedFlagが全体の最適化の状態を表してるとは思えないんだけどな.

2011-12-10 19:10:35
ゆるふわUnaさん@A判定 @UnaNancyOwen

@dandelion1124 よくわからなくなってきたので「まぁOpenCVだから,こういうこともあるよね!OpenCVだから…」で納得することにしました(´・ω・`)

2011-12-10 19:14:57
ゆるふわUnaさん@A判定 @UnaNancyOwen

たぶん昔からの名残みたいなものってことにしておこう.そうしよう.

2011-12-10 19:17:29
dandelion @dandelion1124

@UnaNancyOwen デフォルトだとCMakeで無効にしない限り最適化は有効になると書いてありますが,現状の処理とは乖離するのでTicket書くのはアリな気がします! http://t.co/Ux8Y1dbo

2011-12-10 19:19:16
ゆるふわUnaさん@A判定 @UnaNancyOwen

結論として,「現状OpenCVではcv::setUseOptimized(true)を呼ばないと一部のSSE2最適化が有効にならない.」ってことでいいのか.

2011-12-10 19:21:32
dandelion @dandelion1124

CV_SSE2はCPUサポート有無やCMake指定,USE_SSE2はユーザ指定により決まって,どちらのフラグも立ってる場合にSSE処理が走るのなら,意味は通じる気がするかなー.

2011-12-10 19:24:58
dandelion @dandelion1124

さっきの理解が正しいとしたら,HAVE_IPPがOFFでもUSE_SSE2の初期値をtrueにして,SSE実装側でCV_SSE2,USE_SSE2両方のフラグをチェックするのが正しい気がする.

2011-12-10 19:48:19
ゆるふわUnaさん@A判定 @UnaNancyOwen

検証のためにちょっとライブラリ内に仕掛けるか.

2011-12-11 09:28:05