跳转至内容

提高性能/引导过程

来自 ArchWiki

提高系统的启动性能可以缩短启动等待时间,并作为一种了解特定系统文件和脚本如何相互交互的手段。本文尝试汇总提高 Arch Linux 系统启动性能的方法。

分析启动过程

使用 systemd-analyze

systemd 提供了一个名为 systemd-analyze 的工具,可用于显示启动过程的时间详情,包括一个显示单元等待其依赖项的 SVG 图表。你可以查看哪些单元文件导致启动过程变慢,进而相应地优化你的系统。

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

$ 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 可能会更好。

建议将根卷的存储和文件系统模块构建为内置 (built-in),以便实现 在没有 initramfs 的情况下运行

Initramfs

如果在你的配置中可行,在没有 initramfs 的情况下运行 应该是最快的方式。

mkinitcpio 默认使用 baseudev 钩子 (hooks)。可以通过将它们替换为 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 最小化 微代码镜像 (Microcode image) [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)在启动过程中总是会被启动,那么通过尽可能早地启动它可能会缩短整体启动时间。如果服务文件已为此进行了配置(大多数情况如此),可以通过 启用 (enabling) upower.service 来实现。

这将导致 systemd 尽可能快地启动 UPower,而不会与套接字或 D-Bus 激活产生竞态。

交错启动 (Staggered spin-up)

某些硬件实现了 交错启动 (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 将继续尝试应用这些设置。或者,可以尝试屏蔽 (mask) 该单元。

如果根文件系统使用的是 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,而 autofs 默认被 locate 忽略。自动挂载 /home 的提速可能不超过一两秒,具体取决于你的系统,因此这个技巧可能不值得尝试。
  • 如果系统安装在 btrfs 子卷中(具体来说:根目录 / 本身是一个子卷)且 /home 是一个独立的文件系统,你可能还想防止创建 /home 子卷。屏蔽 home.conf 临时文件:ln -s /dev/null /etc/tmpfiles.d/home.conf

减少启动时的输出

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

更换启动加载程序

更换你的 启动加载程序(例如,使用更简单的启动加载程序,如 systemd-boot)可能会缩短几秒钟的启动时间。

如果你的配置允许,请尝试仅使用 EFI boot stub 以获得更短的启动时间。

挂起到内存

减少启动时间最好的方法就是根本不启动。考虑改为将 系统挂起到 RAM

© . This site is unofficial and not affiliated with Arch Linux.

Content is available under GNU Free Documentation License 1.3 or later unless otherwise noted.