在接续前文的内容中,本章节旨在记录在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方法的支持能力,期待能在这个性能更强的平台上取得突破。