2017年1月30日 星期一

從 "Three tips for maximising your SoC performance" 看軟體優化

先前 ARM 官方提供了 Free Webinar "Three tips to Maximize your SoC performance"
目前簡報的錄影與投影片都已經上線, 填入一些個人資訊即可閱覽

從報告的內容可以看出這個簡報是為了其 "System Guidance" 服務提高能見度
但是從設計原則中也有許多軟體人員可以作為借鏡並思考的地方
而以簡報中對於 SoC 設計上三個對於效能的考量為:
  • 最短化自 CPU 到記憶體路徑 - 每個 clocks cycle 都會歸屬到 CPU latency
  • 最大化系統頻寬 -  確認系統記憶體已經對於效能優化
  • 依流量種類管理流量 - 在系統符合即時性的情況下, 儘可能提供 CPU 優先權

而從軟體優化的角度來看, 這三點反映了對於效能上, 實作上的考量為:
  • 評估各種類型記憶體的 memory latency: 了解 memory latency 才能評估效能, 並且透過理解 cache 管理的機制來避免不當的行為所造成的過長存取時間. 此外理解 CPU 的硬體設計是透過何種方式來克服這問題, 以此來分析軟體上對於硬體差異在效能落差的影響.
  • 量測平台系統的頻寬: 透過 profiling 與 behavior analysis 能了解何時程式達到了 bandwidth bound, 才能採取對應的優化方式
  • 了解應用上可能同時競爭頻寬的硬體: 應用上所仰賴的 GPU 與 硬體加速器都會消耗頻寬
對於 latency 問題主要採取的策略有上述三項, 這三者的意義分別是紙上架構推估, 以軟體模擬
推測, 實際硬體上的量測, 三個不同階段

上圖為以 SGM-773 (System Guidance for Mobile) 的推估 memory latency 的方式, 若僅考量單次的存取, 請注意 85.1ns 這個推估時間約為 209 CPU cycles (也可以看出 CPU 內 cache 為 15 CPU cycles, 而出了 CPU 到了 CCI 則會超過 50 CPU cycles ). 這樣的計算通常能夠以此推敲 best case 與 worst case (考量各階段的 queue depth)的狀況, 也能得知架構上的物理限制, 與合理的數值範圍.

此外 LMBench 也是不錯的工具套件, 以 latency 來說是其中 lat_mem_rd 這個工具,下圖為使用 SGM-773 平台透過 LMBench 去量測後的結果

有興趣者可以先於自己的 ubuntu 平台上安裝 lmbench 套件, 接著執行下列指令:
/usr/lib/lmbench/bin/x86_64-linux-gnu/lat_mem_rd 16 128
其中 16 代表為 16MB, 也就是 bench 的大小上限為 16MB
而 128 所代表的是 stride 大小, 執行後可以看到類似下列的 log:
"stride=128
0.00049 2.361
0.00098 2.361
0.00195 2.362
0.00293 2.361
0.00391 2.361
0.00586 2.361
0.00781 2.361
0.01172 2.361
0.01562 2.362
0.02344 11.838
0.03125 11.819
0.04688 11.827
0.06250 11.816
0.09375 11.818
0.12500 11.825
0.18750 11.822
0.25000 11.817
0.37500 12.190
0.50000 12.182
0.75000 12.188
1.00000 12.188
1.50000 12.249
2.00000 19.838
3.00000 37.352
4.00000 38.298
6.00000 39.394
8.00000 39.920
12.00000 40.455
16.00000 40.674
這裡每行的兩個數字, 前者為該次測試的大小, 後者為測出的 latency 以 ns 計
上面測試的為個人使用 A8-5545M 平台所測出的 (L1: 16KB, L2: 2MB)
可以觀察到對應兩個 size 的 latency 轉折


事實上, LMBench 也提供了 bandwidth 的估測工具 - bw_mem
簡易執行指令如下:
/usr/lib/lmbench/bin/x86_64-linux-gnu/bw_mem  16K rdwr
也就是測試以 16MB 為大小的 Read/Write 頻寬, 有興趣亦可以調整前面的 16K 的數字
輸出有兩個數字:
0.016000 9801.85
前者為所要求測試的大小 (16KB 為 0.016M), 後者為 MB/s (也就是測出為 9891.85MB/s)
了解系統的能力, 對於針對平台的軟體優化有相當的幫助 (像是 tiling 與批次演算作法, 其分割大小能夠以 L2 大小做考量)

沒有留言:

在 ARM 平台上使用 Function Multi-Versioning (FMV) - 以使用 Android NDK 為例

Function Multi-Versioning (FMV) 過往的 CPU 發展歷程中, x86 平台由於因應各種應用需求的提出, 而陸陸續續加入了不同的指令集, 此外也可能因為針對市場做等級區隔, 支援的數量與種類也不等. 在 Linux 平台上這些 CPU 資訊可以透過...