天天看点

C/C++中榨干硬件性能的N种并行姿势初探1. 前言2. 并行计算结构分类几种常见的并行计算框架(技术)3. 几种方法的简单测试对比4. 对比分析

关于并行计算介绍参见

<a href="https://computing.llnl.gov/tutorials/parallel_comp/">https://computing.llnl.gov/tutorials/parallel_comp/</a>

下面主要就部分单进程中常见的几种并行优化技术和相应的框架做一些简单的整理和分析对比,并且主要偏重于端,不涉及多节点多进程!

目前常见的是分类方法主要是flynn提出的经典分类法:根据指令流(单指令或多指令)和数据流(单数据流或多数据流)来分类,如下图:

C/C++中榨干硬件性能的N种并行姿势初探1. 前言2. 并行计算结构分类几种常见的并行计算框架(技术)3. 几种方法的简单测试对比4. 对比分析

neon技术是arm公司在arm-v7a及后续架构实现的一种simd(单指令多数据)结构的指令优化技术,通过arm在汇编级别提供的neon指令,一条指令可以同时进行多条数据的并行处理,比如加,减等

详细介绍参考:

<a href="https://www.arm.com/zh/products/processors/technologies/neon.php">https://www.arm.com/zh/products/processors/technologies/neon.php</a>

使用neon指令优化可以根据需要在三个层次选择不同的优化措施:

目前gcc等已经在编译器级别集成了neon的优化,直接添加编译指令就可以使得应用在某些场合应用到neon的并行优化,一般添加编译开关如下:

<code>-mfloat-abi=softfp -mfpu=neon</code>

在使用了编译开关后性能还无法达到要求或对你的算法没有有效提升的时候,你可以直接调用编译器本身集成的neon 内联函数直接进行优化:如下面的一个rgb转灰度值的例子:

这种方法本质上是编译器把汇编指令封装为c风格的函数,方便嵌入到c/c++中使用!

目前常说的多核cpu处理器一般都属于mimd架构,在这种架构上常用技术主要是多线程技术,目前常用的这类并行框架有 tbb ,cstripes ,openmp,gcd (apple 专用),ms concurrencyd (windows专用)等,下面所说的两种常用并行框架主要都是基于多核多线程的

tbb 是intel开源的一个并行计算框架,主要介绍参见:

<a href="https://www.threadingbuildingblocks.org/">https://www.threadingbuildingblocks.org/</a>

tbb的使用需要引入一个基于相关平台编译的独立库

用法很简单,例如

完成一个简单的for循环的并行计算

"openmp(open multi-processing)是一套支持跨平台共享内存方式的多线程并发的编程api"

openmp的使用相当简单,只要在编译器中加入相应的编译开关即可使用

<code>-fopenmp</code>

写法也很简洁,如

gpu技术本身主要是在图形渲染中用来加速图形渲染的硬件架构,本质是使用了大量计算单元并行进行图形或计算处理,后面发现这个完全可以用来进行通用的并行计算, 于是许多基于此的并行框架和技术诞生了,目前主流的框架主要是cuda和opencl

opencl需要驱动支持才能使用,初始化工作比上述几种方法稍显复杂,此处不赘言...

测试主要基于基本的加,减,乘,除,外加一个稍微复杂一点的混合运算,基本运算描述如下:

混合运算

note3(四核cpu+neon指令支持+opencl支持,配置属于稍高端)

m13(四核cpu+neon指令支持+不支持opencl,配置属于稍低端)

从上面数据可以看出,

1). 整体上,tbb,openmp等多核多线程技术只要核足够,并行计算明显能够获得较大程度优化,简单计算基本上能够根据核数的多少获得相应倍数的提升

2). neon指令在cpu比较弱的机器中性能能够获得成倍的有效提升,但在cpu本身就很强劲的机器上,neon指令的优化效果并不明显,原因可能是在高端机器中cpu已经充分经过多数据流计算优化!

3). opencl由于本身启动开销比较大,只有在运算复杂的情况下才会显示出性能优势,并且是运算越复杂,性能提升会越明显!

上面的测试目前并不涉及共享内存访问等也可能影响到性能的方面,实际使用中需要根据不同的场景使用不同的模型来使得性能获得最优....

继续阅读