最美情侣中文字幕电影,在线麻豆精品传媒,在线网站高清黄,久久黄色视频

歡迎光臨散文網(wǎng) 會(huì)員登陸 & 注冊(cè)

向 LoongArch 架構(gòu)移植 Haskell GHC 編譯器

2023-07-06 20:28 作者:Linux-Story  | 我要投稿

現(xiàn)如今,我們使用的計(jì)算機(jī)幾乎都是 X86 架構(gòu)的,Intel 和 AMD 幾乎是普通消費(fèi)者購(gòu)買(mǎi)新計(jì)算機(jī)時(shí)的唯二選擇,可能會(huì)有少數(shù)的 Apple 用戶(hù)使用了配備 Apple Silicon 處理器的 Arm Mac,除此之外,似乎就沒(méi)有什么別的體系架構(gòu)可供選擇了。但實(shí)際上,無(wú)論是歷史還是現(xiàn)在,指令集的江湖都不是如此平靜的,過(guò)去有 MIPS 和 PowerPC 等等在游戲機(jī)和服務(wù)器等領(lǐng)域挑戰(zhàn) X86 的地位,近有 RISCV 和 LoongArch 等試圖在嵌入式領(lǐng)域開(kāi)辟新的領(lǐng)域,而這些挑戰(zhàn)者們都有一個(gè)共同點(diǎn)——都是 RISC(精簡(jiǎn)指令集架構(gòu))處理器。

何謂 RISC?

要了解什么是 RISC,首先就要清楚什么是 CISC,因?yàn)?RISC 的概念正是從 CISC 延申出來(lái)的。上世紀(jì) 70 年代,Intel 推出了第一顆 X86 處理器——Intel 8086,作為 X86 系列的始祖,它的減配版本(地址線(xiàn)位數(shù)砍半)8088 被 IBM 選中,作為 IBM PC 的處理器,從此開(kāi)啟了個(gè)人電腦和兼容機(jī)的傳奇,同一時(shí)期,Apple 也選中了摩托羅拉的 68000 CPU 作為第一臺(tái) Macintosh 的處理器,用來(lái)支持它引入的圖形界面。

編輯切換為居中

8086 與 68000 看似大相徑庭,但兩者的共同點(diǎn)就在于它們都是復(fù)雜指令集處理器(CISC),由于當(dāng)時(shí)儲(chǔ)存器的價(jià)格普遍較高,編譯器也還不夠成熟,因此當(dāng)時(shí)的軟件開(kāi)發(fā)者往往傾向于手工編寫(xiě)匯編指令,受此影響早期處理器的指令設(shè)計(jì)普遍比較復(fù)雜,并且采用了變長(zhǎng)指令字的設(shè)計(jì),用以支持各種復(fù)雜的操作,這樣可以減小程序的體積和程序員編寫(xiě)指令的工作量,例如在 X86 中,就可以直接使用loop指令編寫(xiě)循環(huán),而無(wú)需手動(dòng)編寫(xiě)跳轉(zhuǎn)等指令。

然而,隨著時(shí)間踏入 90 年代,CISC 處理器暴露出了各種問(wèn)題:一方面,過(guò)于復(fù)雜的指令集不利于引入流水線(xiàn)的設(shè)計(jì),造成性能受到影響;另一方面,程序規(guī)模不斷增大,已經(jīng)很難靠程序員去編寫(xiě)所有匯編代碼了,編譯器也逐漸走向成熟,然而它們還是很難利用上 CISC 指令集上各種復(fù)雜的指令。受此啟發(fā),人們搞出了精簡(jiǎn)指令處理器(RISC),正如其名,它的指令相比 CISC 要簡(jiǎn)單很多,一般有如下的特點(diǎn):

  1. 指令字定長(zhǎng),通常是 32 位長(zhǎng),方便解碼器的設(shè)計(jì)

  2. 通用寄存器較多,例如 ARM 有 16 個(gè)寄存器,而 MIPS 有 32 個(gè)寄存器,減少訪(fǎng)存帶來(lái)的性能瓶頸

  3. 訪(fǎng)存由單獨(dú)的指令完成,普通指令只會(huì)對(duì)寄存器和立即數(shù)進(jìn)行操作,簡(jiǎn)化了處理器的設(shè)計(jì)

  4. 指令數(shù)量較少,語(yǔ)義單一,方便編譯器的實(shí)現(xiàn)

這些特點(diǎn)都給當(dāng)時(shí)的 RISC 處理器帶來(lái)了巨幅的性能提升,RISC 處理器一時(shí)風(fēng)光無(wú)兩,在游戲機(jī)和服務(wù)器等各種領(lǐng)域全面開(kāi)花,就連身為 Wintel 聯(lián)盟一員的微軟都為 MIPS 處理器推出了 Windows NT for RISC 用來(lái)兼容當(dāng)時(shí)在高端工作站領(lǐng)域攻城略地的 MIPS 處理器。

不過(guò),正如《計(jì)算機(jī)體系結(jié)構(gòu)》一書(shū)中所言,如今 RISC 與 CISC 的區(qū)別已經(jīng)日漸消弭了,甚至很多 RISC 架構(gòu)的指令集都不比早期 CISC 更簡(jiǎn)單了:例如 PowerPC 的寄存器窗口和 MIPS 的延遲槽設(shè)計(jì),有些甚至成為了性能提升的瓶頸,而傳統(tǒng)的 CISC 指令集則通過(guò)引入 uop 的方式在執(zhí)行階段 RISC 化,話(huà)雖如此,新的指令集還是不斷出現(xiàn),并且往往還是會(huì)采用 RISC 簡(jiǎn)化的思想——例如 RISC-V 還有筆者本次要介紹的 LoongArch。

LoongArch 簡(jiǎn)介

龍芯架構(gòu) LoongArch 是一種精簡(jiǎn)指令集計(jì)算機(jī)(Reduced Instruction Set Computing,簡(jiǎn)稱(chēng) RISC)風(fēng)格的指令系統(tǒng)架構(gòu)。

這是《龍芯架構(gòu)參考手冊(cè) 卷一:基礎(chǔ)架構(gòu)》中對(duì) LoongArch 給出的定義,LoongArch 是龍芯中科公司設(shè)計(jì)的一種 CPU 指令集架構(gòu),2020 年對(duì)外公開(kāi)其存在,2021 年起公開(kāi)出貨,在其 3A5000 CPU 產(chǎn)品開(kāi)始搭載。龍芯之前的產(chǎn)品采用的是 MIPS 指令集,而隨著時(shí)代的變遷,MIPS 指令集的實(shí)控人幾經(jīng)易手,就連 MIPS 公司自己都在 2020 年宣布放棄 MIPS,轉(zhuǎn)投 RISC-V 陣營(yíng),而龍芯的選擇則是另起爐灶——獨(dú)立開(kāi)發(fā) ISA。

當(dāng)然,任何新指令集逃不過(guò)的一個(gè)問(wèn)題就是生態(tài),畢竟 X86 指令集能夠在今天仍然保持第一的占有量,靠的就是其他指令集無(wú)法比擬的生態(tài)鴻溝,無(wú)數(shù)的軟件都是為了 X86 編寫(xiě)的,并且很難簡(jiǎn)單移植到其他的平臺(tái)上,更遑論無(wú)數(shù)的閉源商業(yè)軟件了。而新架構(gòu)要加強(qiáng)自身的生態(tài),基本只有兩條路可以走:模擬(兼容層)和移植,筆者目前手頭就有一臺(tái) 3A5000 開(kāi)發(fā)機(jī),并且正在從事有關(guān)軟件移植的工作。

移植指北

那么,要如何讓軟件跑在 LoongArch 架構(gòu)上呢?實(shí)際上,對(duì)于大多數(shù)軟件而言,并不需要做任何修改,在 C 編譯器,JRE 運(yùn)行時(shí),.NET 環(huán)境等基礎(chǔ)軟件基本完成適配之后,只需要將代碼重新編譯(Java 等甚至不需要編譯)運(yùn)行即可,但對(duì)于一些依賴(lài)于底層匯編實(shí)現(xiàn)的軟件,則需要手動(dòng)進(jìn)行移植。

筆者在今年年初完成了對(duì) Haskell GHC 編譯器向 LoongArch 架構(gòu)的移植,并在 LLVM 和 GHC 開(kāi)源社區(qū)中順利將移植代碼合并進(jìn)了主線(xiàn)(雖然還差點(diǎn)鬧出點(diǎn)亂子),下面就以我當(dāng)時(shí)的移植過(guò)程為例,展示將一個(gè)依賴(lài)于底層體系架構(gòu)細(xì)節(jié)的應(yīng)用移植到新架構(gòu)上,都需要做哪些改動(dòng)。

不過(guò)要注意的是,隨著 LLVM16 和 GHC 9.6.1 的發(fā)布,相關(guān)代碼已經(jīng)集成進(jìn)了主線(xiàn)源碼中,因此無(wú)需修改源碼即可直接進(jìn)行編譯。

獲取源碼

首先,使用以下命令將 GHC LoongArch 分支克隆至本地

git clone -b loongarch-patch --recurse-submodules https://gitlab.haskell.org/lrzlin/ghc.git

GHC Unregisterised 版本編譯

根據(jù) CLFS 文檔中的指南配置好交叉工具鏈后,找到源碼目錄中的ghc/m4/ghc_unregisteried.m4文件并將其中的loongarch64字段刪除。

將ghc/libffi-tarballs和ghc/libraries/ghc-bignum/gmp/gmp-tarballs中l(wèi)ibffi和gmp的壓縮包替換為支持 LoongArch 的版本。

之后回到GHC根目錄,輸入:

./boot ./configure CC=$SYSDIR/cross-tools/bin/loongarch64-unknown-linux-gnu-gcc --target=loongarch64-unknown-linux-gnu LD=$SYSDIR/cross-tools/bin/loongarch64-unknown-linux-gnu-ld

等待配置完成后,輸入如下命令進(jìn)行編譯。

hadrian/build -j4

如果在編譯中碰到缺少ncurses庫(kù)的報(bào)錯(cuò),請(qǐng)自行編譯并將其安裝至交叉編譯工具鏈中。

編譯完成后,輸入:

hadrian/build binary-dist

打包二進(jìn)制分發(fā)包,至此 GHC Unregisterised 版本編譯完成,可以將其拷貝至 LoongArch 架構(gòu)機(jī)器安裝使用。

GHC Registerised 編譯

GHC Unregistered 即可滿(mǎn)足大多數(shù)情況下的使用需要,但如果需要更高的運(yùn)行效率、更完善的庫(kù)支持和更完整的功能,則需要編譯 GHC Registerised 版本,由于該版本需要 LLVM 后端的支持,因此需要首先編譯支持 LoongArch 架構(gòu)的 LLVM16。

注:以下操作均在 LoongArch 機(jī)器上完成。

首先需要安裝之前編譯完成的 GHC Unregisterised 版本,將 tar 包加壓縮之后,進(jìn)入目錄并輸入如下指令安裝:

./configure hadrian/build install

之后在 LLVM 官方網(wǎng)站或 Github Release 頁(yè)面下載 LLVM16 源碼,解壓至本地之后使用如下命令編譯安裝:

cmake .. -G Ninja -DCMAKE_INSTALL_PREFIX=/usr -DCMAKE_BUILD_TYPE=Release \ ? ? ? ? ? ? ?-DBUILD_SHARED_LIBS:BOOL=OFF -DLLVM_ENABLE_LIBCXX:BOOL=OFF \ ? ? ? ? ? ? ?-DLLVM_LIBDIR_SUFFIX=64 \ ? ? ? ? ? ? ?-DCMAKE_C_FLAGS="-DNDEBUG" -DCMAKE_CXX_FLAGS="-DNDEBUG" \ ? ? ? ? ? ? ?-DLLVM_BUILD_RUNTIME:BOOL=ON -DLLVM_ENABLE_RTTI:BOOL=ON \ ? ? ? ? ? ? ?-DLLVM_ENABLE_ZLIB:BOOL=ON -DLLVM_ENABLE_FFI:BOOL=ON \ ? ? ? ? ? ? ?-DLLVM_ENABLE_TERMINFO:BOOL=OFF \ ? ? ? ? ? ? ?-DLLVM_BUILD_LLVM_DYLIB:BOOL=ON \ ? ? ? ? ? ? ?-DLLVM_LINK_LLVM_DYLIB:BOOL=ON -DLLVM_BUILD_EXTERNAL_COMPILER_RT:BOOL=ON \ ? ? ? ? ? ? ?-DLLVM_INSTALL_TOOLCHAIN_ONLY:BOOL=OFF \ ? ? ? ? ? ? ?-DLLVM_TARGET_ARCH=LoongArch -DLLVM_DEFAULT_TARGET_TRIPLE=loongarch64-unknown-linux-gnu ninja && ninja install

由于 GHC 尚不支持最新的 LLVM 16 版本 因此需要對(duì)進(jìn)行如下修改:

  • 將 ghc/llvm-passes 的內(nèi)容修改為

[ (0, "-passes=module(default<O0>,function(mem2reg),globalopt,function(lower-expect))"), (1, "-passes=module(default<O1>,globalopt)"), (2, "-passes=module(default<O2>)") ]

  • 將 ghc/compiler/GHC/Driver/Pipeline/Execute.hs 第 902 行中的-tbaa刪除

  • 在 ghc/utils/genapply/Main.hs 中添加 #undef UnregisterisedCompiler

由于 GHC 在最新的主線(xiàn)移除了對(duì) make 工具的支持,因此我們還需要編譯并安裝 cabal-install。請(qǐng)自行參考 Cabal Bootstrap 指南進(jìn)行編譯,完成編譯后,請(qǐng)注意需要執(zhí)行一次cabal update之后即可進(jìn)入 GHC 根目錄并使用以下指令編譯安裝 GHC Registerised 版:

./boot ./configure hadrian/build -j4 hadrian/build install

以上,就是一次“簡(jiǎn)單”的移植過(guò)程。

參考文章: https://bbs.loongarch.org/d/150-ghc-loongarch https://blog.xen0n.name/posts/tinkering/loongarch-faq/


向 LoongArch 架構(gòu)移植 Haskell GHC 編譯器的評(píng)論 (共 條)

分享到微博請(qǐng)遵守國(guó)家法律
镇安县| 田东县| 开化县| 定兴县| 永宁县| 福泉市| 张家界市| 黄龙县| 讷河市| 太和县| 岐山县| 屏山县| 桑日县| 兰州市| 南投县| 宁阳县| 额尔古纳市| 新巴尔虎右旗| 梓潼县| 遂平县| 大新县| 图片| 巴楚县| 石河子市| 新河县| 青田县| 丁青县| 新蔡县| 陈巴尔虎旗| 和顺县| 长丰县| 榆林市| 芮城县| 黔南| 涞源县| 万源市| 海原县| 马边| 云安县| 松阳县| 乐平市|