Opencv(C++)学习 TBB与OPENMP的加速效果实验与ARM上的实践(三)

在接续前文的内容中,本章节旨在记录在RV1106平台上尝试运用TBB(Intel Threading Building Blocks)的实践过程,这一经历依然复杂而难以言尽。当前选用的TBB版本为oneTBB-2021.11.0,该版本支持通过cmake进行编译构建。

源码下载,编译TBB
下载地址: https://github.com/oneapi-src/oneTBB
版本使用 oneTBB-2021.11.0,这个版本可以使用cmake编译。

在顺利完成cmake配置之后,进入生成的build目录,并执行make命令进行编译。理论上,在正常情况下,编译过程应能顺利进行,然而遗憾的是,在实际操作中我们遇到了以下错误信息:

/media/oneTBB/src/tbb/../../include/oneapi/tbb/detail/_machine.h:328:5: error: 'fenv_t' does not name a type; did you mean 'dev_t'?
     fenv_t *my_fenv_ptr;
     ^~~~~~
     dev_t
compilation terminated due to -Wfatal-errors

经过深入调查,问题涉及到了与硬件紧密相关的浮点环境类型fenv_t。起初推测该问题是由于可能未包含对应的头文件导致的,因此,在交叉编译环境中我特意找到了并尝试引入了fenv.h头文件到报错的部分,然而即便如此,错误依旧未能解决。

进一步排查发现,问题的关键在于相关宏定义的缺失。为验证fenv.h头文件本身的有效性及兼容性,我决定进行单独的测试以确认其在当前RV1106平台上的适用性。

验证浮点环境的有效性
需要关注的点包括以下几个部分:
1、确认编译工具链支持度:首先确保所使用的交叉编译工具链包含了符合C99标准的编译器(例如gcc或clang),并且附带了相应的库支持,这对于正确处理 <fenv.h> 中的相关功能至关重要

2、查找并确认头文件存在:在交叉编译工具链的头文件目录中检查 <fenv.h> 是否存在,这是实现浮点环境管理功能的基础依赖。

3、设定编译参数:在编译时通过添加 -std=c99 或 -std=gnu99 参数强制使用C99语言标准。对于混合C++代码的情况,还需确保编译器能够同时支持C++和C99标准的混合编译。

4、启用特定宏定义:针对某些交叉编译环境,可能需要启用类似 _GLIBCXX_USE_C99_FENV_TR1 的宏定义以开启对C99浮点环境的支持。

5、编写及执行测试程序:基于以上条件,编写一个简洁的示例程序,用以调用 <fenv.h> 中的浮点环境管理函数,并利用交叉编译工具链进行编译链接。然后将生成的目标文件部署至目标平台上运行,通过实际执行结果来验证 <fenv.h> 功能的有效性和完整性。

依据上述指导原则,已编写了一段代码片段用于进行编译验证过程。
tt.cpp

//#include "fenv.h"
#include <cfenv>
#include <iostream>
class cpu_ctl_env {

    fenv_t *my_fenv_ptr;
};
int main()
{
	int cc = 55;
	std::cout<<"cc " <<cc<<std::endl;
	//int cc = MAXTEST;
	//std::cout<<"Test cc"<< cc <<std::endl;
	return 0;
}

编译验证:
1、直接使用环境UBUNTU自带的指令
运行结果正常:

root@ubuntu:/media/test# g++ -std=c++11 -D_GLIBCXX_USE_C99_FENV_TR1=1 tt.cpp -o tt
root@ubuntu:/media/test# ./tt
cc 55
root@ubuntu:/media/test# 

2、使用交叉编译工具链:

root@ubuntu:/media/test# /opt/toolchain/arm-rockchip830-linux-uclibcgnueabihf/bin/arm-rockchip830-linux-uclibcgnueabihf-g++  -std=c++11 -D_GLIBCXX_USE_C99_FENV_TR1=1 tt.cpp -o tt
In file included from tt.cpp:2:
/opt/toolchain/arm-rockchip830-linux-uclibcgnueabihf/arm-rockchip830-linux-uclibcgnueabihf/include/c++/8.3.0/cfenv:61:11: error: '::fenv_t' has not been declared
   using ::fenv_t;
           ^~~~~~
/opt/toolchain/arm-rockchip830-linux-uclibcgnueabihf/arm-rockchip830-linux-uclibcgnueabihf/include/c++/8.3.0/cfenv:62:11: error: '::fexcept_t' has not been declared
   using ::fexcept_t;
   ....
   ....
   ....

根据编辑结果的前部分显示,我们观察到存在“未定义”的编译错误。在对交叉编译工具链中包含的 头文件进行深入检查时,发现fenv_t的定义确实存在于其中,然而即便如此,在实际编译阶段仍未能顺利通过。为了尝试解决此问题,我们引入了C++命名空间std(尽管浮点环境通常与C99标准相关,而非C++),但这一举措并未奏效。随后,我们改用 <fenv.h> 头文件替换 ,遗憾的是,这一调整同样导致了相同的编译错误。

#ifndef _GLIBCXX_CFENV
#define _GLIBCXX_CFENV 1

#pragma GCC system_header

#if __cplusplus < 201103L
# include <bits/c++0x_warning.h>
#else

#include <bits/c++config.h>

#if _GLIBCXX_HAVE_FENV_H
# include <fenv.h>
#endif

#ifdef _GLIBCXX_USE_C99_FENV_TR1

#undef feclearexcept
#undef fegetexceptflag
#undef feraiseexcept
#undef fesetexceptflag
#undef fetestexcept
#undef fegetround
#undef fesetround
#undef fegetenv
#undef feholdexcept
#undef fesetenv
#undef feupdateenv

namespace std
{
  // types
  using ::fenv_t;
  using ::fexcept_t;

  // functions
  using ::feclearexcept;
  using ::fegetexceptflag;
  using ::feraiseexcept;
  using ::fesetexceptflag;
  using ::fetestexcept;

  using ::fegetround;
  using ::fesetround;

  using ::fegetenv;
  using ::feholdexcept;
  using ::fesetenv;
  using ::feupdateenv;
} // namespace std

#endif // _GLIBCXX_USE_C99_FENV_TR1

#endif // C++11

#endif // _GLIBCXX_CFENV

至此,经过一系列尝试与验证后,我们得出结论:在RV1106平台上当前无法支持浮点环境功能,进而导致无法利用TBB进行软件加速。这一困境使得我们不得不考虑采用更为传统且繁琐的手动线程优化方法来提升性能。

不过,在面对挑战的同时,我计划采取新的解决方案。下一步将转而使用针对RV1126平台的交叉编译工具链进行测试,以评估RV1126是否具备对浮点环境及相应TBB方法的支持能力,期待能在这个性能更强的平台上取得突破。

  • 5
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
DPM(Deformable Part-based Model) Cascade是一种常用的目标检测算法,在OpenCV 3.0中已经支持。在DPM Cascade中,目标被分为多个部分,每个部分用一个分类器来检测,这些分类器被组成一个级联分类器,来提高检测速度和准确率。 TBBOpenMP是常用的多线程库,可以加速DPM Cascade的检测。在使用TBBOpenMP之前,需要先安装它们。在Linux系统中,可以通过以下命令安装: ``` sudo apt-get install libtbb-dev sudo apt-get install libomp-dev ``` 在Windows系统中,可以在Intel官网下载TBBOpenMP的安装程序进行安装。 下面是基于OpenCV 3.0的DPM Cascade检测代码,附带TBBOpenMP加速: ```python import cv2 import numpy as np # 加载级联分类器 cascade = cv2.CascadeClassifier('path/to/cascade.xml') # 加载图像 img = cv2.imread('path/to/image.jpg') # 转换为灰度图像 gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) # 检测目标 rects = cascade.detectMultiScale(gray, scaleFactor=1.3, minNeighbors=3, minSize=(30, 30), flags=cv2.CASCADE_SCALE_IMAGE) # 绘制矩形框 for (x, y, w, h) in rects: cv2.rectangle(img, (x, y), (x+w, y+h), (0, 255, 0), 2) # 显示结果 cv2.imshow('result', img) cv2.waitKey(0) cv2.destroyAllWindows() ``` 加入TBBOpenMP加速的代码如下: ```python import cv2 import numpy as np import time import threading import multiprocessing # 加载级联分类器 cascade = cv2.CascadeClassifier('path/to/cascade.xml') # 加载图像 img = cv2.imread('path/to/image.jpg') # 转换为灰度图像 gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) # 检测目标 start_time = time.time() rects = cascade.detectMultiScale(gray, scaleFactor=1.3, minNeighbors=3, minSize=(30, 30), flags=cv2.CASCADE_SCALE_IMAGE) end_time = time.time() print('串行检测时间:', end_time-start_time) # 绘制矩形框 for (x, y, w, h) in rects: cv2.rectangle(img, (x, y), (x+w, y+h), (0, 255, 0), 2) # 显示结果 cv2.imshow('result', img) cv2.waitKey(0) cv2.destroyAllWindows() # TBB并行检测 def detect_with_tbb(gray, cascade): rects = cascade.detectMultiScale(gray, scaleFactor=1.3, minNeighbors=3, minSize=(30, 30), flags=cv2.CASCADE_SCALE_IMAGE) return rects start_time = time.time() tbb_results = [] tbb = threading.Thread(target=tbb_results.append, args=(detect_with_tbb(gray, cascade),)) tbb.start() tbb.join() end_time = time.time() print('TBB检测时间:', end_time-start_time) # 绘制矩形框 for (x, y, w, h) in tbb_results[0]: cv2.rectangle(img, (x, y), (x+w, y+h), (0, 255, 0), 2) # 显示结果 cv2.imshow('result', img) cv2.waitKey(0) cv2.destroyAllWindows() # OpenMP并行检测 def detect_with_omp(gray, cascade): rects = cascade.detectMultiScale(gray, scaleFactor=1.3, minNeighbors=3, minSize=(30, 30), flags=cv2.CASCADE_SCALE_IMAGE) return rects start_time = time.time() omp_results = [] omp = multiprocessing.Process(target=omp_results.append, args=(detect_with_omp(gray, cascade),)) omp.start() omp.join() end_time = time.time() print('OpenMP检测时间:', end_time-start_time) # 绘制矩形框 for (x, y, w, h) in omp_results[0]: cv2.rectangle(img, (x, y), (x+w, y+h), (0, 255, 0), 2) # 显示结果 cv2.imshow('result', img) cv2.waitKey(0) cv2.destroyAllWindows() ``` 在上面的代码中,我们使用了Python的多线程库threading和多进程库multiprocessing来实现TBBOpenMP的并行化。通过比较串行检测时间和并行检测时间,可以看出TBBOpenMP都可以有效地加速DPM Cascade的检测。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

沉木渡香

感谢鼓励!

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

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

打赏作者

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

抵扣说明:

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

余额充值