提升性能
本文提供了有关性能的基础系统诊断信息,以及可以采取的旨在减少资源消耗或优化系统的步骤。最终目标是实现感知到的或有记录的系统性能改进。另见 游戏#提高性能 了解额外的针对游戏和低延迟的特定建议。
基础知识
了解你的系统
优化系统最好的方法是针对瓶颈,即限制整体速度的子系统。系统规格说明可以帮助识别它们。
- 如果电脑在运行大型程序(如 LibreOffice 和 Firefox)时变慢,请检查 RAM 数量是否充足。使用以下命令,并查看 "available"(可用)列:
$ free -h
- 如果启动时间很慢,并且应用程序(仅)在第一次启动时需要很长时间加载,那么硬盘驱动器可能是罪魁祸首。硬盘的速度可以用
hdparm命令测量:# hdparm -t /dev/sdX
注意: hdparm 仅指示硬盘的纯读取速度,并不是有效的基准测试。但在普通系统上,高于 40MB/s(空闲时)的值是可以接受的。 - 如果即使在 RAM 充足的情况下 CPU 负载也一直居高不下,请尝试通过禁用正在运行的 守护进程 和/或进程来降低 CPU 使用率。可以通过多种方式进行监控,例如使用 htop、
pstree或任何其他 系统监控 工具。$ htop
- 如果使用直接渲染的应用程序(即使用 GPU 的程序,如视频播放器、游戏甚至 窗口管理器)运行缓慢,那么提高 GPU 性能应该会有所帮助。第一步是验证是否确实启用了直接渲染。这由
glxinfo命令指示(属于 mesa-utils 软件包),使用时应返回direct rendering: Yes:$ glxinfo | grep "direct rendering"
- 运行 桌面环境 时,禁用(未使用的)视觉桌面效果可以降低 GPU 使用率。如果当前的桌面环境不符合硬件和/或个人要求,请使用更轻量级的环境或创建 自定义环境。
- 使用经过优化的 内核 可以提高性能。通常,linux-zen 是一个不错的选择。但是,正如本文某些部分所示,可以对默认内核进行微调以获得更好的表现。
基准测试
优化的效果通常难以判断。不过,它们可以通过 基准测试 工具来测量。
存储设备
扇区大小
检查您的 NVMe 驱动器和高级格式硬盘驱动器是否正在使用 最佳逻辑扇区大小。
分区
确保您的分区已 正确对齐。
多个驱动器
如果您有多个可用磁盘,可以将它们设置为软件 RAID 以获得显著的速度提升。
在单独的磁盘上创建 交换空间 (swap) 也可以提供很大帮助,特别是如果您的机器频繁交换数据。
使用 SSD 作为 HDD 的缓存
当无法放弃硬盘驱动器时,可以添加固态硬盘作为缓存层,以提高读/写速度并减少随机访问带来的噪音。实现此目标的选项包括 LVM#Cache、Bcache 和 Bcachefs#SSD caching。
HDD 上的布局
如果使用传统的机械 HDD,分区布局会影响系统性能。驱动器开头的扇区(靠近磁盘外侧)比结尾的扇区快。此外,较小的分区需要较少的磁头移动,从而加快磁盘操作。因此,建议仅为系统创建一个小分区(15-20GiB,视需求而定),并尽可能靠近驱动器的开头。其他数据(图片、视频)应保存在单独的分区上,通常通过将主目录 (/home) 与系统目录 (/) 分开来实现。
选择并调整文件系统
为特定系统选择最佳文件系统非常重要,因为每种文件系统都有其自身的优势。文件系统 文章提供了最常用文件系统的简短摘要。您还可以在 分类:文件系统 中找到相关文章。
挂载选项
各种 *atime 选项可以缓解 strictatime 的性能损失。
其他挂载选项是文件系统特定的,因此请参阅相应文件系统的相关文章:
调整内核参数
有几个影响块设备性能的关键可调参数,请参阅 sysctl#虚拟内存 了解更多信息。
输入/输出调度器
背景信息
输入/输出 (I/O) 调度器是决定块 I/O 操作以何种顺序提交到存储设备的内核组件。在这里有必要提醒一下两种主要驱动器类型的一些规格,因为 I/O 调度器的目标是优化它们处理读取请求的方式:
- HDD 有旋转盘片和物理移动到所需位置的磁头。因此,随机延迟相当高,范围在 3 到 12ms 之间(无论它是高端服务器驱动器还是笔记本电脑驱动器,且绕过磁盘控制器写缓冲区),而顺序访问提供更高的吞吐量。典型的 HDD 吞吐量约为每秒 200 次 I/O 操作 (IOPS)。
- SSD 没有活动部件,随机访问与顺序访问一样快,通常低于 0.1ms,并且可以处理多个并发请求。典型的 SSD 吞吐量大于 10,000 IOPS,这超过了常见工作负载情况下的需求。
如果有许多进程向不同的存储部分发出 I/O 请求,可能会产生数千个 IOPS,而典型的 HDD 只能处理约 200 个 IOPS。此时会产生一个必须等待存储访问的请求队列。这就是 I/O 调度器发挥优化作用的地方。
调度算法
提高吞吐量的一种方法是线性化访问:通过按逻辑地址排序等待的请求并对最接近的请求进行分组。从历史上看,这是第一个 Linux I/O 调度器,称为 电梯 (elevator) 算法。
电梯算法的一个问题是,它对于进行顺序访问的进程不是最优的:读取一个数据块,处理几微秒,然后读取下一个数据块,依此类推。电梯调度器不知道该进程即将读取附近的另一个块,因此会移动到另一个进程在其他位置的另一个请求。预期式 (anticipatory) I/O 调度器解决了这个问题:它在处理另一个请求之前暂停几毫秒,以预期另一个附近的读取操作。
虽然这些调度器试图提高总吞吐量,但它们可能会让一些倒霉的请求等待很长时间。举个例子,假设大多数进程在存储空间开头发出请求,而一个倒霉的进程在存储空间另一端发出请求。这种进程潜在的无限期推迟被称为饥饿。为了提高公平性,开发了 截止时间 (deadline) 算法。它有一个按地址排序的队列(类似于电梯),但如果某个请求在此队列中停留太久,它就会移动到一个按过期时间排序的“过期”队列。调度器先检查过期队列并处理其中的请求,然后才移动到电梯队列。请注意,这种公平性对整体吞吐量有负面影响。
完全公平队列 (CFQ) 采用不同的方法解决问题,它根据提交请求的进程优先级,按队列分配时间片和允许的请求数量。它支持 cgroup,允许为特定的进程集合保留一定量的 I/O。这对于共享和云托管特别有用:支付了某些 IOPS 费用的用户希望在需要时获得其份额。此外,它在同步 I/O 结束时闲置等待其他附近的操纵,继承了 anticipatory 调度器的这一特性并带来了一些增强。anticipatory 和 elevator 调度器都已从 Linux 内核中退役,取而代之的是下面介绍的更先进的替代方案。
预算公平队列 (BFQ) 基于 CFQ 代码并带来了一些增强。它不为每个进程分配固定的磁盘时间片,而是为进程分配一个以扇区数为单位的“预算”并使用启发式算法。它是一个相对复杂的调度器,由于其单次操作开销较高(尤其是与慢速 CPU 搭配时),可能更适合机械驱动器和慢速 SSD。个人系统上使用 BFQ 的目标是,对于交互式任务,存储设备的响应速度几乎就像处于空闲状态一样。在默认配置下,它专注于提供最低延迟而不是实现最大吞吐量,这有时可以极大地 加速硬盘驱动器上应用程序的启动。
Kyber 是一个受网络路由中使用的活动队列管理技术启发的近期调度器。该实现基于“令牌”,令牌充当限制请求的机制。分配请求需要排队令牌,这用于防止请求饥饿。此外还需要调度令牌,用于限制给定设备上某种优先级的操作。最后,定义了目标读取延迟,调度器会自动调整以达到此延迟目标。该算法的实现相对简单,被认为对快速设备非常高效。
内核的 I/O 调度器
虽然一些早期算法现已退役,但官方 Linux 内核支持多种 I/O 调度器。多队列块 I/O 队列机制 (blk-mq) 将 I/O 查询映射到多个队列,任务分布在线程以及 CPU 核心之间。在此框架内,可以使用以下调度器:
- None:不应用排队算法。
- mq-deadline:截止时间调度器对多线程的适配。
- Kyber
- BFQ
更改 I/O 调度器
要列出设备的可用调度器和活动调度器(括号中):
$ cat /sys/block/sda/queue/scheduler
mq-deadline kyber [bfq] none
列出所有设备的可用调度器:
$ grep "" /sys/block/*/queue/scheduler
/sys/block/pktcdvd0/queue/scheduler:none /sys/block/sda/queue/scheduler:mq-deadline kyber [bfq] none /sys/block/sr0/queue/scheduler:[mq-deadline] kyber bfq none
要将设备 sda 的活动 I/O 调度器更改为 bfq,请使用:
# echo bfq > /sys/block/sda/queue/scheduler
根据磁盘是否为机械盘更改 I/O 调度器的过程可以自动化并在重启后保持。例如,下面的 udev 规则将机械盘调度器设置为 bfq,SSD/eMMC 设置为 bfq,NVMe 设备设置为 none:
/etc/udev/rules.d/60-ioschedulers.rules
# HDD
ACTION=="add|change", KERNEL=="sd[a-z]*", ATTR{queue/rotational}=="1", ATTR{queue/scheduler}="bfq"
# SSD
ACTION=="add|change", KERNEL=="sd[a-z]*|mmcblk[0-9]*", ATTR{queue/rotational}=="0", ATTR{queue/scheduler}="bfq"
# NVMe SSD
ACTION=="add|change", KERNEL=="nvme[0-9]*", ENV{DEVTYPE}=="disk", ATTR{queue/scheduler}="none"
重启或强制 udev#加载新规则。
调整 I/O 调度器
内核的每个 I/O 调度器都有其自己的可调参数,例如延迟时间、过期时间或 FIFO 参数。它们有助于针对设备和工作负载的特定组合调整算法。这通常是为了在给定利用率下实现更高的吞吐量或更低的延迟。可调参数及其描述可以在 内核文档 中找到。
要列出设备的可调参数(在下面的示例中,sdb 正在使用 deadline):
$ ls /sys/block/sdb/queue/iosched
fifo_batch front_merges read_expire write_expire writes_starved
为了以延迟为代价提高 deadline 的吞吐量,可以使用以下命令增加 fifo_batch:
# echo 32 > /sys/block/sdb/queue/iosched/fifo_batch
电源管理配置和写入缓存
在处理传统机械磁盘 (HDD) 时,您可能希望完全禁用或降低节电功能,并检查写入缓存是否已启用。
参见 Hdparm#电源管理配置 和 Hdparm#写入缓存。
之后,您可以创建一个 udev 规则 以在启动时应用它们。
减少磁盘读/写
避免对慢速存储驱动器进行不必要的访问有利于性能,并能增加设备的寿命,尽管在现代硬件上寿命差异通常可以忽略不计。
查看磁盘写入
iotop 软件包可以按磁盘写入量排序,并显示程序向磁盘写入的频率和数量。详情参见 iotop(8)。
将文件迁移到 tmpfs
将文件(如浏览器配置文件)迁移到 tmpfs 文件系统,由于所有文件现在都存储在 RAM 中,因此可以提高应用程序响应能力。
- 有关同步浏览器配置文件,请参阅 Profile-sync-daemon。某些浏览器可能需要特殊注意,例如 RAM 上的 Firefox。
- 有关同步任何指定文件夹,请参阅 Anything-sync-daemon。
- 有关通过在 tmpfs 中构建软件包来缩短编译时间,请参阅 Makepkg#提高构建速度。
文件系统
如果已有性能改进说明,请参阅对应的 文件系统 页面,见 #选择并调整文件系统 列表。
交换空间
详情参见 交换空间#性能。
回写间隔和缓冲区大小
详情参见 Sysctl#虚拟内存。
禁用核心转储
参见 核心转储#禁用自动核心转储。
使用 ionice 进行存储 I/O 调度
许多任务(如备份)并不依赖短时间的存储 I/O 延迟或高存储 I/O 带宽来完成任务,它们可以归类为后台任务。另一方面,为了获得良好的桌面 UI 响应能力,快速 I/O 是必要的。因此,当其他任务需要存储 I/O 时,降低分配给后台任务的存储带宽是有益的。这可以通过使用 Linux I/O 调度器 BFQ 来实现,它允许为进程设置不同的优先级。
后台进程的 I/O 优先级可以通过以下方式启动来降至 "Idle"(空闲)级别:
$ ionice -c 3 command
有关更多信息,请参阅 ionice 简短介绍 和 ionice(1)。
Trimming(修整)
为了获得最佳性能,固态硬盘的空块应定期丢弃(即 trim),以优化随机写入速度。详情请参阅 固态硬盘#TRIM。
网络
通用信息
- 内核网络:参见 Sysctl#提高性能
- 网卡 (NIC):参见 网络配置#设置设备 MTU 和队列长度
- DNS:考虑使用缓存 DNS 解析器,参见 域名解析#DNS 服务器
- Samba:参见 Samba#提高吞吐量
监管区域
不同的国家对无线网络服务有不同的标准,通过为您的网络配置设置正确的区域,您通常可以获得更强的信号。这通常在安装期间配置,但在某些情况下 设置不会被正确应用。检查 /sys/module/cfg80211/parameters/ieee80211_regdom 的内容;如果值为 00(通常限制更多的全局设置)或设置了错误的地区,请尝试添加以下 内核参数,将 XX 替换为正确的国家代码(例如,美国为 US,中国为 CN):
cfg80211.ieee80211_regdom=XX
然后重启系统。
电源 management
某些设备存在这样的问题:它们的网络适配器在仍在使用时会错误地进入省电模式,从而限制性能或导致断开连接。如果发生这种情况,请确保将软件包 升级 到最新版本以接收任何必要的固件更新,并参阅 电源管理#网络接口。
CPU
超频
超频 (Overclocking) 通过提高 CPU 的峰值时钟频率来提高计算性能。超频能力取决于 CPU 型号和主板型号的组合。它通常通过 BIOS 完成。超频也有缺点和风险。此处既不推荐也不鼓励超频。
许多 Intel 芯片无法向 acpi_cpufreq 和大多数其他实用程序正确报告其时钟频率。这会导致 dmesg 中出现大量消息,可以通过卸载内核模块 acpi_cpufreq 并将其列入黑名单来避免。要读取它们的时钟速度,请使用 i7zAUR 软件包中的 i7z。为了检查超频 CPU 的正确运行,建议进行 压力测试。
频率缩放
请参阅 CPU 频率缩放。
CPU 调度器
Linux 主线内核中默认的 CPU 调度器是 EEVDF。
- Project C — 将 BMQ 重构为 Project C 的跨项目,并基于 Project C 代码库重新创建了 PDS。因此它是这两个项目的合并,随后更新为 Project C 的 PDS。推荐作为更近期的开发成果。
- BORE — BORE 调度器专注于牺牲一些公平性,以换取调度交互式任务时的更低延迟,它构建在 CFS 之上,仅针对 vruntime 代码更新进行了调整,因此与其他非官方 CPU 调度器相比,整体更改非常小。
- SCX — 允许动态注入各种 CPU 调度器,而无需重置系统。
实时内核
某些应用,例如以全高清分辨率 (1080p) 运行电视卡,可能会受益于使用 实时内核 (realtime kernel)。
调整进程优先级
Ananicy
Ananicy CPP 是一个守护进程,以 ananicy-cpp 或 ananicy-cpp-gitAUR 形式提供,用于自动调整可执行文件的 nice 值。nice 值代表分配 CPU 资源时可执行文件的优先级。
cgroups
参见 cgroups。
LimitCPU
LimitCPU 是一个限制特定进程 CPU 使用率百分比的程序。安装 limitcpuAUR 后,您可以限制进程 PID 的 CPU 使用率,范围是 0 到 100 乘以电脑 CPU 核心数。例如,对于 8 核 CPU,百分比范围将是 0 到 800。用法:
$ limitcpu -l 50 -p 5081
irqbalance
irqbalance 的目的是在多处理器系统的各处理器之间分配硬件中断,以提高性能。它可以通过提供的 irqbalance.service 进行 控制。
关闭 CPU 漏洞缓解
关闭 CPU 漏洞缓解措施可能会提高性能。使用下面的 内核参数 来禁用所有缓解措施:
mitigations=off
它切换的所有开关的说明在 kernel.org 给出。您可以使用 spectre-meltdown-checkerAUR 或 lscpu(1)(来自 util-linux)进行漏洞检查。
针对 CPU 优化编译选项
根据您的 CPU,通过使用标志 -march=native 编译针对您的原生 CPU 微架构 优化的软件,可能会获得少量的性能提升,但使用此标志编译的任何二进制文件在其他 CPU 微架构上运行可能会很慢或无法运行。如果您使用此选项并希望更换或升级 CPU,您需要重新编译二进制文件,或选择与旧 CPU 使用相同微架构的新 CPU。您可以 默认将此选项应用于 makepkg。
如果您 编译自己的内核,也可以在内核编译期间通过 CONFIG_X86_NATIVE_CPU 选项启用此功能。然而,内核性能的改进较小,因为内核在通用代码中 禁止使用 扩展向量指令,而这些指令是常规二进制文件性能提升的主要来源,因此大部分性能改进将来自 更小的微观优化。
图形
Xorg配置
图形性能可能取决于 xorg.conf(5) 中的设置;请参阅 NVIDIA、AMDGPU 和 Intel 的文章。不当设置可能会导致 Xorg 停止工作,因此建议谨慎操作。
Mesa 配置
Mesa 驱动程序的性能可以通过 drirc 进行配置。adriconf(高级 DRI 配置器)是一个 GUI 工具,通过设置选项并将其写入标准的 drirc 文件来配置 Mesa 驱动程序。
硬件视频加速
硬件视频加速 使显卡可以进行视频编解码。
超频
与 CPU 一样,超频可以直接提高性能,但通常不被推荐。有几个软件包,如 rovclockAUR(针对 ATI 显卡)、rocm-smi-lib(较新的 AMD 显卡)、nvclockAUR(旧的 NVIDIA - 最高到 Geforce 9),以及针对较新 NVIDIA 显卡的 nvidia-utils。
参见 AMDGPU#超频 或 NVIDIA/提示与技巧#在 nvidia-settings 中启用超频。
启用 PCIe 可调大小基址寄存器 (Resizable BAR)
- 在某些系统上,启用 PCIe 可调大小基址寄存器 (Resizable BAR) 可能导致性能大幅下降。请对您的系统进行基准测试,以确保它确实提高了性能。请注意,在较新的 Intel Arc 独立显卡上,Intel 官方推荐启用 Resizable BAR,且几乎总能提高性能。
- 必须禁用 兼容性支持模块 (CSM) 才能使其生效。
PCI 规范允许使用更大的 基址寄存器 (BAR) 将 PCI 设备内存暴露给 PCI 控制器。这可以提高显卡的性能。访问完整显存不仅能提高性能,还能启用图形驱动程序中的优化。Resizable BAR、4G 以上解码 (Above 4G decoding) 和这些驱动优化相结合就是 AMD 所称的 AMD Smart Access Memory。最初在 AMD 500 系列芯片组主板上提供,后来通过 UEFI 更新扩展到 AMD 400 系列以及 Intel 300 系列及以后的型号。此设置在某些主板上可能不可用,并且已知在某些板卡上会导致启动问题。
如果 BAR 大小为 256M,则说明该功能未启用或不支持:
# journalctl -k --grep=BAR=
[drm] Detected VRAM RAM=8176M, BAR=256M
要启用它,请在主板设置中开启名为 "Above 4G Decode" 或 ">4GB MMIO" 的设置。确认 BAR 现在更大:
# journalctl -k --grep=BAR=
[drm] Detected VRAM RAM=8176M, BAR=8192M
/etc/modprobe.d/nvidia-rebar.conf
options nvidia NVreg_EnableResizableBar=1
然后 重新生成 initramfs,以便在启动早期加载 NVIDIA 内核模块时应用该选项。
可能需要完整的电源循环(关机并断开电源)才能使 PCIe BAR 大小调整生效。
可以使用 lspci -vv 验证 Resizable BAR,其中 GPU 的 BAR 大小应大于 256 MB(示例中显示的是配备 16GB RAM 的 NVIDIA 4070Ti Super 型号):
# lspci -vv -d ::03xx | grep BAR
Capabilities: [bb0 v1] Physical Resizable BAR
BAR 0: current size: 16MB, supported: 16MB
BAR 1: current size: 16GB, supported: 64MB 128MB 256MB 512MB 1GB 2GB 4GB 8GB 16GB
BAR 3: current size: 32MB, supported: 32MB
RAM、交换空间和 OOM 处理
时钟频率和时序
RAM 可以在不同的时钟频率和时序下运行,这可以在 BIOS 中配置。内存性能取决于这两个值。选择 BIOS 提供的最高预设通常会比默认设置提高性能。请注意,将频率提高到主板和 RAM 供应商都不支持的值属于超频,会产生类似的风险和缺点,请参阅 #超频。
RAM 上的 Root 覆盖层
如果在缓慢的写入介质(USB、机械 HDD)上运行且存储需求较低,则可以将 root 运行在磁盘只读 root 之上的 RAM 覆盖层中。这可以大大提高性能,代价是 root 的可写空间有限。请参阅 liverootAUR。
zram 或 zswap 上的交换空间
使用 zswap 或 zram 上的交换空间 也能获得类似的益处(代价也相似)。虽然运行方式不同,但两者的意图基本一致:
- zswap 充当压缩的 RAM 缓存,既不需要(也不允许)广泛的用户空间配置。它与交换设备协同工作,充当其缓存。通常会进入交换空间的页面可以转而进入 zswap。
- zram 是一个内核模块,可用于在 RAM 中创建压缩的块设备。此压缩块设备可用作交换设备,不需要其他交换设备作为后备。它带有许多选项,包括使用后备设备来保存冷页面的可能性。
因为这两个选项都涉及 交换 (swap) 子系统,所以影响 swap 的配置也会影响这些系统。例如,swappiness 决定了当内存压力较大时,内核应优先丢弃文件缓存还是将页面移动到交换空间。因为 zswap 拦截了移动页面到交换空间的操作,而 zram 充当了交换空间,因此该选项也会决定这两个机制被使用的频率。
使用显卡的 RAM
在极少数情况下,如果您 RAM 极少且显存富余,您可以将显存用作交换空间。参见 显存上的交换空间。
改善低内存情况下的系统响应能力
在传统的 GNU/Linux 系统上,特别是对于图形工作站,当分配的内存超额支出时,整个系统的响应能力可能会在触发内核内置的内存不足 (OOM)-killer 或获得足够的空闲内存之前,下降到接近无法使用的状态(当系统无响应时,这种情况不太可能很快发生,因为您几乎无法关闭可能继续分配更多内存的耗内存应用)。此行为还取决于特定的设置和条件,返回正常的响应状态可能需要几秒钟到半个多小时,这在严肃场景下(如会议演示期间)是非常痛苦的等待。
虽然内核以及用户空间在低内存条件下的行为在未来可能会有所改善(如 内核 和 Fedora 邮件列表中讨论的那样),但与强制重启系统或调整 vm.overcommit_* sysctl 参数相比,用户可以使用更可行和有效的选项:
- 使用 Magic SysRq 键,即
Alt+SysRq+f,手动触发内核 OOM-killer。 - 使用用户空间的 OOM 守护进程来自动(或交互式地)处理这些问题。
有时用户可能更喜欢使用 OOM 守护进程而不是 SysRq,因为使用内核 OOM-killer,您无法优先选择终止(或不终止)的进程。以下是一些 OOM 守护进程:
- systemd-oomd — 由 systemd 以
systemd-oomd.service形式提供,它使用 cgroups-v2 和压力阻塞信息 (PSI) 在内核空间发生 OOM 之前监控并对进程采取行动。
- earlyoom — 用 C 编写的简单用户空间 OOM-killer 实现。
- oomd — 基于 PSI 的 OOM-killer 实现,需要 Linux 内核版本 4.20+。配置采用 JSON 格式,相当复杂。已证实在 Facebook 的生产环境中运行良好。
- nohang — 用 Python 编写的复杂 OOM 处理程序,具有可选的 PSI 支持,比 earlyoom 具更强的可配置性。
- low-memory-monitor — GNOME 开发者的努力,旨在为用户空间应用提供更好的通信以指示低内存状态,此外它还可以配置为触发内核 OOM-killer。基于 PSI,需要 Linux 5.2+。
- uresourced — 一个小型守护进程,可为活跃的图形用户会话启用基于 cgroup 的资源保护。
- bustd — 非常轻量级的用户空间 OOM-killer,对较慢的机器很有用。基于 PSI,需要 Linux 4.2+。