OpenCVを普通にビルドしたら「特定の処理が異常に遅い」という問題が起きて、ビルド設定を見直したら解消できました
概要
OpenCVをWindows x64向けにビルドしました。Web上にたくさん情報があるし、オフィシャルのドキュメントもあるし、楽勝ですね!さっそくビルドして動かしてみたところ・・・
特定の処理が異常に遅いという障害報告が上がりました。オフィシャル配布のDLLではこの障害は起きません。これはビルドのやり方が悪そうですね。
そのような問題が起きてなんとか解決したので、ポイントをこの記事に書いておきます。
最初に結論まとめ
cmakeでソースコードを作るときに、次のオプションを足すことで、解決しました。
-DBUILD_PERF_TESTS=OFF -DBUILD_TESTS=OFF -DBUILD_EXAMPLES=OFF -DINSTALL_PDB=ON -DINSTALL_PDB_COMPONENT_EXCLUDE_FROM_ALL=OFF -DCPU_BASELINE=SSE3 -DWITH_LAPACK=OFF -DVIDEOIO_PLUGIN_LIST=all -DINSTALL_CREATE_DISTRIB=ON -DBUILD_DOCS=OFF -DOPENCV_GENERATE_SETUPVARS=ON -DWITH_OPENCL=ON -DBUILD_opencv_python3=OFF -DBUILD_opencv_python2=OFF -DWITH_TBB=OFF -DWITH_CUDA=OFF -DBUILD_opencv_java=OFF
全体を記載すると次の通りです。
cmake -B . -S .. -G "Visual Studio 17 2022" -DCMAKE_INSTALL_PREFIX=install -DBUILD_SHARED_LIBS=ON -DBUILD_PERF_TESTS=OFF -DBUILD_TESTS=OFF -DBUILD_EXAMPLES=OFF -DINSTALL_PDB=ON -DINSTALL_PDB_COMPONENT_EXCLUDE_FROM_ALL=OFF -DCPU_BASELINE=SSE3 -DWITH_LAPACK=OFF -DVIDEOIO_PLUGIN_LIST=all -DINSTALL_CREATE_DISTRIB=ON -DBUILD_DOCS=OFF -DOPENCV_GENERATE_SETUPVARS=ON -DWITH_OPENCL=ON -DBUILD_opencv_python3=OFF -DBUILD_opencv_python2=OFF -DWITH_TBB=OFF -DWITH_CUDA=OFF -DBUILD_opencv_java=OFF
説明
問題が起きたビルド
最初は、次のドキュメントのcmakeのパラメータを参考にしてビルドしました。Web上で見つかる「VisualStudioでOpenCVをビルド」の類の情報もだいたいこれと同じことを言っているようですし、実際にビルドも通りました。
つまり、次のようなコマンドでビルドをしています。
cmake -B . -S .. -G "Visual Studio 17 2022" -DCMAKE_INSTALL_PREFIX=install -DBUILD_SHARED_LIBS=ON -DBUILD_PERF_TESTS:BOOL=OFF -DBUILD_TESTS:BOOL=OFF -DBUILD_DOCS:BOOL=OFF -DWITH_CUDA:BOOL=OFF -DBUILD_EXAMPLES:BOOL=OFF -DINSTALL_CREATE_DISTRIB=ON
cmake --build . --config release --target install
ビルドは成功し、できたDLLのロードも呼び出しも問題なく成功したのですが・・・概要に書いたとおり、特定の処理が異常に遅いという障害報告が上がりました。
改善方法の調査
オフィシャルで配布されているDLLでは障害が再現しなかったので、オフィシャルのビルドのやり方に合わせれば問題は起きないはず、と推測しました。しかしすでにドキュメントに従っているのに、他にオフィシャルのビルドの情報はあるだろうか・・・?
GitHubならActionsでビルドしているだろうと思って追っていったところ、Windows向けのリリースビルドに使われていそうなActionsのYAMLファイルを見つけました。これです。
ここでcmakeへ渡しているパラメータを見ていくと、上で使ったものよりもだいぶ多いようです。次のものが追加されています。
-DINSTALL_PDB=ON -DINSTALL_PDB_COMPONENT_EXCLUDE_FROM_ALL=OFF -DCPU_BASELINE=SSE3 -DWITH_LAPACK=OFF -DVIDEOIO_PLUGIN_LIST=all -DOPENCV_GENERATE_SETUPVARS=ON -DWITH_OPENCL=ON -DBUILD_opencv_python3=OFF -DBUILD_opencv_python2=OFF -DWITH_TBB=OFF -DBUILD_opencv_java=OFF
ざっと見た印象では、-DCPU_BASELINE=SSE3
などかなり影響がありそうな気がします。
とはいえオフィシャルに合わせるのが目的なので、個別に判断はせず、差分を全て足しました。次のようになります。
改善したビルド方法
cmake -B . -S .. -G "Visual Studio 17 2022" -DCMAKE_INSTALL_PREFIX=install -DBUILD_SHARED_LIBS=ON -DBUILD_PERF_TESTS=OFF -DBUILD_TESTS=OFF -DBUILD_EXAMPLES=OFF -DINSTALL_PDB=ON -DINSTALL_PDB_COMPONENT_EXCLUDE_FROM_ALL=OFF -DCPU_BASELINE=SSE3 -DWITH_LAPACK=OFF -DVIDEOIO_PLUGIN_LIST=all -DINSTALL_CREATE_DISTRIB=ON -DBUILD_DOCS=OFF -DOPENCV_GENERATE_SETUPVARS=ON -DWITH_OPENCL=ON -DBUILD_opencv_python3=OFF -DBUILD_opencv_python2=OFF -DWITH_TBB=OFF -DWITH_CUDA=OFF -DBUILD_opencv_java=OFF
cmake --build . --config release --target install
これでビルドが成功し、しかも障害は起きなくなりました。成功です!
まとめ
結論:ドキュメントじゃない、CI/CDスクリプトを信じろ
という感じになりました。
ドキュメントなどの情報はもちろん大事ですしメンテできているに越したことはないですが、やはり再現性があって確実に履歴が残るのはスクリプトですね。今回はOSSのプロジェクトの話でしたが、CI/CDはやはり大事だと思ったので、担当するプロジェクトでも重視していこうと思います。
Discussion