跳转至内容

提高性能/引导过程

来自 ArchWiki

提高系统的启动性能可以减少启动等待时间,并有助于更深入地了解某些系统文件和脚本如何相互作用。本文旨在汇总提高 Arch Linux 系统启动性能的方法。

分析启动过程

使用 systemd-analyze

systemd 提供了一个名为 systemd-analyze 的工具,可用于显示启动过程的详细时间信息,包括一个 SVG 图,展示了单元(unit)在等待其依赖项。您可以找出哪些单元文件导致您的启动过程变慢,然后相应地优化您的系统。

要查看启动时花费在内核空间和用户空间的时间,只需使用

$ systemd-analyze
提示 如果您通过 UEFI 启动,并使用实现了 systemd 的 引导加载程序接口 (Boot Loader Interface) 的引导加载程序(目前 systemd-bootGRUB 支持),那么 systemd-analyze 还可以显示在 EFI 固件和引导加载程序本身花费的时间。

要列出启动单元文件,按它们各自启动所花费的时间排序

$ systemd-analyze blame

在启动过程的某些阶段,事情无法继续,直到给定的单元成功。要查看哪些单元处于这些关键的启动链环节,请执行

$ systemd-analyze critical-chain

您还可以创建一个 SVG 文件,以图形方式描述您的启动过程,类似于 Bootchart

$ systemd-analyze plot > plot.svg

有关详细信息,请参阅 systemd-analyze(1)

使用 bootchart2

您也可以使用 Bootchart2 来可视化启动序列。

编译自定义内核

编译自定义内核可以减少启动时间和内存使用。尽管 64 位架构已标准化,且 Linux 内核具有模块化特性,但这些优势可能不如预期那么大。有关更多信息,请参阅 Kernel#Compilation

官方内核模块的压缩级别使用 ZSTD_CLEVEL=19 构建。但对于 SSD,ZSTD_CLEVEL=1 可能更好。

建议将用于存储和文件系统的模块内置到根卷中,以便 无需 initramfs 即可运行

Initramfs

如果您的设置允许,无需 initramfs 即可运行应能提供最快的速度。

mkinitcpio 默认使用 baseudev 钩子。通过将它们替换为 systemd 可以实现更快的启动时间。有关更多详细信息,请参阅 Mkinitcpio#Common hooks。如果替换 fsck 钩子,请参阅 Fsck#Boot time checking

#编译自定义内核类似,initramfs 也可以进行瘦身。一种简单的方法是包含 mkinitcpioautodetect 钩子。Booster 生成的 initramfs 比 mkinitcpiodracut 生成的更小,并具有快速的单二进制 init。请参阅 Minimal initramfsBooster#Removing modules

根据您的硬件(处理器和存储速度),使用 lz4 而不是默认的 zstd 压缩选项可能会更快,因为启动时更快的解压缩速度通常会抵消 initramfs 从磁盘读取时稍大的尺寸。请参阅 Mkinitcpio#COMPRESSION

如果您使用 无需 initramfs 即可运行Booster,您还可以最小化 intel-ucode 的 微码映像 [1]

/etc/pacman.d/hooks/shrink-intel-ucode
[Trigger]
Type = Package
Operation = Install
Operation = Upgrade
Target = intel-ucode

[Action]
Description = Minimizing intel-ucode.img ...
When = PostTransaction
Depends = iucode-tool
Exec = /usr/bin/iucode_tool -S /usr/lib/firmware/intel-ucode --overwrite --write-earlyfw=/boot/intel-ucode.img

选择合适的启动服务方式

systemd 的一个核心特性是 D-Bus 和套接字激活(socket activation)。在大多数情况下应优先使用此特性,因为它仅在服务首次被访问时启动,这通常是件好事(例如,在启动时启用 cups.service 对桌面用户通常没有用,不如启用 cups.socket,它只在实际打印时才启动服务)。

然而,如果您知道某个服务(如 upower)将在启动时始终被启动,那么尽早启动它可能会减少总体启动时间。这可以通过 启用 upower.service 来实现(如果服务文件已为此配置,大多数情况下都是如此)。

这将导致 systemd 尽快启动 UPower,而不会与套接字或 D-Bus 激活产生冲突。

交错启动

某些硬件实现了 交错启动(staggered spin-up),它会导致操作系统串行探测 ATA 接口,从而逐个启动驱动器并降低峰值功耗。这会减慢启动速度,并且在大多数消费级硬件上根本没有好处,因为驱动器在接通电源时会立即启动。要检查 SSS 是否正在使用

# dmesg | grep SSS

如果在启动过程中未使用,则不会有输出。

要禁用它,请在 内核参数中添加 libahci.ignore_sss=1

文件系统挂载

得益于 mkinitcpiofsck 钩子,您可以通过在内核行将 ro 更改为 rw 来避免可能耗时的根分区重新挂载:选项可以使用 rootflags=rw,other_mount_options 设置。该条目必须从 /etc/fstab 文件中删除,否则 systemd-remount-fs.service 将继续尝试应用这些设置。或者,可以尝试屏蔽该单元。

如果根文件系统使用 Btrfs,则不像其他文件系统那样需要在每次启动时进行 fsck。如果是这种情况,可以删除 mkinitcpiofsck 钩子。您还可以屏蔽 systemd-fsck-root.service,或使用 fsck.mode=skip 内核命令行告诉它不要对根文件系统进行 fsck。如果没有 mkinitcpiofsck 钩子,systemd 仍会使用 systemd-fsck@.service 对任何相关文件系统进行 fsck。

您还可以从 /etc/fstab 中删除 API 文件系统,因为 systemd 会自行挂载它们(请参阅 pacman -Ql systemd | grep '\.mount$' 获取列表)。用户通常有一个从 sysvinit 继承的 /tmp 条目,但您可能已经注意到上面的命令表明 systemd 已经处理了它。因此,可以安全地删除它。

其他文件系统,例如 /homeEFI 系统分区,可以使用自定义挂载单元进行挂载。在挂载选项中添加 noauto,x-systemd.automount 将缓冲对该分区的全部访问,并在首次访问时进行 fsck 和挂载,从而减少必须在启动过程中 fsck/挂载的文件系统数量。

  • 这将使您的 /home 文件系统类型为 autofs,该类型默认被 locate 忽略。根据您的系统,自动挂载 /home 的速度提升可能不会超过一两秒,因此这个技巧可能不值得。
  • 如果系统安装在 btrfs 子卷中(特别是:根目录 / 本身就是一个子卷)并且 /home 是一个单独的文件系统,您也可能想防止创建 /home 子卷。屏蔽 home.conf tmpfile:ln -s /dev/null /etc/tmpfiles.d/home.conf

减少启动时的输出

对于某些系统,特别是那些使用 SSD 的系统,TTY 的缓慢性能实际上是一个瓶颈,因此输出越少意味着启动越快。有关建议,请参阅 静默启动 文章。

更改引导加载程序

更改您的 引导加载程序(例如,使用更简单的引导加载程序,如 systemd-boot)可以减少几秒的启动时间。

如果您的设置允许,请尝试仅使用 EFI 引导存根以获得更短的启动时间。

挂起到内存

减少启动时间最好的方法是不启动。考虑将系统挂起到内存