淺嘗ncnn優(yōu)化&&vulkan api的應用

vulkan 的顯存管理

  • 一個 VkBuffer 對象,多個 offset

    • 使用同一塊 VkBuffer 存儲中間層的特征數據,不同的 blob 使用不同的offset進行區(qū)分 。
VkDeviceMemory結構
  • 可以在內存架構方面做到零拷貝

    • 集成顯卡和手機上采用unified內存架構(統(tǒng)一內存架構),這種架構下,GPU可以直接訪問CPU上的主存。利用這種架構上的特性,在GPU計算的時候就不用把 內存上的數據 拷貝到 顯存 上,計算完成后也不需要將 顯存上的數據 拷貝到 內存。
不同內存架構的對比

對GPU存儲布局的優(yōu)化

1.[c,h,w] 這種布局不太適合在GPU上做IO:[c, h, w] ---> [c/4, h, w, 4]

  • 因為GPU訪問和讀寫顯存用的時候更多的是使用 vec4 的類型,ncnn 通過將布局改為[c/4,h,w,4],使得GPU的IO效率得到大幅度提升
  1. 減少內存帶寬的需求

    • ncnn 中的 Tensor float數據可以使用半精度
    • 在一些不直接支持 fp16 存儲的情況下,ncnn 使用 packHalf2x16unpackHalf2x16 來模擬 fp16fp32 的轉換(這兩個函數是 GLSL 內置的函數)
  2. 更加方便的維護代碼

    • ncnn 中創(chuàng)建了一個 GLSL 的宏。

      所以寫代碼的時候可以不用管類型上的事,運行時會自動轉換為設備支持的 fp32fp16 的對應代碼


cpu-gpu 混合推理

  • 模型中有些層,在沒有GPU實現(xiàn)的時候,我們需要自動切換到CPU上去做推理。這就涉及到存儲布局相互轉換
CPU和GPU轉換
  • ncnn 提供了一套pipline,使用一套pipline實現(xiàn)端到端的完成 最佳的布局轉換。在獨顯上也傾向使用 fp16 做上傳和下載,能用半精度,也會優(yōu)先使用。

并行推理

  • ncnn 在GPU上實現(xiàn)并行推理的方式。

    • Vulkan的api中同一塊gpu會暴露多個隊列。

      例如:nvidia的gpu中有8個隊列,那么就可以使用多線程的方式同時在8個隊列上提交8個任務。

      好處:可以增加GPU的使用率 ,從而提高效率。

11個任務同時在三塊gpu上做推理

GLSL->SPIR-V 運行編譯

  • 原因:有些驅動需要對 GLSL 或者 SPIR-V 的源代碼進行特殊的處理,所以只能采用運行時編譯
  • 好處:不需要在離線時編譯多個 SPIR-V 的二進制文件,減少二進制文件的體積。

Swiftshader

  • swiftshader項目地址:google在cpu上實現(xiàn) vulkan驅動 的項目,可以實現(xiàn)在cpu上執(zhí)行vulkan的代碼,可以保證每次代碼運行結果都是一致的。

復用 VkPipeline 和相關的 vulkan object

  • 模型加載的時候, 特別是第一次加載模型的時候,由于沒有離線的cache和優(yōu)化的手段, pipeline的編譯是一個十分耗時的操作。
  • 有些模型層的參數(kernal size, stride)是一樣的。ncnn 在運行時就將 層的參數vulkan對象 的關系記錄下來,當遇到具有相同參數層的時候,就可以直接復用之前創(chuàng)建好的 vulkan對象,這樣可以顯著降低第一次加載模型的耗時。
降低第一次加載模型的耗時
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

友情鏈接更多精彩內容