SIMD——请不要妄图优化opencv的函数

2023-11-21 15:10

本文主要是介绍SIMD——请不要妄图优化opencv的函数,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

大纲

  • ORB-SLAM特征提取之SIMD优化
    • 一、优化手段
      • 1、NEON
      • 2、SSE
    • 二、cv::gaussianblur函数优化
    • 三、cv::FAST函数优化
    • 四、原因分析

ORB-SLAM特征提取之SIMD优化

一、优化手段

1、NEON

NEON是基于ARM架构的一种128位的SIMD(Single Instruction, Multiple Data,单指令、多数据)的拓展结构,具体的细节在这里不做过多的介绍,我们来讨论NEON在实际工程中的两种使用方式:

(1)汇编

相信学习过单片机的朋友对汇编语言一定都是又恨又怕,复杂的指令与奇怪的逻辑令人望而却步,我们来看一小段基于汇编的NEON指令:

 "vld1.8       {d8,d9}, [%[in0]]\n\t""add          %[in0], %[step]\n\t""vld1.8       {d10,d11}, [%[in1]]\n\t""add          %[in1], %[step]\n\t""vld1.8       {d12,d13}, [%[in0]]\n\t""add          %[in0], %[step]\n\t""vld1.8       {d14,d15}, [%[in1]]\n\t"

什么东西?这是什么东西!说实话,我也看不太懂,所以基于汇编的NEON指令难度大,可移植性差,但是由于汇编语言的特性,决定了它具有很高的效率。Anyway,我们来看下一种方式。

(2)使用arm提供的Intrinsics函数
可以认为是内联函数,但是在编译时编译器会将函数转化为neon指令。调用该函数需要包含头文件arm_neon.h,该头文件包含了neon各种操作函数。当然,我在这里同样来展示一段代码:

 for(; j < img.cols - 16 - 3; j += 16, ptr += 16){uint8x16_t m0,m1;uint8x16_t v0 = vld1q_u8((const uint8_t*)ptr);uint8x16_t v1 = vqsubq_u8(v0,t);v0 = vqaddq_u8(v0,t);

了解过NEON的同学这段代码应该不难看懂,就是简单的加减法,我们可以看到,这种内联方式的NEON代码指令难度低,可移植行也就比汇编形式的高很多。

2、SSE

SSE是Intel x86架构CPU的SIMD指令的简称,与NEON一样具有汇编和内联函数两种形式。

二、cv::gaussianblur函数优化

由于本次实验的电脑是intel的CPU,所以采用SSE优化的方式对高斯模糊函数进行优化,在优化之前,记录了cv::gaussianblur函数的效率如下图所示:在这里插入图片描述9.41ms,在我的认知领域内,应该不是具有很高效率的时常,所以我对该函数进行了SSE优化,对gaussainblur函数的源码进行了修改,执行时间如下:在这里插入图片描述惊人的148ms。当然,如果你需要的源码,可以私信我,我发给你自己run一下。总的来说,这并不是一次非常愉快的优化过程,同样的,接下来的SSE优化也令我大跌眼镜。

三、cv::FAST函数优化

FAST提取图像中的特征点是ORB-SLAM系列中使用的一种方法,具体原理不再赘述,因为这毕竟不是一篇介绍SLAM算法的blog,我们来看opencv实现的FAST函数耗时如何:在这里插入图片描述
结果是2.65ms,不得不说opencv优化的已经很好了。注意!!!这里使用了和ORBSLAM2中相同的阈值:20。在ORBSLAM2中该函数在网格的循环遍历中被调用,ORBSLAM2将图像分为30x30个网格,在每个网格中进行FAST角点检测,经过测量,每个网格中耗时约为0.02ms,为什么差异这么大呢,首先于ORBSLAM中独特的网格划分有关系,其次与图像的大小也有关系。接下来,我们来看我进行了SSE优化的代码,相关代码已经有NEON实现,你需要做的只是将NEON转化为SSE即可:在这里插入图片描述50ms。。唉,当我看到这个结果的时候,心里有一种说不出的酸楚…

四、原因分析

实验失败不可怕,可怕的是不分析为什么失败,经过资料的查询与文献的阅读我大概的掌握了其中的奥义。

(1)OpenCV的函数自带SIMD加速,无论是gaussainblur还是FAST都自带了SMID的并行加速,并且OpenCV代码结构和顺序更加合理,能够更好的发挥CPU的全部性能
(2)OpenCV的优化是按照运行环境中CPU的架构来决定的,我们知道到INTEL的SIMD指令集avx512是高于SSE的,由于我运行的环境中支持avx512,所以使用该指令集的优化代码效率必然高于SSE。
(3)最终的建议是:别动OpenCV的源码为好,除非用汇编…,这得是神人来写了。

这篇关于SIMD——请不要妄图优化opencv的函数的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/403146

相关文章

Python itertools中accumulate函数用法及使用运用详细讲解

《Pythonitertools中accumulate函数用法及使用运用详细讲解》:本文主要介绍Python的itertools库中的accumulate函数,该函数可以计算累积和或通过指定函数... 目录1.1前言:1.2定义:1.3衍生用法:1.3Leetcode的实际运用:总结 1.1前言:本文将详

Deepseek使用指南与提问优化策略方式

《Deepseek使用指南与提问优化策略方式》本文介绍了DeepSeek语义搜索引擎的核心功能、集成方法及优化提问策略,通过自然语言处理和机器学习提供精准搜索结果,适用于智能客服、知识库检索等领域... 目录序言1. DeepSeek 概述2. DeepSeek 的集成与使用2.1 DeepSeek API

轻松上手MYSQL之JSON函数实现高效数据查询与操作

《轻松上手MYSQL之JSON函数实现高效数据查询与操作》:本文主要介绍轻松上手MYSQL之JSON函数实现高效数据查询与操作的相关资料,MySQL提供了多个JSON函数,用于处理和查询JSON数... 目录一、jsON_EXTRACT 提取指定数据二、JSON_UNQUOTE 取消双引号三、JSON_KE

MySQL数据库函数之JSON_EXTRACT示例代码

《MySQL数据库函数之JSON_EXTRACT示例代码》:本文主要介绍MySQL数据库函数之JSON_EXTRACT的相关资料,JSON_EXTRACT()函数用于从JSON文档中提取值,支持对... 目录前言基本语法路径表达式示例示例 1: 提取简单值示例 2: 提取嵌套值示例 3: 提取数组中的值注意

Tomcat高效部署与性能优化方式

《Tomcat高效部署与性能优化方式》本文介绍了如何高效部署Tomcat并进行性能优化,以确保Web应用的稳定运行和高效响应,高效部署包括环境准备、安装Tomcat、配置Tomcat、部署应用和启动T... 目录Tomcat高效部署与性能优化一、引言二、Tomcat高效部署三、Tomcat性能优化总结Tom

解读Redis秒杀优化方案(阻塞队列+基于Stream流的消息队列)

《解读Redis秒杀优化方案(阻塞队列+基于Stream流的消息队列)》该文章介绍了使用Redis的阻塞队列和Stream流的消息队列来优化秒杀系统的方案,通过将秒杀流程拆分为两条流水线,使用Redi... 目录Redis秒杀优化方案(阻塞队列+Stream流的消息队列)什么是消息队列?消费者组的工作方式每

Java function函数式接口的使用方法与实例

《Javafunction函数式接口的使用方法与实例》:本文主要介绍Javafunction函数式接口的使用方法与实例,函数式接口如一支未完成的诗篇,用Lambda表达式作韵脚,将代码的机械美感... 目录引言-当代码遇见诗性一、函数式接口的生物学解构1.1 函数式接口的基因密码1.2 六大核心接口的形态学

Oracle查询优化之高效实现仅查询前10条记录的方法与实践

《Oracle查询优化之高效实现仅查询前10条记录的方法与实践》:本文主要介绍Oracle查询优化之高效实现仅查询前10条记录的相关资料,包括使用ROWNUM、ROW_NUMBER()函数、FET... 目录1. 使用 ROWNUM 查询2. 使用 ROW_NUMBER() 函数3. 使用 FETCH FI

C#使用HttpClient进行Post请求出现超时问题的解决及优化

《C#使用HttpClient进行Post请求出现超时问题的解决及优化》最近我的控制台程序发现有时候总是出现请求超时等问题,通常好几分钟最多只有3-4个请求,在使用apipost发现并发10个5分钟也... 目录优化结论单例HttpClient连接池耗尽和并发并发异步最终优化后优化结论我直接上优化结论吧,

Java内存泄漏问题的排查、优化与最佳实践

《Java内存泄漏问题的排查、优化与最佳实践》在Java开发中,内存泄漏是一个常见且令人头疼的问题,内存泄漏指的是程序在运行过程中,已经不再使用的对象没有被及时释放,从而导致内存占用不断增加,最终... 目录引言1. 什么是内存泄漏?常见的内存泄漏情况2. 如何排查 Java 中的内存泄漏?2.1 使用 J