国产精品久久久aaaa,日日干夜夜操天天插,亚洲乱熟女香蕉一区二区三区少妇,99精品国产高清一区二区三区,国产成人精品一区二区色戒,久久久国产精品成人免费,亚洲精品毛片久久久久,99久久婷婷国产综合精品电影,国产一区二区三区任你鲁

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

如何在裸機環境中運行KleidiAI微內核

Arm社區 ? 來源:Arm社區 ? 2025-08-08 15:16 ? 次閱讀
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

作者:Arm 工程部產品管理總監 Paul Black

Arm KleidiAI 是一款具有突破性意義的軟件庫,專為提升 Arm CPU 上的人工智能 (AI) 性能而設計。在此前發布的《Arm KleidiAI 助力 AI 框架性能提升》一文中,對 KleidiAI 進行了簡要概述,并附有相關指南鏈接,其中詳細說明了在 Linux 環境中運行 KleidiAI 矩陣乘法 (matmul) 微內核的分步操作,這份指南內容詳實且極易上手。而本篇內容則將探索如何在裸機環境中運行 KleidiAI 內核,并通過測試多款 C/C++ 編譯器,以確定如何能更高效地生成代碼。

本文將介紹如何在裸機環境中運行 KleidiAI 微內核,并針對不同編譯器在不同優化級別下的表現進行基礎基準測試。文中會用到 Arm Development Studio 的相關組件,包括固定虛擬平臺 (FVP),以及 Arm Compiler for Embedded (AC6) 的授權許可。與此同時,還提供了有關如何查看編譯器已采用(或未采用)的優化的相關信息。

設置裸機項目

本文將評估的三個編譯器分別是:

Arm Compiler for Embedded,更為人熟知名稱的是 AC6

Arm GNU 工具鏈,即 GCC

新一代 Arm 嵌入式編譯器 Arm Toolchain for Embedded (ATfE)。撰寫本文時,該工具鏈還處于 Beta 測試階段

為了在裸機項目中運行 KleidiAI 內核,可參考 Kleidi 指南中的說明。本文以 Arm Development Studio 中的 C++ 示例項目為基礎進行開發:startup_Armv8-Ax1_AC6_CPP是 AC6 版本,startup_Armv8-Ax1_GCC_CPP是 GCC 版本,而 ATfE 的移植版本則包含在 ATfE 測試版下載包中。這三個編譯器對應的項目功能相同,但需要對 Makefile 和鏈接腳本進行必要的修改。

各工具鏈的修復和更改

在粘貼 Kleidi 指南中提供的代碼后,需對這三個項目進行以下簡單修改以確保正常運行:

包含 float.h 頭文件以定義 FLT_MAX

添加 KleidiAI 頭文件的 include 路徑

將架構更改為armv8.2-a+dotprod+i8mm

要運行此代碼,需要一個具備 i8mm 擴展的 Arm 核心。此擴展在 Armv8.2-A 至 Armv8.5-A 架構中為可選功能,而在后續支持高級 SIMD 指令的核心中則為必選,因此 Arm Neoverse V1 是個不錯的選擇。Arm Development Studio 提供了 Neoverse V1 固定虛擬平臺 (FVP),此處所選用的是-C cluster0.NUM_CORES=1 -C bp.secure_memory=false -C cache_state_modelled=0

啟動代碼中存在一段用于設置 SMPEN 的讀-改-寫序列,但這在 Neoverse V1 FVP 上會引發問題。由于是復用 Arm Cortex-A 的啟動代碼來適配 Neoverse 核心,因此需要進行一些修改,而在本場景中,移除該序列即可解決問題。理想情況下,應根據 Neoverse 核心的要求重新審閱啟動代碼,但就本次研究而言,確保代碼正常運行便已足夠。

添加了一些代碼,用于向矩陣中填充隨機數據。這一步可能并非必需,因為內存中原本就已填充了重復的非零模式。

此外,還需要對各個項目單獨做一些修改。示例項目主要是實現處理器的啟動,并未考慮在啟動后運行較為復雜的負載任務:

在 ATfE 項目中,RAM 大小被設為 0x80000,這個容量過小,會導致堆與棧發生沖突。不過此問題很容易解決,因為即便是 FVP 的默認配置,其提供的 RAM 也遠大于該數值。因此,我們可以在鏈接腳本中設置更大的 RAM 大小。

在 GCC 項目中,.init_array 段被分配到 0x80100000 地址,該地址過低,會與 .eh_frame 段產生沖突。移除這一地址設置即可解決問題。

至此就能成功在裸機環境中使用三款不同的工具鏈運行 KleidiAI 內核。接下來便可開展性能測試。

基準測試方法和結果

本次研究中使用了 FVP 的周期計數器來作為性能衡量指標。雖然它并非完美,但對于本次研究而言已經足夠。由于三款編譯器運行的是相同的工作負載,因此即便存在測量誤差,其誤差程度和分布位置也會保持一致。所以,作為一種性能參考指標,FVP 的周期計數完全能滿足本次研究的需求。接著,分別在 -O0、-O1、-O2 和 -O3 這四個優化級別下,對三款編譯器的周期計數進行了測量,以啟動處理器核心、設置矩陣以及執行 KleidiAI 內核:

a06946c0-6e8e-11f0-a18e-92fbcf53809c.png

這里有兩個值得關注的現象。首先,大部分優化效果在 -O1 級別就已顯現。在 -O2 和 -O3 級別下雖有小幅提升(其中 GCC 的提升相對更明顯),但提升幅度遠不及 -O1 級別。這并不令人驚訝,因為 KleidiAI 內核本身已通過大量手工編寫的匯編指令進行了優化,而在 Kleidi 內核外添加的代碼既簡短又簡單。本文后續會深入分析所使用的優化手段。

其次,ATfE 的表現似乎明顯快于 AC6 和 GCC。新一代 Arm 嵌入式編譯器能在與 AC6 的對比中展現出如此優勢,固然令人欣喜,但這一性能差距也促使我進行更深入的探究。

AC6 和 ATfE 的匯編器、編譯器及 C++ 庫組件均基于 LLVM 構建,兩款工具鏈的主要差異體現在鏈接器和 C 庫上(AC6 采用專有版本,ATfE 則使用開源版本)。因此,兩者之間約 20% 的性能差距讓我頗為好奇。我需要確保所有性能數據和基準測試結果都能適用于實際項目,所以必須進一步厘清 ATfE 的速度提升究竟源于何處。

深入分析

在這一部分對性能測試進行了簡化,但同時也提升了復雜度。通過只關注 -O1 優化等級,以此簡化了測試,因為大部分優化效果都體現在這一級別。與此同時,通過將代碼分為三個部分來提高分析的粒度:

啟動:所有啟動代碼,直至進入 main ()

準備:為矩陣分配內存,向矩陣填充隨機數據

執行:運行 Kleidi 內核

周期計數如下:

a07a86d8-6e8e-11f0-a18e-92fbcf53809c.png

從 KleidiAI 內核的執行耗時來看,三款編譯器的表現十分接近,ATfE 略領先于 AC6(約 1%),而 GCC 則稍顯落后。在 -O2 和 -O3 級別下重新運行了該測試,如前文所述,隨著優化級別的提高,GCC 在 -O3 級別時小幅反超,這正是高級別優化帶來的提升效果之一。

在準備階段,ATfE 與 AC6 的表現依然接近,GCC 則仍然落后。同樣在 -O2 和 -O3 級別下重新測試后發現,在這些優化級別下,GCC 縮小了部分差距。這似乎表明,不同編譯器會在不同優化級別中納入特定的優化過程。

然而,ATfE 之所以能實現整體耗時的大幅縮短,關鍵提速點其實在啟動階段。我猜測,這可能是因為 ATfE 所使用的 Picolibc 在 C 庫設置環節,比 AC6 采用的 ArmCLib 或 GCC 采用的 newlib 更輕量化。由于 ATfE 的主要提速點在于此,而測試項目本身的代碼量較少,這就導致初始的性能對比結果存在偏差:如果增大工作負載,啟動代碼在整體運行時間中的占比就不會如此之高了。

分析編譯器優化

若要了解 ATfE 采用(或未采用)哪些優化過程,可借助編譯器選項-Rpass(或-Rpass-missed)。這兩個選項后可接=.*(表示所有優化過程)或=(特定優化過程)。例如,使用-Rpass=inline可查看哪些函數調用已被內聯,而使用-Rpass-missed=inline則能了解哪些調用未被內聯。-Rpass-missed 選項對于開發者而言頗具價值,它能揭示 C/C++ 代碼可如何調整,從而讓編譯器更易于優化。

快速查看了 ATfE 在 -O0、-O1、-O2 和 -O3 下級別下的優化過程,其結果如下:

即便在 -O0 級別,編譯器仍會對部分 Arm C 語言擴展 (ACLE) 內聯函數進行內聯處理,例如 vaddq_s16(向量加法)。這一點是合理的,因為這類調用僅對應單條指令,因此在性能(得益于消除函數調用開銷)與代碼體積增加(因代碼復制導致)之間不存在權衡問題。

在 -O1 級別,編譯器進行了大量的函數內聯,尤其是對小型函數(如隨機數生成器實現)。此外,若循環中某些指令或表達式無需在每次迭代時重新計算,編譯器會將它們提升 (hoist) 到循環外部。

在 -O2 級別,編譯器開始進行循環向量化,但部分向量化操作會推遲到 -O3 級別。編譯器采用啟發式算法來權衡每項優化的收益與成本。如同內聯優化,在同一優化級別下,不同循環可能會采用不同的向量化策略,這一點值得關注。

在 - O3 級別,編譯器還會對部分循環進行展開。

提升 (hoisting) 機制值得深入探究。以 KleidiAI 源文件中一段大幅簡化的代碼為例:

for (size_t dst_row_idx = 0; dst_row_idx < dst_num_rows; ++dst_row_idx) {?

for (size_t dst_byte_idx = 0; dst_byte_idx < dst_num_bytes_per_row; ++dst_byte_idx) {?

const size_t block_idx = dst_byte_idx / block_length_in_bytes;

const size_t nr_idx = block_idx % nr;

const size_t n0_idx = dst_row_idx * nr + nr_idx;

編譯器注意到,在計算 n0_idx 時,其中的乘法部分無需放在內層循環中,因為在內層循環中,dst_row_idx 和 nr 均為常量:

src/kai_rhs_pack_nxk_qsi4cxp_qs4cxs1s0.c47: remark: hoisting mul [-Rpass=licm]

96 | const size_t n0_idx = dst_row_idx * nr + nr_idx;

| ^

編譯器會將該乘法操作從內層循環提升 (hoist) 到外層循環,大致如下:

for (size_t dst_row_idx = 0; dst_row_idx < dst_num_rows; ++dst_row_idx) {?

const size_t hoist_temp = dst_row_idx * nr;

for (size_t dst_byte_idx = 0; dst_byte_idx < dst_num_bytes_per_row; ++dst_byte_idx) {?

const size_t block_idx = dst_byte_idx / block_length_in_bytes;

const size_t nr_idx = block_idx % nr;

const size_t n0_idx = hoist_temp + nr_idx;

開發者也可手動進行此類優化,但這可能會使代碼變得不夠簡潔、清晰,難以理解和維護。編譯器會考慮這些因素,從而讓開發者能夠專注于代碼功能、清晰度和可維護性。

ATfE 的 -Rpass 選項輸出包含大量信息,既涉及已應用的優化過程,也涉及未應用的過程。這些信息對于開發者而言非常有幫助,能讓開發者了解編譯器如何優化代碼,并指導開發者對代碼進行調整,以更好地配合編譯器優化。這是一個龐大的主題,我將在后續博客中深入探討。

結論

Arm Development Studio 提供了一套適用于裸機環境下 KleidiAI 內核實驗的工具,包括便于快速上手的示例項目、用于測試的 FVP,以及 AC6 的授權(之后還將包含 ATfEP 的授權)。與所有軟件開發工作一樣,在評估編譯器性能等指標時,需要考慮采集所有相關數據。在本案例中,很容易輕易得出“用 ATfE 構建的項目比用 AC6 構建的項目快約 20%”的結論。ATfE 會基于每項潛在優化的成本與收益做出啟發式優化決策,并提供實用選項來查看已采用和未采用的優化。通過這些選項獲取的信息,可用于調整代碼,使編譯器能夠實現更多優化。

聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • ARM
    ARM
    +關注

    關注

    135

    文章

    9552

    瀏覽量

    391834
  • 內核
    +關注

    關注

    4

    文章

    1467

    瀏覽量

    42870
  • cpu
    cpu
    +關注

    關注

    68

    文章

    11277

    瀏覽量

    224942
  • 人工智能
    +關注

    關注

    1817

    文章

    50094

    瀏覽量

    265273

原文標題:在裸機 Arm 環境中運行 Arm KleidiAI MatMul 內核

文章出處:【微信號:Arm社區,微信公眾號:Arm社區】歡迎添加關注!文章轉載請注明出處。

收藏 人收藏
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

    評論

    相關推薦
    熱點推薦

    何在嵌入式Linux開發板上配置Qt運行環境

    本文基于I.MX6ULL芯片的Linux開發板,介紹如何在嵌入式Linux開發板上配置Qt運行環境,并運行Qt程序進行測試
    發表于 10-10 09:56 ?3267次閱讀

    何在裸機系統中集成SystemView

    SystemView是嵌入式系統可視化分析工具,提供了對應用程序的完整洞察,包括時間軸、CPU負載、運行時間信息、上下文運行時信息等可視化窗口,能夠幫助開發者獲得對應用運行時行為的深入理解。除μC
    的頭像 發表于 12-29 11:07 ?3822次閱讀
    如<b class='flag-5'>何在</b><b class='flag-5'>裸機</b>系統中集成SystemView

    何在樹莓派上安裝并運行 Arduino 集成開發環境

    使用樹莓派單板計算機,你可以運行各種應用程序,包括廣受歡迎的Arduino集成開發環境(IDE)。這意味著你可以用它輕松地為通過USB連接到樹莓派計算機的微控制器編程,以創建交互式電子項目。下面
    的頭像 發表于 07-01 17:41 ?4351次閱讀
    如<b class='flag-5'>何在</b>樹莓派上安裝并<b class='flag-5'>運行</b> Arduino 集成開發<b class='flag-5'>環境</b>!

    《電子發燒友電子設計周報》聚焦硬科技領域核心價值 第23期:2025.08.04--2025.08.08

    、安森美分析工業充電器拓撲結構選型 3、國際原廠一文詳解高速模數轉換器的奈奎斯特規則 4、如何在裸機環境運行
    發表于 08-08 20:47

    【OK210試用體驗】之三裸機開發環境搭建

    一、裸機開發思路S5PV210裸機編程有好多種思路,主要思路有如下: 1.RVDS2.2開發環境。板子在NAND燒寫UBOOT或者EBOOT,RVDS2.2編寫c語言程序,jlink
    發表于 09-27 15:24

    請問裸機程序怎么做才可以直接下載到SDRAM運行

    ),對裸機程序多少有些了解。就是因為前面做過的這些驗證性試驗,編譯出的bin文件可以直接下載到SDRAM運行,而韋老大的這些裸機程序還是比較明確的規定要燒到NAND Flash的0地
    發表于 08-02 05:45

    何在UltraEdit建立Verilog環境

    何在UltraEdit建立Verilog環境
    發表于 04-30 06:40

    可以將MCUXpresso用于該設備M7內核的軟件開發,而不是A53內核,這是否正確?

    這樣,那么我對此有一些疑問: 您只能在 A53 內核運行 Linux 等操作系統是否正確?你不能在 A53 內核上進行一些裸機編程嗎? 我可以從 M7 核心訪問所有外圍設備(以
    發表于 05-29 07:41

    如何使用J-Link在A55內核上進行i.MX93 EVK裸機調試?

    我正在研究在 i.MX93 EVK 的 A-55 內核運行裸機代碼(例如帶有 Zephyr RTOS 的程序)。是否有很多關于如何使用 SEGGER J-Link 調試以這種方式運行
    發表于 06-05 07:00

    請問nuc980如何在裸機程序實現nuc980軟件復位?

    nuc980如何在裸機程序實現nuc980軟件復位?
    發表于 06-13 08:21

    請問nuc980如何在裸機程序實現nuc980軟件復位?

    nuc980如何在裸機程序實現nuc980軟件復位?
    發表于 09-04 08:22

    內核與宏內核的比較與分析

    混合內核實質上也是內核,而外內核是一種比較極端的設計方法,目前還處于研究階段,所以我們就著重討論宏內核
    發表于 03-17 16:05 ?11次下載
    <b class='flag-5'>微</b><b class='flag-5'>內核</b>與宏<b class='flag-5'>內核</b>的比較與分析

    環境監測設備的FreeRTOS低功耗

    筆者的團隊專業從事環境監測設備的開發,在開發過程團隊的工作人員提到了關于FreeRTOS低功耗的問題。RTOS低功耗與裸機跑的進入的方式不同。普通單片機進入的方式分為SLEEP、STOP
    發表于 12-31 19:08 ?1次下載
    <b class='flag-5'>環境</b>監測設備<b class='flag-5'>中</b>的FreeRTOS低功耗

    程序是如何在 CPU 運行的(二)

    在上一篇文章《程序是如何在 CPU 運行的(一)》筆者講述了程序中一條一條指令以及一條一條數據是如何在 CPU
    發表于 02-07 11:10 ?1次下載
    程序是如<b class='flag-5'>何在</b> CPU <b class='flag-5'>中</b><b class='flag-5'>運行</b>的(二)

    Linux內核的編譯和運行

    想讓Linux內核代碼跑起來,得先搭建編譯和運行代碼的環境
    發表于 06-23 11:56 ?2408次閱讀
    Linux<b class='flag-5'>內核</b>的編譯和<b class='flag-5'>運行</b>