網頁設計
距離我們上次更新RISC-V的狀態已經過去一年多了,我們最近在RISC-V PC上成功運行了《巫師3》,我相信這是第一款在RISC-V上運行的AAA遊戲機器。 所以我認為這是編寫更新的最佳時機,而且它來了。
網頁設計 故事
一年前,RV64 DynaRec 還只能運行一些相對「容易運行」的 Linux 遊戲,例如《星露穀物語》、《黏糊糊的世界》等。
相對而言,這是因為大量新的x86_64 指令在RISC-V 中快速實現後,DynaRec 中留下了許多bug。我們當時無法插入AMD顯示卡的RISC-V設備,而VisionFive 2和LicheePi 4A上的IMG整合式顯示卡不支援OpenGL,僅支援OpenGL ES。
我們可以使用 gl4es 獲得一定程度的 OpenGL 支持,這使得像《星露穀物語》這樣的遊戲能夠運行,但對於其他更嚴肅的 Linux 遊戲以及一般的所有 Windows 遊戲來說這還不夠。
所以這成為了我們在更脆弱的世界測試更多x86程式的障礙,直到ptitSeb和我都收到了Sophgo的Milk-V Pioneer,這是一台硬64核心的RISC-V PC,當然,它也有用於顯示卡的PCIe插槽。
另外,另一位核心貢獻者xctan也找到了透過M.2界面將AMD顯示卡「插」進VisionFive 2的方法。了大量新的x86指令。
這就是在 RISC-V 上運行《巫師 3》的故事。
網頁設計 RISC-V DynaRec 的現況如何?
x86 指令集非常非常大。根本沒有實現。
另外,對於SSE指令,我們使用標量指令來實現,而AArch64使用Neon擴展,LoongArch64使用LSX擴展。
然而,事情並不是一成不變的。
現在已經有一些支援 RVV 的設備了,例如上面提到的 Milk-V Pioneer,它支援 xtheadvector 擴展,它是 RVV 0.7.1 版本的變體(事情有點複雜)。 M1 SoC 支援RVV 1.0 的核准版本。
有了這些可用的設備,最近我們為box64添加了基本的RVV支持,並實現了一些常見的SSE指令。對吧?
接下來,我們來談談 RISC-V 上空的兩朵烏雲的籠罩 這些是我覺得一年 RISC-V 在過去 x86 模擬中最缺乏的東西。
網頁設計 最需要的 x86 仿真指令
至少在x86 模擬的背景下,在我們支援的所有3 種架構中,RISC-V 是表現力最差的一種。必須使用更多的指令來模擬相同的行為,因此翻譯效率會較低。
其中,預留指令是最關鍵的──從一個暫存器中選擇一系列位元到另一個暫存器的能力;以及將一個暫存器中的位元插入到另一個暫存器的能力一系列範圍中的能力。
LoongArch64 和 AArch64 都有對應的指令,但 RISC-V 世界沒有這兩種指令的對應指令,因此無論是官方還是供應商補充。 V 上不存在。
但為什麼它對於 x86 模擬如此重要?
例如,對於一個 ADD AH, BL
指令,box64需要從RBX中提取最低字節,加入到RAX的第二位組中,然後將其插回RAX的第二位組中 同時保留 RAX 中的所有其他位元不變組。
在LoongArch64上,我們有 BSTRPICK.D
挑選位,並且 BSTRINS.D
插入位,所以實現是:
BSTRPICK.D scratch1, xRAX, 15, 8BSTRPICK.D scratch2, xRBX, 7, 0ADD scratch1, scratch1, scratch2BSTRINS.D xRAX, scratch1, 15, 8
在ARM64上就很簡單了, UBFX
和 BFI
操作碼。
# extract the second lowest byte of RAXSRLI scratch1, xRAX, 8ANDI scratch1, scratch1, 0xFF# extract the lowest byte of RBXANDI scratch2, xRBX, 0xFF# do the additionADD scratch1, scratch1, scratch2# fill scratch3 with mask 0xFFFF_FFFF_FFFF_00FFLUIscratch3, 0xFFFF0ADDIW scratch3, scratch3, 0xFF# insert it backAND xRAX, xRAX, scratch3ANDI scratch1, scratch1, 0xFFSLLI scratch1, scratch1, 8OR xRAX, xRAX, scratch1
因此,一個簡單的位元組總共需要添加 10 個指令,這個介面是一個孤立的實際案例!
網頁設計 16位元組原子指令的挫敗感
x86 有用於無鎖原子操作的 LOCK 指令,box64 主要使用 LR/SC 序列來模擬這些。
例如,對於 LOCK ADD [RAX], RCX
,我們產生以下方案碼:
MARKLOCK:LR.D scratch1, (xRAX)ADD scratch2, scratch1, xRCXSC.D scratch3, scratch2, (xRAX)BNEZ scratch3, MARKLOCK
如果 RAX 中的地址未連接,事情會變得有點複雜,但總的來說,這非常有效。
另外 LOCK CMPXCHG16B
指令,比較 RDX:RAX
具有 16 位元組記憶體和交換 RCX:RBX
雖然 AArch64 和 LoongArch64 中的一些 16 位元組原子指令可用於實現這一點,但不幸的是,RISC-V 中沒有任何對應的指令。
因此,我們無法像其他架構一樣完美地實現這條指令,更不幸的是,許多程式都使用了這條指令,例如UnityGame。
網頁設計 結局
最後,儘管有這些缺點,《巫師3》實際上還是可以在box64上速度高達15 fps的遊戲並且主選單上的全速運行!