FreeBSD 與 Linux:核心呼叫約定的效能

FreeBSD 與 Linux:核心呼叫約定的效能

int80h.org,FreeBSD 組譯語言教學課程

[Linux 呼叫] 約定比 Unix 方式有很大的缺點,至少就組合語言程式設計而言是如此:每次進行核心呼叫時,都必須壓入暫存器,然後再彈出它們。這會使您的程式碼變得更龐大且更慢。

繼續說 FreeBSD 支援 Linux 約定和“Unix 約定”

如果您專門針對 FreeBSD 進行編碼,則應始終使用 Unix 約定:速度更快,您可以將全域變數儲存在暫存器中,不必為可執行檔新增品牌,並且不必強行安裝 Linux 類比套件目標系統。

我覺得奇怪的是 Linux 方式會比較笨重、比較慢。好像有兩個選擇,

  • 僅保存您需要保留的暫存器,它們是
    • 那些可能被系統呼叫破壞的易失性暫存器(據我所知ecx
    • 或者,需要將適當的參數傳送到核心以產生的暫存器syscall(可能是eax, ecx, edx, esi, edi, ebp
  • 將 100% 的核心參數保存在堆疊上。

看起來 FreeBSD 就是最糟糕的Linux 約定的案例場景。我缺什麼? FreeBSD 約定(他們稱為「Unix 方式」)如何變得更小、更快?

答案1

在我看來,這其實歸結為作者的觀點。

在 FreeBSD(“Unix”)約定中,將參數壓入堆疊,在 中指定係統呼叫號EAX,然後呼叫中斷 0x80(在堆疊上有一個額外的操作數,因為它期望從單獨的函數呼叫)。

在 Linux i386 約定中,您將參數放置在適當的暫存器中,並呼叫中斷 0x80。

體積大/速度慢的爭論大概來自這樣一個事實:按照 Linux 慣例,呼叫者需要處理其暫存器的使用。如果系統呼叫需要暫存器中包含呼叫者關心的值的參數,則需要保留它們,這會導致額外的跑腿工作;請參閱 C 庫中的範例。在此範例中,系統呼叫需要 EAX、EBX、EDX、EDI 和 ESI 中的值;但呼叫者只關心保留 EBX、EDI 和 ESI,因此它只將它們推送到堆疊。一般情況是相當複雜一點(但這也是處理 C 和彙編語言混合的結果,試圖在所有情況下產生最佳程式碼),但是當用彙編語言編寫時,這就是您所指的網站的要點,那就不會了這不是什麼大問題。

在我看來,有六個半:在 FreeBSD 約定中,您在所有情況下都會推送到堆疊,在 Linux 約定中,您會推送到堆疊(或其他地方),這取決於您正在做什麼呼叫站點。您可能會說 Linux 約定可以實現更快的程式碼,因為您可以在暫存器中執行所有計算...然而指出,在 Linux 上,暫存器最終仍然會被壓入(建構struct pt_regs用於向處理系統呼叫的 C 函數提供參數的實例),因此 Linux 端的總體成本高於 Linux 端的總體成本。

無論如何,考慮到執行系統呼叫本身的成本,在圍繞系統呼叫談論堆疊或基於寄存器的程式碼時爭論效能似乎相當迂腐。從絕對意義上來說,任何節省的周期當然都是好的,但相對的改進將會很小。

相關內容