编译支持TBB的opencv4.1.0、4.5.2及TBB的使用

环境:ubuntu16.04 + gcc 5.4.0 + Cmake 4.4 +opencv4.1.0 (这个opencv4.1.0_master和contrib_master是我昨天新下载的,因为去年的编译完就删掉了)

首先我命令行安装了tbb的包:

apt-get install libtbb-dev

然后我开始参考自己前面那篇编译opencv4.4.0的文章开始编译,与之前不同的是我还勾选了BUILD_TBB和WITH_TBB这两项标志。因为我已经提前下好了cmake时肯定会报错的文件即vgg、boostdesc等复制到.cache下对应路径,同时将改名后的这些文件也复制一份到.cache对应路径下,令我惊奇的是竟然也报错了:

CMake Warning at cmake/OpenCVDownload.cmake:193 (message):
  wechat_qrcode: Download failed: 7;"Couldn't connect to server"

  For details please refer to the download log file:

  /home/jumper/forcv/opencv-4.1.0/build/CMakeDownloadLog.txt

Call Stack (most recent call first):
  /home/jumper/forcv/opencv_contrib-master/modules/wechat_qrcode/CMakeLists.txt:26 (ocv_download)
  modules/world/CMakeLists.txt:13 (include)
  modules/world/CMakeLists.txt:32 (include_one_module)


CMake Warning at /home/jumper/forcv/opencv_contrib-master/modules/wechat_qrcode/CMakeLists.txt:37 (message):
  WeChatQRCode: Can't get detect caffemodel file for wechat qrcode.
Call Stack (most recent call first):
  modules/world/CMakeLists.txt:13 (include)
  modules/world/CMakeLists.txt:32 (include_one_module)


wechat_qrcode: Download: detect.prototxt

=======================================================================
  Couldn't connect to server from the Internet.
  Perhaps direct connections are not allowed in the current network.
  To use proxy please check/specify these environment variables:
  - http_proxy/https_proxy
  - and/or HTTP_PROXY/HTTPS_PROXY
=======================================================================

CMake Warning at cmake/OpenCVDownload.cmake:193 (message):
  wechat_qrcode: Download failed: 7;"Couldn't connect to server"

  For details please refer to the download log file:

  /home/jumper/forcv/opencv-4.1.0/build/CMakeDownloadLog.txt

Call Stack (most recent call first):
  /home/jumper/forcv/opencv_contrib-master/modules/wechat_qrcode/CMakeLists.txt:26 (ocv_download)
  modules/world/CMakeLists.txt:13 (include)
  modules/world/CMakeLists.txt:32 (include_one_module)


CMake Warning at /home/jumper/forcv/opencv_contrib-master/modules/wechat_qrcode/CMakeLists.txt:37 (message):
  WeChatQRCode: Can't get detect prototxt file for wechat qrcode.
Call Stack (most recent call first):
  modules/world/CMakeLists.txt:13 (include)
  modules/world/CMakeLists.txt:32 (include_one_module)


wechat_qrcode: Download: sr.caffemodel

=======================================================================
  Couldn't connect to server from the Internet.
  Perhaps direct connections are not allowed in the current network.
  To use proxy please check/specify these environment variables:
  - http_proxy/https_proxy
  - and/or HTTP_PROXY/HTTPS_PROXY
=======================================================================

CMake Warning at cmake/OpenCVDownload.cmake:193 (message):
  wechat_qrcode: Download failed: 7;"Couldn't connect to server"

  For details please refer to the download log file:

  /home/jumper/forcv/opencv-4.1.0/build/CMakeDownloadLog.txt

Call Stack (most recent call first):
  /home/jumper/forcv/opencv_contrib-master/modules/wechat_qrcode/CMakeLists.txt:26 (ocv_download)
  modules/world/CMakeLists.txt:13 (include)
  modules/world/CMakeLists.txt:32 (include_one_module)


CMake Warning at /home/jumper/forcv/opencv_contrib-master/modules/wechat_qrcode/CMakeLists.txt:37 (message):
  WeChatQRCode: Can't get sr caffemodel file for wechat qrcode.
Call Stack (most recent call first):
  modules/world/CMakeLists.txt:13 (include)
  modules/world/CMakeLists.txt:32 (include_one_module)


wechat_qrcode: Download: sr.prototxt

=======================================================================
  Couldn't connect to server from the Internet.
  Perhaps direct connections are not allowed in the current network.
  To use proxy please check/specify these environment variables:
  - http_proxy/https_proxy
  - and/or HTTP_PROXY/HTTPS_PROXY
=======================================================================

CMake Warning at cmake/OpenCVDownload.cmake:193 (message):
  wechat_qrcode: Download failed: 7;"Couldn't connect to server"

  For details please refer to the download log file:

  /home/jumper/forcv/opencv-4.1.0/build/CMakeDownloadLog.txt

Call Stack (most recent call first):
  /home/jumper/forcv/opencv_contrib-master/modules/wechat_qrcode/CMakeLists.txt:26 (ocv_download)
  modules/world/CMakeLists.txt:13 (include)
  modules/world/CMakeLists.txt:32 (include_one_module)


CMake Warning at /home/jumper/forcv/opencv_contrib-master/modules/wechat_qrcode/CMakeLists.txt:37 (message):
  WeChatQRCode: Can't get sr prototxt file for wechat qrcode.
Call Stack (most recent call first):
  modules/world/CMakeLists.txt:13 (include)
  modules/world/CMakeLists.txt:32 (include_one_module)

可以从报错信息看到,这些报错都与Wechat有关,稍微查了一下这是微信二维码caffe识别相关的内容,这说明opencv团队更新了opencv源文件,去年编译时明明没有报错这些内容的。于是跟vgg和boostdesc一样,我去手动翻墙下载了日志中缺少的caffemodel和prototxt文件,复制到.cache/wechat_qrcode的路径下,同时改名后的版本也复制过去一份,

然后重新configure,不再出现那个报错:

但出现如下红色报错:

TBB: Download: 2018_U1.tar.gz
CMake Warning at cmake/OpenCVDownload.cmake:213 (message):
  TBB: Hash mismatch: 4bb4d8913a0a044fb2a11553a1492ca1
Call Stack (most recent call first):
  3rdparty/tbb/CMakeLists.txt:19 (ocv_download)

我依旧手动去下载TBB对应的2018_U1的版本,然后复制到.cache/tbb下一份,同时将改名后的也复制过去一份。然后点击configure没有红色报错出现!再configure一次也没有红色报错出现!但此时我发现有一个flag是TBB_VER_FILE这一栏显示:TBB_VER_FILE_NOTFOUND

TBB_VER_FILE                  TBB_VER_FILE_NOTFOUND

于是我手动为其指定了路径,然后configure,我发现Cmake的outputs中依旧没有显示版本号:

Parallel framework:            TBB (ver . interface )

但也没有红色报错,所以我就没管。然后我点击Generate,出现了红色报错:

Configuring done
CMake Error at 3rdparty/tbb/CMakeLists.txt:102 (add_library):
  Cannot find source file:

    /home/jumper/forcv/opencv-4.1.0/buildcv/3rdparty/tbb/tbb-2018_U1/src/rml/client/rml_tbb.cpp

  Tried extensions .c .C .c++ .cc .cpp .cxx .m .M .mm .h .hh .h++ .hm .hpp
  .hxx .in .txx


CMake Error: CMake can not determine linker language for target: tbb
CMake Error in 3rdparty/tbb/CMakeLists.txt:
  Exporting the target "tbb" is not allowed since its linker language cannot
  be determined


CMake Error: CMake can not determine linker language for target: tbb
CMake Error in 3rdparty/tbb/CMakeLists.txt:
  Exporting the target "tbb" is not allowed since its linker language cannot
  be determined


CMake Error: Cannot determine link language for target "tbb".
CMake Error in 3rdparty/tbb/CMakeLists.txt:
  Exporting the target "tbb" is not allowed since its linker language cannot
  be determined


CMake Error in 3rdparty/tbb/CMakeLists.txt:
  Exporting the target "tbb" is not allowed since its linker language cannot
  be determined


Generating done

说找不到这个rml_tbb.cpp文件,然后tbb找不到对应的链接器!我承认我的文件夹是oneTBB-2018_U1而不是tbb-2018_U1,难道是这个原因???但是不对啊,我检查了下tbb的cmakelist文件

#Cross compile TBB from source
project(tbb)

if (WIN32 AND NOT ARM)
  message(FATAL_ERROR "BUILD_TBB option supports Windows on ARM only!\nUse regular official TBB build instead of the BUILD_TBB option!")
endif()

set(tbb_filename "2018_U1.tar.gz")
set(tbb_subdir "tbb-2018_U1")
set(tbb_md5 "4bb4d8913a0a044fb2a11553a1492ca1")

ocv_warnings_disable(CMAKE_CXX_FLAGS /wd4702
    -Wshadow
    -Wunused-parameter
    -Wmissing-prototypes  # MacOSX
)

set(tbb_src_dir "${OpenCV_BINARY_DIR}/3rdparty/tbb")
ocv_download(FILENAME ${tbb_filename}
             HASH ${tbb_md5}
             URL
               "${OPENCV_TBB_URL}"
               "$ENV{OPENCV_TBB_URL}"
               "https://github.com/01org/tbb/archive/"
             DESTINATION_DIR ${tbb_src_dir}
             ID TBB
             STATUS res
             UNPACK RELATIVE_URL)
if(NOT res)
  return()
endif()
set(tbb_src_dir "${tbb_src_dir}/${tbb_subdir}")

ocv_include_directories("${tbb_src_dir}/include"
                        "${tbb_src_dir}/src/"
                        "${tbb_src_dir}/src/rml/include"
                        "${CMAKE_CURRENT_SOURCE_DIR}")

file(GLOB lib_srcs "${tbb_src_dir}/src/tbb/*.cpp")
file(GLOB lib_hdrs "${tbb_src_dir}/src/tbb/*.h")
list(APPEND lib_srcs "${tbb_src_dir}/src/rml/client/rml_tbb.cpp")

if (WIN32)
  add_definitions(/D__TBB_DYNAMIC_LOAD_ENABLED=0
                  /D__TBB_BUILD=1
                  /DTBB_NO_LEGACY=1
                  /D_UNICODE
                  /DUNICODE
                  /DWINAPI_FAMILY=WINAPI_FAMILY_APP
                  /DDO_ITT_NOTIFY=0
                  /DUSE_WINTHREAD
               ) # defines were copied from windows.cl.inc

  if (ARM)
    add_definitions(/D_WIN32_WINNT=0x0602
                    /D__TBB_WIN32_USE_CL_BUILTINS
                   )
  endif()

set(CMAKE_LINKER_FLAGS "${CMAKE_LINKER_FLAGS} /APPCONTAINER")
else()
  add_definitions(-D__TBB_DYNAMIC_LOAD_ENABLED=0         #required
                  -D__TBB_WEAK_SYMBOLS_PRESENT=0         #required for 4.3
                  -D__TBB_BUILD=1                        #required
                  -D__TBB_SURVIVE_THREAD_SWITCH=0        #no cilk support
                  -DTBB_USE_DEBUG=0                      #just to be sure
                  -DTBB_NO_LEGACY=1                      #don't need backward compatibility
                  -DDO_ITT_NOTIFY=0                      #it seems that we don't need these notifications
                 )
endif()

if(HAVE_PTHREAD)
  add_definitions(-DUSE_PTHREAD) #required for Unix
endif()

if(CV_GCC)
  add_definitions(-DTBB_USE_GCC_BUILTINS=1) #required for ARM GCC
  if(NOT CMAKE_CXX_COMPILER_VERSION LESS 6.0)
    set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -flifetime-dse=1") # workaround for GCC 6.x
  endif()
endif()

if(ANDROID_COMPILER_IS_CLANG)
  add_definitions(-D__TBB_GCC_BUILTIN_ATOMICS_PRESENT=1)
  ocv_warnings_disable(CMAKE_CXX_FLAGS -Wmissing-prototypes)
endif()

set(TBB_SOURCE_FILES ${lib_srcs} ${lib_hdrs})

if (ARM AND NOT WIN32)
  if (NOT ANDROID)
    set(TBB_SOURCE_FILES ${TBB_SOURCE_FILES} "${CMAKE_CURRENT_SOURCE_DIR}/arm_linux_stub.cpp")
  endif()
  set(TBB_SOURCE_FILES ${TBB_SOURCE_FILES} "${CMAKE_CURRENT_SOURCE_DIR}/android_additional.h")
  set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -include \"${CMAKE_CURRENT_SOURCE_DIR}/android_additional.h\"")
endif()

set(tbb_version_file "version_string.ver")
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/${tbb_version_file}.cmakein" "${CMAKE_CURRENT_BINARY_DIR}/${tbb_version_file}" @ONLY)
list(APPEND TBB_SOURCE_FILES "${CMAKE_CURRENT_BINARY_DIR}/${tbb_version_file}")

add_library(tbb ${TBB_SOURCE_FILES})

为什么要在这最后一句报错,而Cmakedownload记录中又显示TBB、Wechat、Vgg、boostdesc、ippicv等都成功?

 

我查了很久实在没找到结果,还在这里提问了https://ask.csdn.net/questions/7426653 目前没人回答。

然后我重新试了以下 不勾选BUILD_TBB,只勾选WITH_TBB,结果configure和Generate均成功,没有任何红色报错!也出现了TBB版本号,图片见下下图(顺序乱了)。

然后我进入生成的文件夹中开始make和make install 这最后两步,但在make进行到54%时出现:

modules/rapid/src/rapid.cpp:357:64: error: ‘solvePnPRefineLM’ was not declared in this scope
     solvePnPRefineLM(pts3d, pts2d, K, cv::noArray(), rvec, tvec);
                                                                ^
modules/world/CMakeFiles/opencv_world.dir/build.make:14505: recipe for target 'modules/world/CMakeFiles/opencv_world.dir/home/jumper/forcv/opencv_contrib-master/modules/rapid/src/rapid.cpp.o' failed
make[2]: *** [modules/world/CMakeFiles/opencv_world.dir/home/jumper/forcv/opencv_contrib-master/modules/rapid/src/rapid.cpp.o] Error 1
CMakeFiles/Makefile2:3875: recipe for target 'modules/world/CMakeFiles/opencv_world.dir/all' failed
make[1]: *** [modules/world/CMakeFiles/opencv_world.dir/all] Error 2
Makefile:160: recipe for target 'all' failed
make: *** [all] Error 2

这与TBB和wechat这两个去年我没搞的内容不相关,说明什么,说明opencv团队的确在更新opencv源文件,目前还有点问题,所以我目前觉得这个昨天新下的版本暂时不能用,但去年下的源文件我又删掉了,很无奈啊。难道只能等opencv团队处理好这个问题更新后我再重新下载。目前虽然有TBB版本号出来,即使我在下图TBB_ENV_LIB_DEBUG位置指定libtbb_debug.so的路径,最终在opencv编译时还是会出现54%时的那个错误。估计是现在更新的opencv哪里存在不兼容,等opencv团队解决了再来搞。

 

 

 

 

幸好我在去年装的电脑上找到了opencv4.4.0的源文件,于是我重新勾选WITH_BUILD,cmake没有任何问题而且去新生成的文件下make和make install 均成功。。顺便说一下,我用去年这个4.4.0没有任何关于wechat的内容,说明的确去年opencv公司没有加入微信二维码的内容。的确是今年新加的。待会儿我再用一个测试tbb的例子试下。

的确加速比很诱人啊。

 

 

 

新下载的4.1.0我又试了几次,依旧是在make那步出现那个问题。

我又试了一下去年下载的4.4.0的源文件,将BUILD_TBB和WITH_TBB以及OPENMP都选上:

看竟然关于TBB的路径不用手动指定,就出来了这个版本号!很轻松就得到了让我有点怀疑。然后我开始在buildcv文件夹下编译cv,即make和make install均成功:

而且可以看到生成了tbb的库

而且buildcv下自动就生成了tbb的相关文件夹:

然后我开始整合所有的include和lib,并测试网上的例子,例子需要使用opencv_world和tbb的库

报错说没有这个文件,于是我修改这个h文件:

然后再编译

报错

opencv2/tbb/internal/../tbb_config.h:596:35: error: ISO C++ forbids declaration of ‘type name’ with no type [-fpermissive]
 #define __TBB_DEFAULT_PARTITIONER tbb::auto_partitioner
include/opencv2/tbb/parallel_for.h:109:77: error: template argument 3 is invalid
     serial::interface9::start_for<Range,Body,const __TBB_DEFAULT_PARTITIONER>::run(range,body,__TBB_DEFAULT_PARTITIONER());
opencv2/tbb/parallel_for.h:109:83: error: qualified-id in declaration before ‘(’ token
     serial::interface9::start_for<Range,Body,const __TBB_DEFAULT_PARTITIONER>::run(range,body,__TBB_DEFAULT_PARTITIONER());
tbb/parallel_for.h:115:97: error: ‘simple_partitioner’ does not name a type
opencv2/tbb/parallel_for.h:116:52: error: ISO C++ forbids declaration of ‘type name’ with no type [-fpermissive]
opencv2/tbb/parallel_for.h:116:70: error: template argument 3 is invalid
tbb/parallel_for.h:116:76: error: qualified-id in declaration before ‘(’ token
     serial::interface9::start_for<Range,Body,const simple_partitioner>::run(range,body,partitioner);
tbb/parallel_for.h:129:39: error: redefinition of ‘template<class Range, class Body> void tbb::serial::interface9::parallel_for(const Range&, const Body&, const int&)’
tbb/parallel_for.h:136:91: error: ‘affinity_partitioner’ has not been declared
tbb/parallel_for.h:137:46: error: ‘affinity_partitioner’ was not declared in this scope
opencv2/tbb/parallel_for.h:137:95: error: expression list treated as compound expression in initializer [-fpermissive]
opencv2/tbb/parallel_for.h:165:44: error: ISO C++ forbids declaration of ‘type name’ with no type [-fpermissive]
include/opencv2/tbb/parallel_for_each.h:74:13: error: ‘parallel_for’ is not a member of ‘tbb’

这个我没查到原因,我估计是哪里没设置好,于是我试着挪动tbb的位置:

也就是include内不要放tbb了,放到外面来即可。然后编译成功并运行对比跑2280张图高斯滤波,使用TBB与不用时间对比,迭代10次:

很诱人的效果。

 

After several hours,i close the eclipse and then restart it.The following error appears when i run the project again even though i change nothing:

TBB Warning: Exact exception propagation is requested by application but the linked library is built without support for it

I am  very confused about this !

The red warning has gone after I delete the folder of 'Release' in the path of my project by hand and then rebuild and run the project.

 

今天我又试着下载了4.5.2,因为这个版本开始的core模块可以选择TBB作为后端,之前的版本里没有。按照上面的步骤编译,CMAKE部分出现几个错误:

Detected processor: x86_64
Looking for ccache - not found
Found ZLIB: /usr/lib/x86_64-linux-gnu/libz.so (found suitable version "1.2.8", minimum required is "1.2.3") 
Cleaning INTERNAL cached variable: JPEG_LIBRARY
Cleaning INTERNAL cached variable: JPEG_INCLUDE_DIR
Could NOT find JPEG (missing:  JPEG_LIBRARY JPEG_INCLUDE_DIR) 
libjpeg-turbo: VERSION = 2.0.6, BUILD = opencv-4.5.2-libjpeg-turbo
Cleaning INTERNAL cached variable: TIFF_LIBRARY
Cleaning INTERNAL cached variable: TIFF_INCLUDE_DIR
Could NOT find TIFF (missing:  TIFF_LIBRARY TIFF_INCLUDE_DIR) 
Cleaning INTERNAL cached variable: WEBP_LIBRARY
Cleaning INTERNAL cached variable: WEBP_INCLUDE_DIR
Could NOT find OpenJPEG (minimal suitable version: 2.0, recommended version >= 2.3.1). OpenJPEG will be built from sources
OpenJPEG: VERSION = 2.4.0, BUILD = opencv-4.5.2-openjp2-2.4.0
OpenJPEG libraries will be built from sources: libopenjp2 (version "2.4.0")
Found ZLIB: /usr/lib/x86_64-linux-gnu/libz.so (found version "1.2.8") 
Checking for module 'gtk+-3.0'

 但我没管,然后generate时又出现:

Configuring done
WARNING: Target "tbb" has EXCLUDE_FROM_ALL set and will not be built by default but an install rule has been provided for it.  CMake does not define behavior for this case.
Generating done

我也没管,继续去编译:make时出现错误:

In file included from /home/jumper/workspace/opencv4.5.2_source/opencv-4.5.2/modules/gapi/src/executor/gtbbexecutor.cpp:12:0:
/home/jumper/workspace/opencv4.5.2_source/opencv-4.5.2/modules/gapi/src/executor/gtbbexecutor.cpp: In function ‘void cv::gimpl::parallel::detail::async::wake_master(cv::gimpl::parallel::detail::async::async_tasks_t&, cv::gimpl::parallel::detail::async::wake_tbb_master)’:
/home/jumper/workspace/opencv4.5.2_source/opencv-4.5.2/modules/gapi/src/executor/gtbbexecutor.cpp:146:35: error: ‘ittTbbUnlockMasterThread’ was not declared in this scope
         GAPI_ITT_AUTO_TRACE_GUARD(ittTbbUnlockMasterThread);
                                   ^
/home/jumper/workspace/opencv4.5.2_source/opencv-4.5.2/modules/gapi/src/executor/gapi_itt.hpp:47:99: note: in definition of macro ‘GAPI_ITT_NAMED_TRACE_GUARD’
 CE_GUARD(name, h)  auto name =  cv::gimpl::parallel::make_itt_guard(h); cv::uti
                                                                     ^
/home/jumper/workspace/opencv4.5.2_source/opencv-4.5.2/modules/gapi/src/executor/gapi_itt.hpp:54:61: note: in expansion of macro ‘GAPI_ITT_AUTO_TRACE_GUARD_IMPL_’
     #define GAPI_ITT_AUTO_TRACE_GUARD_IMPL(LINE, h)         GAPI_ITT_AUTO_TRACE
                                                             ^
/home/jumper/workspace/opencv4.5.2_source/opencv-4.5.2/modules/gapi/src/executor/gapi_itt.hpp:55:61: note: in expansion of macro ‘GAPI_ITT_AUTO_TRACE_GUARD_IMPL’
     #define GAPI_ITT_AUTO_TRACE_GUARD(h)                    GAPI_ITT_AUTO_TRACE
                                                             ^
/home/jumper/workspace/opencv4.5.2_source/opencv-4.5.2/modules/gapi/src/executor/gtbbexecutor.cpp:146:9: note: in expansion of macro ‘GAPI_ITT_AUTO_TRACE_GUARD’
         GAPI_ITT_AUTO_TRACE_GUARD(ittTbbUnlockMasterThread);
         ^
/home/jumper/workspace/opencv4.5.2_source/opencv-4.5.2/modules/gapi/src/executor/gtbbexecutor.cpp:146:35: note: suggested alternatives:
         GAPI_ITT_AUTO_TRACE_GUARD(ittTbbUnlockMasterThread);
                                   ^
/home/jumper/workspace/opencv4.5.2_source/opencv-4.5.2/modules/gapi/src/executor/gapi_itt.hpp:47:99: note: in definition of macro ‘GAPI_ITT_NAMED_TRACE_GUARD’
 CE_GUARD(name, h)  auto name =  cv::gimpl::parallel::make_itt_guard(h); cv::uti
                                                                     ^
/home/jumper/workspace/opencv4.5.2_source/opencv-4.5.2/modules/gapi/src/executor/gapi_itt.hpp:54:61: note: in expansion of macro ‘GAPI_ITT_AUTO_TRACE_GUARD_IMPL_’
     #define GAPI_ITT_AUTO_TRACE_GUARD_IMPL(LINE, h)         GAPI_ITT_AUTO_TRACE
                                                             ^
/home/jumper/workspace/opencv4.5.2_source/opencv-4.5.2/modules/gapi/src/executor/gapi_itt.hpp:55:61: note: in expansion of macro ‘GAPI_ITT_AUTO_TRACE_GUARD_IMPL’
     #define GAPI_ITT_AUTO_TRACE_GUARD(h)                    GAPI_ITT_AUTO_TRACE
                                                             ^
/home/jumper/workspace/opencv4.5.2_source/opencv-4.5.2/modules/gapi/src/executor/gtbbexecutor.cpp:146:9: note: in expansion of macro ‘GAPI_ITT_AUTO_TRACE_GUARD’
         GAPI_ITT_AUTO_TRACE_GUARD(ittTbbUnlockMasterThread);
         ^
/home/jumper/workspace/opencv4.5.2_source/opencv-4.5.2/modules/gapi/src/executor/gtbbexecutor.cpp:90:33: note:   ‘cv::gimpl::parallel::detail::tasking::{anonymous}::ittTbbUnlockMasterThread’
     static __itt_string_handle* ittTbbUnlockMasterThread      = __itt_string_ha
                                 ^
/home/jumper/workspace/opencv4.5.2_source/opencv-4.5.2/modules/gapi/src/executor/gtbbexecutor.cpp:90:33: note:   ‘cv::gimpl::parallel::detail::tasking::{anonymous}::ittTbbUnlockMasterThread’
In file included from /home/jumper/workspace/opencv4.5.2_source/opencv-4.5.2/modules/gapi/src/executor/gtbbexecutor.cpp:12:0:
/home/jumper/workspace/opencv4.5.2_source/opencv-4.5.2/modules/gapi/src/executor/gtbbexecutor.cpp: In function ‘std::size_t cv::gimpl::parallel::detail::graph::push_ready_dependants(cv::gimpl::parallel::prio_items_queue_t&, cv::gimpl::parallel::tile_node*)’:
/home/jumper/workspace/opencv4.5.2_source/opencv-4.5.2/modules/gapi/src/executor/gtbbexecutor.cpp:231:35: error: ‘ittTbbAddReadyBlocksToQueue’ was not declared in this scope
         GAPI_ITT_AUTO_TRACE_GUARD(ittTbbAddReadyBlocksToQueue);
                                   ^
/home/jumper/workspace/opencv4.5.2_source/opencv-4.5.2/modules/gapi/src/executor/gapi_itt.hpp:47:99: note: in definition of macro ‘GAPI_ITT_NAMED_TRACE_GUARD’
 CE_GUARD(name, h)  auto name =  cv::gimpl::parallel::make_itt_guard(h); cv::uti
                                                                     ^
/home/jumper/workspace/opencv4.5.2_source/opencv-4.5.2/modules/gapi/src/executor/gapi_itt.hpp:54:61: note: in expansion of macro ‘GAPI_ITT_AUTO_TRACE_GUARD_IMPL_’
     #define GAPI_ITT_AUTO_TRACE_GUARD_IMPL(LINE, h)         GAPI_ITT_AUTO_TRACE
                                                             ^
/home/jumper/workspace/opencv4.5.2_source/opencv-4.5.2/modules/gapi/src/executor/gapi_itt.hpp:55:61: note: in expansion of macro ‘GAPI_ITT_AUTO_TRACE_GUARD_IMPL’
     #define GAPI_ITT_AUTO_TRACE_GUARD(h)                    GAPI_ITT_AUTO_TRACE
                                                             ^
/home/jumper/workspace/opencv4.5.2_source/opencv-4.5.2/modules/gapi/src/executor/gtbbexecutor.cpp:231:9: note: in expansion of macro ‘GAPI_ITT_AUTO_TRACE_GUARD’
         GAPI_ITT_AUTO_TRACE_GUARD(ittTbbAddReadyBlocksToQueue);
         ^
/home/jumper/workspace/opencv4.5.2_source/opencv-4.5.2/modules/gapi/src/executor/gtbbexecutor.cpp:231:35: note: suggested alternatives:
         GAPI_ITT_AUTO_TRACE_GUARD(ittTbbAddReadyBlocksToQueue);
                                   ^
/home/jumper/workspace/opencv4.5.2_source/opencv-4.5.2/modules/gapi/src/executor/gapi_itt.hpp:47:99: note: in definition of macro ‘GAPI_ITT_NAMED_TRACE_GUARD’
 CE_GUARD(name, h)  auto name =  cv::gimpl::parallel::make_itt_guard(h); cv::uti
                                                                     ^
/home/jumper/workspace/opencv4.5.2_source/opencv-4.5.2/modules/gapi/src/executor/gapi_itt.hpp:54:61: note: in expansion of macro ‘GAPI_ITT_AUTO_TRACE_GUARD_IMPL_’
     #define GAPI_ITT_AUTO_TRACE_GUARD_IMPL(LINE, h)         GAPI_ITT_AUTO_TRACE
                                                             ^
/home/jumper/workspace/opencv4.5.2_source/opencv-4.5.2/modules/gapi/src/executor/gapi_itt.hpp:55:61: note: in expansion of macro ‘GAPI_ITT_AUTO_TRACE_GUARD_IMPL’
     #define GAPI_ITT_AUTO_TRACE_GUARD(h)                    GAPI_ITT_AUTO_TRACE
                                                             ^
/home/jumper/workspace/opencv4.5.2_source/opencv-4.5.2/modules/gapi/src/executor/gtbbexecutor.cpp:231:9: note: in expansion of macro ‘GAPI_ITT_AUTO_TRACE_GUARD’
         GAPI_ITT_AUTO_TRACE_GUARD(ittTbbAddReadyBlocksToQueue);
         ^
/home/jumper/workspace/opencv4.5.2_source/opencv-4.5.2/modules/gapi/src/executor/gtbbexecutor.cpp:87:33: note:   ‘cv::gimpl::parallel::detail::tasking::{anonymous}::ittTbbAddReadyBlocksToQueue’
     static __itt_string_handle* ittTbbAddReadyBlocksToQueue   = __itt_string_ha
                                 ^
/home/jumper/workspace/opencv4.5.2_source/opencv-4.5.2/modules/gapi/src/executor/gtbbexecutor.cpp:87:33: note:   ‘cv::gimpl::parallel::detail::tasking::{anonymous}::ittTbbAddReadyBlocksToQueue’
In file included from /home/jumper/workspace/opencv4.5.2_source/opencv-4.5.2/modules/gapi/src/executor/gtbbexecutor.cpp:12:0:
/home/jumper/workspace/opencv4.5.2_source/opencv-4.5.2/modules/gapi/src/executor/gtbbexecutor.cpp: In lambda function:
/home/jumper/workspace/opencv4.5.2_source/opencv-4.5.2/modules/gapi/src/executor/gtbbexecutor.cpp:333:55: error: ‘ittTbbEnqueueSpawnReadyBlocks’ was not declared in this scope
                             GAPI_ITT_AUTO_TRACE_GUARD(ittTbbEnqueueSpawnReadyBl
                                                       ^
/home/jumper/workspace/opencv4.5.2_source/opencv-4.5.2/modules/gapi/src/executor/gapi_itt.hpp:47:99: note: in definition of macro ‘GAPI_ITT_NAMED_TRACE_GUARD’
 CE_GUARD(name, h)  auto name =  cv::gimpl::parallel::make_itt_guard(h); cv::uti
                                                                     ^
/home/jumper/workspace/opencv4.5.2_source/opencv-4.5.2/modules/gapi/src/executor/gapi_itt.hpp:54:61: note: in expansion of macro ‘GAPI_ITT_AUTO_TRACE_GUARD_IMPL_’
     #define GAPI_ITT_AUTO_TRACE_GUARD_IMPL(LINE, h)         GAPI_ITT_AUTO_TRACE
                                                             ^
/home/jumper/workspace/opencv4.5.2_source/opencv-4.5.2/modules/gapi/src/executor/gapi_itt.hpp:55:61: note: in expansion of macro ‘GAPI_ITT_AUTO_TRACE_GUARD_IMPL’
     #define GAPI_ITT_AUTO_TRACE_GUARD(h)                    GAPI_ITT_AUTO_TRACE
                                                             ^
/home/jumper/workspace/opencv4.5.2_source/opencv-4.5.2/modules/gapi/src/executor/gtbbexecutor.cpp:333:29: note: in expansion of macro ‘GAPI_ITT_AUTO_TRACE_GUARD’
                             GAPI_ITT_AUTO_TRACE_GUARD(ittTbbEnqueueSpawnReadyBl
                             ^
/home/jumper/workspace/opencv4.5.2_source/opencv-4.5.2/modules/gapi/src/executor/gtbbexecutor.cpp:333:55: note: suggested alternatives:
                             GAPI_ITT_AUTO_TRACE_GUARD(ittTbbEnqueueSpawnReadyBl
                                                       ^
/home/jumper/workspace/opencv4.5.2_source/opencv-4.5.2/modules/gapi/src/executor/gapi_itt.hpp:47:99: note: in definition of macro ‘GAPI_ITT_NAMED_TRACE_GUARD’
 CE_GUARD(name, h)  auto name =  cv::gimpl::parallel::make_itt_guard(h); cv::uti
                                                                     ^
/home/jumper/workspace/opencv4.5.2_source/opencv-4.5.2/modules/gapi/src/executor/gapi_itt.hpp:54:61: note: in expansion of macro ‘GAPI_ITT_AUTO_TRACE_GUARD_IMPL_’
     #define GAPI_ITT_AUTO_TRACE_GUARD_IMPL(LINE, h)         GAPI_ITT_AUTO_TRACE
                                                             ^
/home/jumper/workspace/opencv4.5.2_source/opencv-4.5.2/modules/gapi/src/executor/gapi_itt.hpp:55:61: note: in expansion of macro ‘GAPI_ITT_AUTO_TRACE_GUARD_IMPL’
     #define GAPI_ITT_AUTO_TRACE_GUARD(h)                    GAPI_ITT_AUTO_TRACE
                                                             ^
/home/jumper/workspace/opencv4.5.2_source/opencv-4.5.2/modules/gapi/src/executor/gtbbexecutor.cpp:333:29: note: in expansion of macro ‘GAPI_ITT_AUTO_TRACE_GUARD’
                             GAPI_ITT_AUTO_TRACE_GUARD(ittTbbEnqueueSpawnReadyBl
                             ^
/home/jumper/workspace/opencv4.5.2_source/opencv-4.5.2/modules/gapi/src/executor/gtbbexecutor.cpp:89:33: note:   ‘cv::gimpl::parallel::detail::tasking::{anonymous}::ittTbbEnqueueSpawnReadyBlocks’
     static __itt_string_handle* ittTbbEnqueueSpawnReadyBlocks = __itt_string_ha
                                 ^
/home/jumper/workspace/opencv4.5.2_source/opencv-4.5.2/modules/gapi/src/executor/gtbbexecutor.cpp:89:33: note:   ‘cv::gimpl::parallel::detail::tasking::{anonymous}::ittTbbEnqueueSpawnReadyBlocks’
/home/jumper/workspace/opencv4.5.2_source/opencv-4.5.2/modules/gapi/src/executor/gtbbexecutor.cpp: At global scope:
/home/jumper/workspace/opencv4.5.2_source/opencv-4.5.2/modules/gapi/src/executor/gtbbexecutor.cpp:87:33: warning: ‘cv::gimpl::parallel::detail::tasking::{anonymous}::ittTbbAddReadyBlocksToQueue’ defined but not used [-Wunused-variable]
     static __itt_string_handle* ittTbbAddReadyBlocksToQueue   = __itt_string_ha
                                 ^
/home/jumper/workspace/opencv4.5.2_source/opencv-4.5.2/modules/gapi/src/executor/gtbbexecutor.cpp:89:33: warning: ‘cv::gimpl::parallel::detail::tasking::{anonymous}::ittTbbEnqueueSpawnReadyBlocks’ defined but not used [-Wunused-variable]
     static __itt_string_handle* ittTbbEnqueueSpawnReadyBlocks = __itt_string_ha
                                 ^
/home/jumper/workspace/opencv4.5.2_source/opencv-4.5.2/modules/gapi/src/executor/gtbbexecutor.cpp:90:33: warning: ‘cv::gimpl::parallel::detail::tasking::{anonymous}::ittTbbUnlockMasterThread’ defined but not used [-Wunused-variable]
     static __itt_string_handle* ittTbbUnlockMasterThread      = __itt_string_ha
                                 ^
modules/world/CMakeFiles/opencv_world.dir/build.make:19713: recipe for target 'modules/world/CMakeFiles/opencv_world.dir/__/gapi/src/executor/gtbbexecutor.cpp.o' failed
make[2]: *** [modules/world/CMakeFiles/opencv_world.dir/__/gapi/src/executor/gtbbexecutor.cpp.o] Error 1
CMakeFiles/Makefile2:3833: recipe for target 'modules/world/CMakeFiles/opencv_world.dir/all' failed
make[1]: *** [modules/world/CMakeFiles/opencv_world.dir/all] Error 2
Makefile:160: recipe for target 'all' failed
make: *** [all] Error 2

我去这个报错文件下看了:

#ifdef OPENCV_WITH_ITT
namespace {
    static __itt_string_handle* ittTbbAddReadyBlocksToQueue   = __itt_string_handle_create("add ready blocks to queue");
    static __itt_string_handle* ittTbbSpawnReadyBlocks        = __itt_string_handle_create("spawn ready blocks");
    static __itt_string_handle* ittTbbEnqueueSpawnReadyBlocks = __itt_string_handle_create("enqueueing a spawn of ready blocks");
    static __itt_string_handle* ittTbbUnlockMasterThread      = __itt_string_handle_create("Unlocking master thread");
}
#endif // OPENCV_WITH_ITT

于是我重新cmake时仔细看了下 WITH_ITT这一项是默认勾选的,于是我取消。

然后一切顺利:

 

 测试了一下,运行OK!测了下例子:

#include <iostream>
#include <tbb/tbb.h>
using namespace tbb;

#include <opencv2/opencv.hpp>
using namespace cv;

void concurrent_parallel_for() {
	cv::parallel_for_(Range(0, 50000), [&](const Range& range)
	{
		for (int n = range.start; n < range.end; n++)
		{
	        tbb::concurrent_vector<int> array(n);
	        for( int i=0; i<n; ++i )
	            array.at(i) = (i*7)%n;
	        std::sort( array.begin(), array.end() );
	    }
	});
}

void justparallel_for() {
	cv::parallel_for_(Range(0, 50000), [&](const Range& range)
	{
		for (int n = range.start; n < range.end; n++)
		{
	        std::vector<int> array(n);
	        for( int i=0; i<n; ++i )
	            array.at(i) = (i*7)%n;
	        std::sort( array.begin(), array.end() );
	    }
	});
}

/*使用了并发容器 但CPU核只用了一个
 *是在不使用锁的情况下能够保证线程安全的容器。保证同一时间内只有一个线程来读/写此容器或者此容器的某一部分。
 *那岂不是对性能而言没什么?加上开销比标准STL还慢2倍*/
/*
 * 并发容器应该这样去用,多个线程对容器进行读写操作防止race而用到锁导致性能太差,这时就可以
 * 用并发容器,而不用锁,会提高性能。
 * */
void justconcurrent_vecot() {
	    for( int n=0; n<50000; n++) {
	    	tbb::concurrent_vector<int> array(n);
	        for( int i=0; i<n; ++i )
	            array.at(i) = (i*7)%n;
	        std::sort( array.begin(), array.end() );
	    }
	}

void withoutAnyparallel() {
	    for( int n=0; n<50000; n++) {
	        std::vector<int> array(n);
	        for( int i=0; i<n; ++i )
	            array.at(i) = (i*7)%n;
	        std::sort( array.begin(), array.end() );
	    }
	}

int maintbb() {
	std::cout<<std::endl<<std::endl;

	tbb::tick_count t1 = tbb::tick_count::now();
	withoutAnyparallel();
	tbb::tick_count t2 = tbb::tick_count::now();
	 std::cout<<"Time without any parallel tool =: "<<(t2-t1).seconds()<<std::endl;

	 tbb::tick_count t3 = tbb::tick_count::now();
	 justconcurrent_vecot();
	 tbb::tick_count t4 = tbb::tick_count::now();
	 std::cout<<"Time with concurrent_vector  = "<<(t4-t3).seconds()<<std::endl;

	 tbb::tick_count t5 = tbb::tick_count::now();
	 justparallel_for();
	 tbb::tick_count t6 = tbb::tick_count::now();
	 std::cout<<"Time with parallel for  = "<<(t6-t5).seconds()<<std::endl;

	 tbb::tick_count t7 = tbb::tick_count::now();
	 concurrent_parallel_for();
	 tbb::tick_count t8 = tbb::tick_count::now();
	 std::cout<<"Time with concurrent_vector and parallel_for = "<<(t8-t7).seconds()<<std::endl;

	return 0;
}

可以看到使用了TBB的parallel_for后大大提速了。而且CPU几个核都跑满了。不使用TBB时只有1个CPU在跑。  

但是我的concurrent_vector用法错误,所以时间测出来比不加TBB的普通容器慢2倍。因为并发容器就是多线程访问或写时不用自己加锁解锁使得线程安全,但如果是单线程调用,那么不存在需要锁的情况,其实用普通容器更快,这时候用并发容器没有作用,加上开销会导致其比普通容器慢很多。

The concurrent containers are in general slower than their STL counterparts in sequential code, but of course enable cocurrency and scalability in parallel code.So unfortunately if you do replace your containers with TBB everywherein a sequential application, you will likelysee a slowdown. The performance impact will varyfrom application to application depending on the usage scenario though. So it's something you would need to evaluate for your application.

There is no way to "locally disable synchronization" in the TBB containers. In some cases to create thread safe and scalable implementations, the internals vastly differ between the standard containers and TBB's concurrent containers. It's therefore not as easy as skipping a synchronization here or there to get back to STLs sequential performance.

 

"Generally speaking: Use for( or for_each when the amount of computation is small (not worth the overhead to parallelize). Use parallel_for when you have a large number of objects and each object has equal work of small work. Use parallel_for with appropriate grain size when you have a large number of objects and each object has un-equal work of small work. Use parallel_for_each when each objects work is relatively large and number of objects is few and each object has un-equal work. When number of objects is very small and known, consider using switch(nObjects) and cases using parallel_invoke in each case that you wish to impliment and parallel_for_each for the default case."

 

4.5.2的core模块的TBB作为backend原来其实选backend作为后端就是省略自己写TBB那一大段工作,效果与之一样,只是是由opencv帮我们做了而已。

 

 编译4.5.2过程需要下载的东西我都上传在此了 https://download.csdn.net/download/wd1603926823/18664183 需要的同志可自行下载。这里面的内容对于opencv4.x别的版本也是可用的,做适当更改即可。比如对于4.1.0可能TBB版本过高,那就自己根据其给的网址下一个低版本的TBB,比如ippicv的版本对,但md5码不对,那就改成4.1.0需要的md5即可。详情可参考之前的文章。

 

我查了下TBB与openmp混合编程,之前CMake时就已编译进去了omp,所以只用加上-fopenmp即可

但是我试了一下,并不如我所愿,而且要很小心乒乓效应,假共享现象。可能是我了解不够,不过暂时不想搞这个。

 

 

 

*****************************************TBB的使用感受****************************************************************

我盲目的试了一下,并不是将TBB运用到所有地方都能获得性能提升,有时往往相反。我以为原因是:

1、原本的耗时就很快,改成TBB,TBB并行开销本来就大,其开销大于带来的加速比,那么就变成了慢!甚至很慢!

如上,这个方法我没进行算法上的修改,本来使用TBB后耗时减少30s,但当我仅仅修改算法的时长后,第一个黄色部分这一次就比不使用TBB慢很多!!!然后书上说耗时大于1ms的才能考虑TBB,否则别考虑!!!但不是说大于1ms的用TBB就一定加速,我试过不一定。

2、当耗时足够长时,使用TBB后每个核都会跑起来,每个核都跑到将近100%就会很快!因为不用TBB时总是一个核在跑,其它核都在休息。如下图

绿色部分所有核都跑到飞起,性能提高;蓝色部分总是只有一个核在跑,其它核利用率低,所以性能很低。  但我只说对一半,前半句错了,并不是算法耗时足够长,用TBB时就能让所有核跑起来性能提升!至于原因我不知,我检查了TBB的确用上去了!但就是像串行一样始终只有一个核在飞,其它核始终在休息。而且我也检查了算法没有依赖性!我很苦恼!

这两点让我没了主意,到底何时该用TBB?!

然后我本来在看《Intel threading building blocks》,然而用处对我而言不大;现在我换成了《Pro TBB c++ programming》我觉得很有用!建议大家一定要去看!!!我现在才看到129页!

 

 

 

我在opencv官网看到这个,但是我查了很久,没看到有人使用C=,我在cmake中也没看到相关选项?!

 

inference:

https://docs.opencv.org/4.5.2/d7/dff/tutorial_how_to_use_OpenCV_parallel_for_.html

http://www.hoopoesnest.com/cstripes/cstripes-sketch.htm

The following error appears when i try to compile it ! solution: Add pthread library!

/usr/bin/ld: /tmp/cc2k3k3E.o: undefined reference to symbol 'sem_post@@GLIBC_2.2.5'
//lib/x86_64-linux-gnu/libpthread.so.0: error adding symbols: DSO missing from command line
collect2: error: ld returned 1 exit status

 我看这段介绍好像很厉害的样子,可以与TBB和OPENMP等兼容,但其网站和宣传资料2013年后就没更新了?!

C= package has no specific dependencies on language runtime or other libraries, which
implies its compatibility (subject to the above disclaimer) with other parallel
programming solutions (for instance, Intel Threading Building Blocks, OpenMP, and
Microsoft Concurrency Runtime). However, there may be occasional conflicts as
keywords defined by different parallel programming extensions may coincide: thus
OpenMP standard makes use of the parallel keyword: #pragma omp parallel . To
avoid such conflicts, the C= header file (C=.h) contains a special language customization
section that maps C= keywords to their internal codenames, for instance:
#define parallel CPX_KEYWORD_PARALLEL , which, in effect, enables a
programmer to redefine any C= keyword and avoid compilation conflicts.

 

 

 

 

 

 

 

 

 

 

 

TBB(Threading Building Blocks)是一个开源的C++线程库,可以用于并行化计算密集型任务。OpenCV库中包含了TBB模块,可以使用TBB库来加速一些OpenCV函数的处理速度。下面是使用TBB模块加速OpenCV函数的一般步骤: 1. 引入TBB库:在代码中引入TBB库头文件,例如: ```c++ #include "tbb/tbb.h" ``` 2. 创建并行任务:使用TBB库中的parallel_for函数创建并行任务,例如: ```c++ tbb::parallel_for(tbb::blocked_range<int>(0, n), [&](const tbb::blocked_range<int>& range) { for (int i = range.begin(); i < range.end(); ++i) { // 并行处理代码 } }); ``` 在这个示例中,parallel_for函数将任务分成多个块,并行处理每个块中的数据。在lambda表达式中,可以将要并行处理的代码放在for循环中。 3. 加速OpenCV函数:在并行任务中调用OpenCV函数,例如: ```c++ tbb::parallel_for(tbb::blocked_range<int>(0, n), [&](const tbb::blocked_range<int>& range) { for (int i = range.begin(); i < range.end(); ++i) { cv::Mat dst; cv::warpAffine(src, dst, M, cv::Size(width, height), cv::INTER_LINEAR); // 处理dst图像 } }); ``` 在这个示例中,warpAffine函数被调用了多次,并行处理多个图像。注意,在并行处理图像时需要使用不同的输出图像(即dst),以避免多线程写入同一个图像的问题。 需要注意的是,并不是所有的OpenCV函数都可以使用TBB模块加速。一些OpenCV函数已经使用了OpenMP或其他多线程库进行优化,或者不适合并行化处理。在使用TBB模块加速OpenCV函数之前,需要仔细考虑是否适合使用TBB模块,并进行性能测试以验证加速效果。
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

元气少女缘结神

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值