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

在上一篇文章中,我们成功验证了Intel Threading Building Blocks (TBB) 与 OpenMP 在多线程并行处理方面的加速潜力。为了更深入地理解这些技术在实际应用场景中的效能提升,接下来我们将目光转向目标开发板环境,进一步探究这两种框架在嵌入式系统上的实际加速效果。
一、OPENMP加速效果测试
在探讨OPENMP对性能提升的影响时,我们首先遇到了一个有趣的插曲。通常情况下,OpenMP作为一项编译器层面的支持特性,只需在编译阶段通过简单的命令行标志即可启用,例如在使用make构建时追加-fopenmp参数,或在CMake项目中配置如set(CMAKE_CXX_FLAGS “-fopenmp”),即可轻松为项目开启并行处理能力。

然而,在针对RV1106平台的交叉编译环境中,我们发现原生的交叉编译工具链并不支持OpenMP功能。通过执行arm-rockchip830-linux-uclibcgnueabihf-gcc -v来查看编译器详细信息时,注意到其构建选项中包含了–disable-libgomp,这意味着该编译器在构建之初就已排除了对OpenMP库的支持。这可能是因为RV1106芯片本身为单核架构,考虑到硬件资源有限,制造商在设计工具链时并未考虑多线程并行处理的需求。
RV1106交叉编译器能力
尽管如此,面对手头仅有的嵌入式开发环境限制,我们并未止步于此。经过深入研究和探索,最终成功实现了对该交叉编译器OpenMP支持的集成。虽然整个过程尚未完全优化与标准化,此处暂且略过具体实现细节,我们将简要概述如何使编译器支持OpenMP以及随后进行的测试效果评估。

交叉编译器不支持的临时解决办法:
1、从源码编译openmp:
官网介绍:https://www.openmp.org/specifications/
下载地址:https://github.com/OpenMP/sources
编译过程比较简单:在源码中将makefile的configure 后面指定当前的编译工具链路径和生产路径。

all: mkdir src/libgomp/build ;          \cd src/libgomp/build &&            \../configure --host=arm-rockchip830-linux-uclibcgnueabihf && \$(MAKE)

2、编译好的libgomp放入工具链
我生成的libgomp 路径在 libgomp-master\src\libgomp\build.libs 下面,将其中的
libgomp.so libgomp.so.1 libgomp.so.1.0.0 以及上一级目录的libgomp.spec 一共四个文件拷贝到工具链的以下两个路径:

/arm-rockchip830-linux-uclibcgnueabihf/arm-rockchip830-linux-uclibcgnueabihf/lib/lib
/arm-rockchip830-linux-uclibcgnueabihf/arm-rockchip830-linux-uclibcgnueabihf/sysroot/lib/

编译测试:
在编译过程中,直接加入-fopenmp指令:

arm-rockchip830-linux-uclibcgnueabihf-g++ OptCvTestWin.cpp -o test -fopenmp

即可生成可执行文件。
此处不用cmake编译,因为写好的cmakelist中配置的-fopenmp不生效。

加速效果:

# ./test cv F1 Time = 79  rslt 3.20518e+10cv F2 Time = 153  rslt 3.20518e+10cv F1 Time = 91  rslt 2.99779e+10cv F2 Time = 166  rslt 2.99779e+10cv F1 Time = 76  rslt 2.93042e+10cv F2 Time = 166  rslt 2.93042e+10cv F1 Time = 75  rslt 3.1813e+10cv F2 Time = 158  rslt 3.1813e+10cv F1 Time = 75  rslt 3.18925e+10cv F2 Time = 177  rslt 3.18925e+10cv F1 Time = 81  rslt 3.07783e+10cv F2 Time = 158  rslt 3.07783e+10cv F1 Time = 90  rslt 3.05833e+10cv F2 Time = 156  rslt 3.05833e+10cv F1 Time = 76  rslt 2.83669e+10cv F2 Time = 158  rslt 2.83669e+10cv F1 Time = 91  rslt 3.42625e+10cv F2 Time = 170  rslt 3.42625e+10cv F1 Time = 75  rslt 3.44049e+10cv F2 Time = 163  rslt 3.44049e+10

对比了多线程方案F1与常规单线程方案F2的执行速度(单位ms)。实验发现,随着OpenMP线程数从2增至10,F1的加速效果逐步提升;但超过10个线程后,加速收益不再明显增加。这表明存在一个最优线程数阈值,在该范围内使用OpenMP能有效提高程序性能。

测试的代码放出来:
整体上跑10遍观察效果,选取其中一部分数据打印看结果是否一致。

#include <fstream>
#include <iostream>
#include <vector>
//#include <opencv2/opencv.hpp>
//#include "libgomp.h"
#include <future>
#include <thread>
//#include <tbb/parallel_for.h>
//#include <tbb/blocked_range.h>
#include <chrono>
//using namespace cv;
using namespace std;typedef std::chrono::system_clock::time_point SYS_TIME;
SYS_TIME getClock()
{return std::chrono::system_clock::now();
}
double getMsTime(SYS_TIME start, SYS_TIME end)
{return  std::chrono::duration_cast<std::chrono::milliseconds>(end-start).count();
}
int main()
{for (int j =0; j <10; j++)
{const int iCnt = 1000000;std::vector<float> data1(iCnt);std::vector<float> data2(iCnt);for (float i = 0; i < iCnt; ++i) {data1[i] = rand(); // 假设填充了随机整数data2[i] = data1[i];}float fv1=0;SYS_TIME start = getClock();
#pragma omp parallel num_threads(4){
#pragma omp forfor(int i = 0; i < iCnt; i++){data1[i]+=i;if(i>iCnt/3&&i<iCnt/3+30)fv1+=data1[i];}}cout << " cv F1 Time = " << getMsTime(start, getClock()) <<"  rslt "<< fv1  << endl;float fv2=0;SYS_TIME start2 = getClock();{for (float i = 0; i < iCnt; i++){data2[i]+=i;if(i>iCnt/3&&i<iCnt/3+30)fv2+=data2[i];}}cout << " cv F2 Time = " << getMsTime(start2, getClock()) <<"  rslt "<< fv2  << endl;
}    return 0;
}

后记:
在本阶段的技术探索中,我们遇到了CMakeLists.txt中设置的OpenMP编译选项未能生效的问题。尽管GPT暂时无法给出具体原因,但当前的重点已转向验证OpenMP的实际加速效果,并发现尽管其在基准测试中表现出显著优势,但在实际业务工程应用时却遭遇了挑战。由于现有工程完全依赖于由CMake构建的Makefile体系,直接修改Makefile以整合OpenMP支持无疑会增加额外的工作量。
在这里插入图片描述
1、一种解决方案是联系RK(瑞芯微)厂家,请求提供一个内建OpenMP支持的交叉编译器版本,或者自行构建这样一个工具链。然而,鉴于目前的知识储备尚不足以完成这一任务,该方案暂时尚未实施
2、另个一个可行的方案是,将预先编译好的libgomp库作为静态或动态链接库与可执行文件进行链接。这种方法虽然理论上可行,但在调用OpenMP接口和管理库依赖方面可能会遇到复杂性问题,需要进一步技术评估。

接下来的步骤,我们将把注意力转向Intel Threading Building Blocks (TBB) 并行编程库,计划对其进行编译和测试验证,以对比分析其对项目性能提升的效果。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/666999.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

vulhub中spring的CVE-2022-22965漏洞复现

在JDK 9上运行的Spring MVC或Spring WebFlux应用程序可能存在通过数据绑定执行远程代码&#xff08;RCE&#xff09;的漏洞。 现在已知的利用方法要求应用程序以WAR部署的形式在Tomcat上运行&#xff0c;然而&#xff0c;该漏洞的性质更为普遍&#xff0c;可能有其他方法可以利…

[职场] 老教师对年轻教师的肺腑之言 #媒体#笔记

老教师对年轻教师的肺腑之言 对学生 不要拖堂&#xff01;不要拖堂&#xff01;不要拖堂&#xff01;临下课十分钟&#xff0c;学生已经心不在焉&#xff0c;更别说下课后了&#xff01;有什么内容等下节课再说&#xff0c;不连贯没关系&#xff0c;反正拖堂讲课他们更听不进去…

利用ReentrantLock解决死锁----以哲学家问题为例

问题描述 哲学家问题&#xff1a;其中多个哲学家在共享有限资源&#xff08;筷子&#xff09;的情况下进行工作&#xff08;思考和吃饭&#xff09;&#xff0c;这可能导致死锁。 每位哲学家需要两根筷子才能吃饭&#xff0c;而每根筷子只能被一位哲学家使用&#xff0c;这就…

91.网游逆向分析与插件开发-游戏窗口化助手-游戏窗口化助手的UI设计

内容参考于&#xff1a;易道云信息技术研究院VIP课 上一个内容&#xff1a;项目需求与需求拆解-CSDN博客 码云地址&#xff08;游戏窗口化助手 分支&#xff09;&#xff1a;https://gitee.com/dye_your_fingers/sro_-ex.git 码云版本号&#xff1a;e512d44da1b7e6a8726b1be0…

【Linux取经路】进程控制——程序替换

文章目录 一、单进程版程序替换看现象二、程序替换的基本原理三、程序替换接口学习3.1 替换自己写的可执行程序3.2 第三个参数 envp 验证四、结语一、单进程版程序替换看现象 #include <stdio.h> #

【Linux进程间通信】匿名管道

【Linux进程间通信】匿名管道 目录 【Linux进程间通信】匿名管道进程间通信介绍进程间通信目的进程间通信发展进程间通信分类 管道用fork来共享管道原理站在文件描述符角度——深度理解管道站在内核角度——管道本质 匿名管道在myshell中添加管道的实现&#xff1a;管道读写规则…

jss/css/html 相关的技术栈有哪些?

js 的技术组件有哪些&#xff1f;比如 jQuery vue 等 常见的JavaScript技术组件&#xff1a; jQuery&#xff1a; jQuery是一个快速、小巧且功能丰富的JavaScript库&#xff0c;用于简化DOM操作、事件处理、动画效果等任务。 React&#xff1a; React是由Facebook开发的用于构…

STM32--HAL库定时器学习记录(易懂)--持续学习

一、什么是定时器 定时器就是计数器&#xff0c;通过计数完成一系列功能。 二、定时器的分类 定时器分为基本定时器、通用定时器、高级定时器。级别不同&#xff0c;功能不同。级别越高&#xff0c;功能越强。 三、定时器&#xff08;计数器&#xff09;三个重要寄存器 预分…

问题:金属电化学反应的实质是氧化还原反应,被腐蚀金属发生还原反应( ) #知识分享#知识分享#媒体

问题&#xff1a;金属电化学反应的实质是氧化还原反应&#xff0c;被腐蚀金属发生还原反应(  ) A、正确 B、错误 参考答案如图所示

Ainx框架实现 一

&#x1f4d5;作者简介&#xff1a; 过去日记&#xff0c;致力于Java、GoLang,Rust等多种编程语言&#xff0c;热爱技术&#xff0c;喜欢游戏的博主。 &#x1f4d7;本文收录于Ainx系列&#xff0c;大家有兴趣的可以看一看 &#x1f4d8;相关专栏Rust初阶教程、go语言基础系列…

Powershell Install 一键部署Prometheus

前言 Prometheus是一个开源的系统监控和报警系统,现在已经加入到CNCF基金会,成为继k8s之后第二个在CNCF托管的项目,在kubernetes容器管理系统中,通常会搭配prometheus进行监控,同时也支持多种exporter采集数据,还支持pushgateway进行数据上报,Prometheus性能足够支撑上…

计算机毕业设计 | vue+SpringBoot图书借阅管理系统(附源码)

1&#xff0c; 概述 1.1 课题背景 随着现在科学技术的进步&#xff0c;人类社会正逐渐走向信息化&#xff0c;图书馆拥有丰富的文献信息资源&#xff0c;是社会系统的重要组成部分&#xff0c;在信息社会中作用越来越重要&#xff0c;在我国图书馆计算机等 信息技术的应用起步…

docker安装-centos

Docker CE 支持 64 位版本 CentOS 7&#xff0c;并且要求内核版本不低于 3.10 卸载旧版本Docker sudo yum remove docker \ docker-common \ docker-selinux \ docker-engine使用yum安装 yum 更新到最新版本: sudo yum update执行以下命令安装依赖包&#xff1a; sudo yum…

PyTorch 2.2 中文官方教程(十五)

&#xff08;beta&#xff09;计算机视觉的量化迁移学习教程 原文&#xff1a;pytorch.org/tutorials/intermediate/quantized_transfer_learning_tutorial.html 译者&#xff1a;飞龙 协议&#xff1a;CC BY-NC-SA 4.0 提示 为了充分利用本教程&#xff0c;我们建议使用这个C…

vue中使用html2canvas配合jspdf导出pdf(以及在导出时遇到的导出样式问题)

指定页面中导出为pdf格式并打包&#xff0c;使用html2canvas先转为图片格式&#xff0c;在利用jspdf转为pdf&#xff0c;最后下载打包为本地压缩包 yarn add html2canvas yarn add jspdf1. 注册一个插件并挂载 import html2Canvas from html2canvas import JsPDF from jspdf …

记一次生产系统每隔10小时(36000000毫秒)固定进行一次Full GC排查思路

一、 背景描述 某个应用在生产环境通过系统监控发现&#xff0c;应用每隔10小时就会触发一次Full GC&#xff0c;该系统当时承接的业务量并不大&#xff0c;而且固定10小时就会进行Full GC&#xff0c;通过监控时间轴发现Full GC频率很规律&#xff0c;直觉告诉我这不是JVM自身…

寒假 day1

1、请简述栈区和堆区的区别? 2、有一个整形数组:int arr[](数组的值由外部输入决定)&#xff0c;一个整型变量: x(也 由外部输入决定)。要求: 1)删除数组中与x的值相等的元素 2)不得创建新的数组 3)最多只允许使用单层循环 4)无需考虑超出新数组长度后面的元素&#xff0c;所以…

【lesson40】理解文件系统

文章目录 问题磁盘结构&#xff08;物理&#xff09;磁盘的存储结构磁盘的抽象结构 问题 1.有没有没有被打开的文件&#xff1f;当然有 在哪里呢&#xff1f;磁盘中也叫磁盘级文件 2.学习磁盘级别文件的侧重点在哪&#xff1f; 站在单个文件角度: 这个文件在哪里&#xff1f…

【Linux】权限管理

&#x1f525;博客主页&#xff1a; 小羊失眠啦. &#x1f3a5;系列专栏&#xff1a;《C语言》 《数据结构》 《C》 《Linux》 《Cpolar》 ❤️感谢大家点赞&#x1f44d;收藏⭐评论✍️ 文章目录 一 、Linux中的用户1.1 Linux用户分类1.2 用户转换1.3 指令提权 二、Linux权限管…

企业网络采用SD-WAN的优势

近年来&#xff0c;SD-WAN成为企业网络领域的一项热门技术&#xff0c;为传统网络带来了新的变革。SD-WAN&#xff08;Software Defined Wide Area Network&#xff0c;软件定义广域网&#xff09;以其灵活性、可管理性和低成本而备受青睐。它不仅能够创建成熟的专用网络&#…