天天看點

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由于本身啟動開銷比較大,隻有在運算複雜的情況下才會顯示出性能優勢,并且是運算越複雜,性能提升會越明顯!

上面的測試目前并不涉及共享記憶體通路等也可能影響到性能的方面,實際使用中需要根據不同的場景使用不同的模型來使得性能獲得最優....

繼續閱讀