当一个算法实现之后,需要集成到产品中去,这时就要面临性能问题。在实际工程应用中,除采用降低算法的复杂度去解决性能问题外,通常也会选择优化代码以及良好运用硬件等方式。接下来将针对在不改动算法情况下,对纯工程方面做性能优化的技术作一个介绍。
对初始算法进行流程优化主要有:
simd即(single instruction multiple data),单指令多数据流,是cpu中能够复制多个操作数,并把它们打包在大型寄存器的一组指令集。
目前pc上intel指令集有sse、avx等,sse/avx是对其x86体系的simd扩展指令集,它基于simd向量化技术,提高x86硬件的计算性能,增强了x86多核向量处理器的图像和视频处理能力。sse/avx指令支持向量化数据并行,一个指令可以同时对多个操作数进行操作,同时操作的数据个数由向量寄存器的长度和数据类型共同决定。
simd属于细粒度的并行,对于图像算法中利用simd技术优化,可以一次性对多个像素进行处理,性能提升明显,大部分情况下都有3-4倍的提升。
当系统有多个线程/进程时,cpu会按一定的调度策略,把它们尽可能放在不同的核上执行,多线程优化就是把算法拆成多个子任务,跑在不同的线程上,利用cpu多个核的能力,并行执行算法。
比较有名的框架就是openmp,openmp是一种共享内存并行系统的多线程程序设计方案,支持的编程语言包括c、c 和python。openmp提供了对并行算法的高层抽象描述,特别适合在多核cpu机器上的并行程序设计。编译器根据程序中添加的pragma指令,自动将程序并行处理,使用openmp简化了并行程序设计。openmp采用fork-join的执行模式,开始的时候只存在一个主线程,当需要并行计算的时候,派生出若干个分支线程来执行并行任务。当并行代码执行完成之后,分支线程汇合,并把控制流程交给单独的主线程。一个典型的fork-join执行模型如图1所示。
gpu即(graphic processing unit),图形处理器。如图2所示,cpu功能模块很多,能适应复杂运算环境;gpu构成则相对简单,目前流处理器和显存控制器占据了绝大部分晶体管。cpu中大部分晶体管主要用于构建控制电路(比如分支预测等)和cache,只有少部分的晶体管来完成实际的运算工作。而gpu的控制相对简单,且对cache的需求小,所以大部分晶体管可以组成各类专用电路、多条流水线,使得gpu的计算速度有了突破性的飞跃,拥有了更强大的处理浮点运算的能力。
要使用gpu进行通用计算,需要基于一个框架,目前的框架主要有cuda和opencl。
cuda是一种由nvidia推出的通用并行计算架构,该架构使gpu能够解决复杂的计算问题。 它包含了cuda指令集架构(isa)以及gpu内部的并行计算引擎。这个架构只能在装配了nvidia显卡的机器上使用。
opencl是一个为异构平台编写程序的框架,此异构平台可由cpu,gpu或其他类型的处理器组成。opencl由一门用于编写kernels(在opencl设备上运行的函数)的语言(基于c99)和一组用于定义并控制平台的api组成。opencl提供了基于任务分割和数据分割的并行计算机制。
更多机器视觉分享,欢迎继续关注“汉振智能”....