热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

算法加速的一些方法思路

文章目录0引入1、算法优化2、语言选择3、算法并行3.1指令集加速3.2多核编程3.3CUDA编程加速4、汇编加速5、硬件加速6、引用0引入在实际软件层面应用来说,


文章目录

  • 0 引入
  • 1、算法优化
  • 2、语言选择
  • 3、算法并行
    • 3.1 指令集加速
    • 3.2 多核编程
    • 3.3 CUDA 编程加速
  • 4、汇编加速
  • 5、硬件加速
  • 6、引用




0 引入

在实际软件层面应用来说,一把算法的执行速度还是能够满足需求的,但是在大数据和复杂计算的过程中,由于算法模型的选择和硬件甚至是语言的选择都会影响到算法输出结果的时间,在实时性要求比较高的场合,算法加速往往是绕不开的话题,本文从算法到最后输出的环节,来提供一些可以优化的思想
在这里插入图片描述


  • 算法优化,指降低算法计算复杂度,设计新算法快速求解,比如Hungarian匹配算法。或牺牲一些内存,预计算一些重复计算的过程,减少程序层面的复杂度。
  • 语言更换,指将自己算法迁移到更加底层的算法,越是低级的算法,执行速度越快。常见地,将Matlab、Python等解释性代码移植到C++平台,往往有5-20倍的加速效果。
  • 算法并行,指将自己算法的独立计算部分,分成几块,利用CPU指令集、多核或GPU的特性实现加速。多核并行和CUDA并行最为常见。
  • 汇编加速,将自己的一片代码指定为自己设计的汇编语言。多种C++编译器实际上也是将语言转换为汇编代码,对汇编进行加速在嵌入式中常见。(该方法对平台有需求,并不常见)
  • 硬件加速,利用特殊硬件处理特殊算法,降低CPU架构的复杂度。常见的就是FPGA。
  • cccccccccccccccccccc光学加速,利用参数制作特定的光散射模型,输入目标光源直接得到输出结果。(离谱的加速方式,目前停留在概念)

1、算法优化

算法优化分为两种类型:① 降低算法复杂度;② 减少重复计算过程。




2、语言选择

**越是高级的语言,开发效率越高,执行速度越慢。**

  • 尽量用当前语言的官方库,官方库往往对算法做了足够的加速。
  • 将部分简单函数编译成C++进行调用,比如Python调用C++,或Matlab调用C++。
  • 对并行性较强的,且用了少量STL库的算法使用CUDA加速。
  • 大矩阵运算考虑Eigen,cublas等专用库。
  • 对并行性较强,且用了大量STL库的算法使用多核并行加速。
    将高级代码转换为C++项目,这也是最简单的转换方法了,这样开发出的算法非常容易落地


3、算法并行

**并行思想从小到大可以总结为:**指令集开发->多核并行->CUDA**并行,**

3.1 指令集加速

指令集加速,一般是针对CPU架构进行的底层优化,常见于OpenCV和Tensorflow的CPU版本。之所以OpenCV是个经典的开源图像框架,很大原因是因为其在多个平台上执行效率很高,其中底层的优化,比如指令集优化,起到了关键作用。

数据并行的两种实现在计算机体系中,数据并行有两种实现路径:


  • MIMD(Multiple Instruction Multiple Data,多指令流多数据流)。MIMD的表现形式主要有多发射、多线程、多核心,在当代设计的以处理能力为目标驱动的处理器中,均能看到它们的身影。

  • SIMD(Single Instruction Multiple Data,单指令流多数据流)。随着多媒体、大数据、人工智能等应用的兴起,为处理器赋予SIMD处理能力变得愈发重要,因为这些应用存在大量细粒度、同质、独立的数据操作,而SIMD天生就适合处理这些操作。SIMD本身并不是一种指令集,而是一种处理思想,现在的一些指令集都支持SIMD。(简单来说,计算1000维向量的点积,乘法是独立的,多核心不值得,这时候就可以利用指令集一次性计算4次或8次乘法,同样的,之后的加法也同样可以用指令集计算)
    CPU指令集的发展(针对Intel的x86指令集系列):

  • MMX指令集 (Multi Media eXtension, 多媒体扩展指令集)。MMX指令集率先在Pentium处理器中使用,MMX指令集支持算数、比较、移位等运算,MMX指令集的向量寄存器是64bit。

  • SSE指令集(Streaming SIMD Extensions,单指令多数据流扩展),所有的SSE系列指令的向量寄存器都是128bit,也就是一次性可以计算4个int。SSE最早出现在1999年,在之后的近10年内,推出了SSE,SSE2,SSE3,SSE4.1,SSE4.2。
    AVX指令集(Advanced Vector Extensions,高级向量扩展)。AVX指令集是在之前的SSE128位扩展到和256位的单指令多数据流。AVX出现在2008年,之后出了AVX2,2014年,AVX-512将数据bit由256bit扩展到了512bit。AVX是目前比较常用的指令集,256位的类型可以一次计算4个double,有效的提升性能。
    利用CPU-Z软件可以查看电脑的CPU信息,查看电脑支持哪些指令集。

现代编译器有三种方式来支持 SIMD:
(1)编译器能够在没有用户干预的情况下生成 SIMD 代码,称之为自动矢量化。
(2)用户可以插入 Intrinsics 函数实现 SIMD。
(3)用户可以使用矢量 C++ 类 (仅限ICC编译器) 来实现 SIMD。
在C++中使用SIMD指令集需要包含头文件,在QT中需要包含头文件


3.2 多核编程

多核编程可以理解为就是多线程编程,总体上可以分为三个部分:OpenMP并行,opencv并行和多线程并行。在设计相关代码时候,切记变量可以被多个线程访问,但同一时间只能被一个线程修改,如果多个线程想修改同一个变量,可使用原子操作或加锁。 当然,多核编程不止这些,还有tbb,mkl等等。


  • OpenMP 并行。这种并行办法是最简单的一种并行方法,直接在for循环前面添加#pragma omp parallel for即可,程序会自动将for循环分解。值得注意的是,该方法是在for循环前开始创建线程,结束后并销毁,这个过程会产生一些时间消耗,大约在3-5ms之间,做实时性应用开发的时候需要注意这个问题。(如果用到opencv,内部也有并行)
  • 多线程并行。上述的两种方法是针对一个for循环来解决的,但是整个算法不可能就由一个for循环构成,如果每个for循环都这么做的话,创建线程的开销巨大,因此,多线程并行主要就是解决这类问题的。初始化时候创建好线程,之后主线程串联算法,子线程解决for循环问题,线程可能会使用同步,加锁等手段逐步执行,最终获得输出结果。创建多线程时候,系统本身就会将不同线程分到不同核心上,有自己的调度手段,所以该方法加速效果很明显,就是过于面向过程,不方便后续的改进。

3.3 CUDA 编程加速


  • CUDA加速其实是最好的加速手段,CUDA最大的特性就是核心数特别多,一般是几千个,相比于CPU,加速倍数高达20-200倍之间。特别是推出的Jetson NX系列嵌入式卡,核心数在128-512之间,推进了更多算法的落地应用
    CUDA开发主要还是有C语言风格,C++用的很少,切记一点避免在CUDA中动态分配内存,最好通过参数传递内存指针。



4、汇编加速

用汇编加速的方法往往指的是C/C++与汇编混合编程,尽管多种编译器均有优化等级选项,但是越是高级的语言,时间损耗越多。
什么时候使用汇编加速呢? 一般有两种情况需要嵌入汇编代码:


  • ① 升级项目,项目原始版本是汇编代码,现在需要用C++开发,重写汇编代码注定耗时,直接调用汇编是个很好的解决方案。
  • ② 不同的语言对算法一半都有特定的处理方法,比如Matlab之类尽量使用矩阵运算,C++尽量使用指针访问等,如果有个频繁调用的算法,在汇编上有独特的计算方法,那么直接在C++调用这个汇编函数,可以达到加速效果。
    如何嵌入汇编代码呢? 方法很简单,使用关键字__asm来加入一段汇编语言的程序,C++下具体的格式为:__asm{ 指令 [;指令] /* comments */ … 指令}



5、硬件加速

前面介绍了各种通过编程加速的方法,核心是将算法进行并行化处理,总的来说

多核并行&#xff0c;启动并行时需要开多线程&#xff0c;需要少量的时间&#xff08;<10ms)&#xff0c;因此仅适用耗时较长的算法(>100ms)的并行。
CUDA并行&#xff0c;算法不可避免串行过程&#xff0c;因此许多时间在内存和显存之间的拷贝。
CPU指定集&#xff0c;小规模加速&#xff0c;但仅限于各种基本运算操作&#xff08;加减乘除、位运算等&#xff09;。
如今&#xff0c;FPGA是日趋热门的一种加速方法&#xff0c;与软件加速不同&#xff0c;该方法是直接将算法设计在电路上&#xff0c;变成专有模块进行并行。




6、引用

算法加速总的来说就是拿空间换时间&#xff0c;在执行上并行运算&#xff0c;达到加速效果。

1、是科研人就要快&#xff01;加速你的算法&#xff01;
2、C&#43;&#43;中使用SIMD的方法
3、深入代码优化 (二) 使用SIMD优化程序




推荐阅读
  • 在2022年,随着信息化时代的发展,手机市场上出现了越来越多的机型选择。如何挑选一部适合自己的手机成为了许多人的困扰。本文提供了一些配置及性价比较高的手机推荐,并总结了选择手机时需要考虑的因素,如性能、屏幕素质、拍照水平、充电续航、颜值质感等。不同人的需求不同,因此在预算范围内找到适合自己的手机才是最重要的。通过本文的指南和技巧,希望能够帮助读者节省选购手机的时间。 ... [详细]
  • 本文介绍了在Windows环境下如何配置php+apache环境,包括下载php7和apache2.4、安装vc2015运行时环境、启动php7和apache2.4等步骤。希望对需要搭建php7环境的读者有一定的参考价值。摘要长度为169字。 ... [详细]
  • Linux如何安装Mongodb的详细步骤和注意事项
    本文介绍了Linux如何安装Mongodb的详细步骤和注意事项,同时介绍了Mongodb的特点和优势。Mongodb是一个开源的数据库,适用于各种规模的企业和各类应用程序。它具有灵活的数据模式和高性能的数据读写操作,能够提高企业的敏捷性和可扩展性。文章还提供了Mongodb的下载安装包地址。 ... [详细]
  • Java在运行已编译完成的类时,是通过java虚拟机来装载和执行的,java虚拟机通过操作系统命令JAVA_HOMEbinjava–option来启 ... [详细]
  • Oracle优化新常态的五大禁止及其性能隐患
    本文介绍了Oracle优化新常态中的五大禁止措施,包括禁止外键、禁止视图、禁止触发器、禁止存储过程和禁止JOB,并分析了这些禁止措施可能带来的性能隐患。文章还讨论了这些禁止措施在C/S架构和B/S架构中的不同应用情况,并提出了解决方案。 ... [详细]
  • 本文介绍了Python高级网络编程及TCP/IP协议簇的OSI七层模型。首先简单介绍了七层模型的各层及其封装解封装过程。然后讨论了程序开发中涉及到的网络通信内容,主要包括TCP协议、UDP协议和IPV4协议。最后还介绍了socket编程、聊天socket实现、远程执行命令、上传文件、socketserver及其源码分析等相关内容。 ... [详细]
  • 原文地址:https:www.cnblogs.combaoyipSpringBoot_YML.html1.在springboot中,有两种配置文件,一种 ... [详细]
  • C语言注释工具及快捷键,删除C语言注释工具的实现思路
    本文介绍了C语言中注释的两种方式以及注释的作用,提供了删除C语言注释的工具实现思路,并分享了C语言中注释的快捷键操作方法。 ... [详细]
  • baresip android编译、运行教程1语音通话
    本文介绍了如何在安卓平台上编译和运行baresip android,包括下载相关的sdk和ndk,修改ndk路径和输出目录,以及创建一个c++的安卓工程并将目录考到cpp下。详细步骤可参考给出的链接和文档。 ... [详细]
  • 【Windows】实现微信双开或多开的方法及步骤详解
    本文介绍了在Windows系统下实现微信双开或多开的方法,通过安装微信电脑版、复制微信程序启动路径、修改文本文件为bat文件等步骤,实现同时登录两个或多个微信的效果。相比于使用虚拟机的方法,本方法更简单易行,适用于任何电脑,并且不会消耗过多系统资源。详细步骤和原理解释请参考本文内容。 ... [详细]
  • Android Studio Bumblebee | 2021.1.1(大黄蜂版本使用介绍)
    本文介绍了Android Studio Bumblebee | 2021.1.1(大黄蜂版本)的使用方法和相关知识,包括Gradle的介绍、设备管理器的配置、无线调试、新版本问题等内容。同时还提供了更新版本的下载地址和启动页面截图。 ... [详细]
  • 本文介绍了Hyperledger Fabric外部链码构建与运行的相关知识,包括在Hyperledger Fabric 2.0版本之前链码构建和运行的困难性,外部构建模式的实现原理以及外部构建和运行API的使用方法。通过本文的介绍,读者可以了解到如何利用外部构建和运行的方式来实现链码的构建和运行,并且不再受限于特定的语言和部署环境。 ... [详细]
  • Voicewo在线语音识别转换jQuery插件的特点和示例
    本文介绍了一款名为Voicewo的在线语音识别转换jQuery插件,该插件具有快速、架构、风格、扩展和兼容等特点,适合在互联网应用中使用。同时还提供了一个快速示例供开发人员参考。 ... [详细]
  • 本文介绍了计算机网络的定义和通信流程,包括客户端编译文件、二进制转换、三层路由设备等。同时,还介绍了计算机网络中常用的关键词,如MAC地址和IP地址。 ... [详细]
  • 本文介绍了在mac环境下使用nginx配置nodejs代理服务器的步骤,包括安装nginx、创建目录和文件、配置代理的域名和日志记录等。 ... [详细]
author-avatar
大家庭方不_402
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有