性能優化/啟動過程 - Arch Linux 中文维基

跳至內容

# 性能優化/啟動過程

出自 Arch Linux 中文维基
< 性能优化

相關文章

- 性能優化
- 靜默啟動
- Daemon
- Kexec

翻譯狀態：

- 本文（或部分內容）譯自 Improving performance/Boot process，最近一次同步於 2025-04-03，若英文版本有所更改，則您可以幫助同步與翻譯更改的內容。
- 您可以在 ArchWiki 的對應頁面找到本文翻譯的原始修訂歷史。
- 本文可能與英文原文存在出入。

提升系統的啟動性能可以縮短啟動等待時長，還能學習系統文件和腳本見交互的方式。本文整合了數種提升 Arch Linux 啟動性能的方式。

## 啟動過程分析

### 使用 systemd-analyze

systemd 提供了一個名為 `systemd-analyze` 的工具，可用於顯示有關啟動過程的計時細節, 包括一個顯示各單元等待其依賴項的 svg 圖。您可以看到哪些單元文件導致啟動過程減慢, 然後可以相應地優化系統.

要查看啟動時在內核/用戶空間中消耗的時間, 只需使用：

    $ systemd-analyze

提示：如果系統使用 UEFI 引導，且啟動引導器實現了 systemd 的啟動引導器接口（目前只有 GRUB 和 systemd-boot 實現了），systemd-analyze 還可以顯示 EFI 固件和啟動引導器自身花費的時間。

按照耗費時間順序，列出啟動各個單元耗費的時間：

    $ systemd-analyze blame

在啟動過程的一些時刻，需要特定的單元成功啟動了才能繼續。要查看在啟動鏈中哪些單元處於這些關鍵點，可以執行：

    $ systemd-analyze critical-chain

類似於 Bootchart，還可以生成 SVG 形式的啟動流程圖：

    $ systemd-analyze plot > plot.svg

更多信息請參考 systemd-analyze(1)。

### 使用 bootchart2

你還可以使用 Bootchart2 將啟動流程可視化。

## 編譯自定義內核

使用自定義內核可以減少啟動時間和內存占用，但由於 Linux 內核的模塊化特性以及 64 位架構的逐漸標準化，這些好處可能沒有預期的那麼大。具體信息請參考內核#編譯。

官方內核的模塊默認壓縮等級為 `ZSTD_CLEVEL=19`，但 SSD 可能更適合使用 `ZSTD_CLEVEL=1`。

建議將會用到的存儲和文件系統模塊嵌入到內核中，以使用 Arch 的啟動流程#Running_without_initramfs。

## Initramfs

最佳做法是 Arch 的啟動流程#Running_without_initramfs。

mkinitcpio 默認使用 `base` 和 `udev` 鉤子，將它們替換為 `systemd`可以提升啟動速度，具體細節請參考 Mkinitcpio#常用鉤子。如果要替換 `fsck` 鉤子，請參考 Fsck#啟動時檢查。

與#編譯自定義內核類似，initramfs 也可以被精簡。最簡單的方法是包含 mkinitcpio 的 `autodetect` 鉤子。Booster 可以生成比 mkinitcpio 和 dracut 更小的 initramfs，並使用更快的單二進制文件 init. 參閱極簡 initramfs 或 Booster#Removing modules 以獲得更多信息。

取決於你的硬體（處理器和存儲速度）不同，由於啟動時更快的解壓速度通常可以抵消掉從硬碟讀取稍大的 initramfs 的負面影響，使用 lz4包 取代默認的 zstd包 壓縮算法有可能會更快，具體細節請參考 Mkinitcpio#壓縮方式(COMPRESSION)。

## 選擇合適的服務啟動方式

systemd 的一個核心功能是 D-Bus 和 socket 激活。多數情況下建議使用該功能，它會使服務只在初次訪問時啟動，通常來說這是件好事（例如 `cups.service` 在桌面環境通常沒必要開機啟動，而啟用 `cups.socket` 會使只在列印時啟動服務）。

但如果有個服務（以 upower包 為例）始終會在開機時啟動，那儘早將其啟動有可能會減少啟動耗時，該操作可通過啟用 `upower.service` 達成（前提是已配置了啟動文件，多數情況下都是如此）。

這樣 systemd 就會儘早啟動 UPower，而不會引起 socket 或 D-Bus 激活的競爭。

## 分批啟動

有些硬體使用了分批啟動（Staggered spin-up，SSP），會使系統按順序探測 ATA 接口，從而使硬碟逐個輪流啟動，以降低耗電峰值。這會降低啟動速度，且由於多數消費級硬體在通電後就會立即啟動，因此並沒有提供什麼優勢。執行以下命令可以檢查是否啟用了分批啟動：

    # dmesg | grep SSS

無輸出表示沒有使用該功能。

可以將 `libahci.ignore_sss=1` 添加到內核參數以禁用該功能。

## 掛載文件系統

藉助 mkinitcpio 的 `fsck` 鉤子，你可以通過在內核命令行中將 ro 改為 rw 來避免對 root 分區進行影響性能的重掛載：一個選擇是使用 `rootflags=rw,other_mount_options` 來設置相關選項。必須從 `/etc/fstab` 中移除對應的條目，否則 `systemd-remount-fs.service` 仍會嘗試應用這些設置。或者，也可以嘗試屏蔽（mask）此服務單元。

如果根文件系統是 Btrfs，就不需要和其他文件系統一樣每次啟動都進行 `fsck`。在這種情況下，可以移除 mkinitcpio 的 fsck 鉤子。你也可以選擇屏蔽（Mask） `systemd-fsck-root.service`，或者使用內核命令行`fsck.mode=skip`來告訴根文件系統跳過 `fsck`。沒有 mkinitcpio 的 fsck 鉤子，systemd 仍會使用 `systemd-fsck@.service` 對任何相關的文件系統進行 fsck。

你也可以移除`/etc/fstab`中的 API 文件系統，因為 systemd 會自動掛載它們（列表見 `pacman -Ql systemd | grep '\.mount$'`）。用戶可能看到從 sysvinit 遷移過來的 `/tmp` 條目，但你可能已經注意到，從上面的命令可以看出，systemd 已經處理了這個問題。因此，`/tmp` 條目可以安全地移除。

其他文件系統，比如 `/home` 或者 EFI 系統分區，可以使用自定義的掛載單元進行掛載。向掛載參數中添加 `noauto,x-systemd.automount` 會延遲掛載分區，直到首次訪問時才進行 fsck 和掛載，從而減少啟動過程中需要 fsck 或掛載的文件系統數量，幫助加快啟動速度。

注意：

- 這將使你的 `/home` 文件系統類型變成 `autofs`，默認情況下，locate 會忽略它。自動掛載 `/home` 的加速效果可能不會超過一兩秒，具體取決於你的系統，因此這個技巧可能並不值得嘗試。
- 如果系統安裝在一個 btrfs 子卷中（具體來說：根目錄 `/` 本身是一個子卷），並且 `/home` 是一個獨立的文件系統，你可能還需要防止創建一個 `/home` 子卷。可以通過屏蔽 `home.conf` 臨時文件來實現：`ln -s /dev/null /etc/tmpfiles.d/home.conf`。

## 精簡啟動階段輸出信息

對於某些用戶，特別是 SSD 用戶，TTY 的龜速實際上成為了性能瓶頸，精簡輸出信息實際上有利於提高性能。具體建議請參考靜默啟動。

## 替換啟動引導器

替換引導加載程序（例如換成 systemd-boot 這種簡單的引導器）可能會減少數秒的啟動時間。

在可用的情況下，只使用一個 EFI boot stub 可以進一步降低啟動耗時。

## 內核參數

有些內核參數可以提升啟動性能。

如果不需要 systemd-gpt-auto-generator，使用 `systemd.gpt_auto=no` 可能會減少 0.2~3 秒的啟動時長。如果根分區是 Btrfs 且沒有使用 initramfs 進行啟動，那 systemd-gpt-auto-generator 不會起效[1]。

`cryptomgr.notests` 會禁用自測試，但效果可能不大。

## 掛起到內存

減少啟動時長的最好方法是完全不用啟動，可以考慮轉而將系統掛起到內存。

分類：​

- 啟動過程

性能優化/啟動過程
新增話題