QPL 压缩
Intel Query Processing Library(Intel QPL)是提供压缩和解压功能的开源库,基于 deflate 压缩算法(RFC 1951)。
QPL 压缩依赖 Intel In-Memory Analytics Accelerator(IAA)和共享虚拟内存(SVM)技术。这些功能从第四代 Intel Xeon 可扩展处理器开始支持,该处理器代号为 Sapphire Rapids(SPR)。
有关 QPL 的更多介绍,参见 QPL 简介。
QPL 压缩框架
+----------------+ +------------------+
| MultiFD 线程 | |accel-config 工具 |
+-------+--------+ +--------+---------+
| |
| |
|压缩/解压 |
+-------+--------+ | 配置 IAA
| QPL 库 | | 资源
+-------+---+----+ |
| | |
| +-------------+-------+
| 打开 IAA |
| 设备 +-----+-----+
| |idxd 驱动 |
| +-----+-----+
| |
| |
| +-----+-----+
+-----------+IAA 设备 |
提交任务 +-----------+
经 enqcmd
构建与安装 QPL
$git clone --recursive https://github.com/intel/qpl.git qpl
$mkdir qpl/build
$cd qpl/build
$cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=/usr -DQPL_LIBRARY_TYPE=SHARED ..
$sudo cmake --build . --target install
有关 QPL 安装的更多信息,参见 QPL 安装。
IAA 设备管理
IAA 设备数量取决于 Xeon 产品型号。在 SPR 服务器上,最多可有 8 个 IAA 设备,每个处理器插槽最多 4 个。
默认情况下,所有 IAA 设备均处于禁用状态,需要用户手动配置并启用。
通过以下命令检查设备数量:
#lspci -d 8086:0cfe
6a:02.0 System peripheral: Intel Corporation Device 0cfe
6f:02.0 System peripheral: Intel Corporation Device 0cfe
74:02.0 System peripheral: Intel Corporation Device 0cfe
79:02.0 System peripheral: Intel Corporation Device 0cfe
e7:02.0 System peripheral: Intel Corporation Device 0cfe
ec:02.0 System peripheral: Intel Corporation Device 0cfe
f1:02.0 System peripheral: Intel Corporation Device 0cfe
f6:02.0 System peripheral: Intel Corporation Device 0cfe
配置与启用 IAA 设备
accel-config 工具用于启用 IAA 设备,以及配置 IAA 硬件资源(工作队列和引擎)。一个 IAA 设备具有 8 个工作队列和 8 个处理引擎,可以通过 group 属性把多个引擎分配给一个工作队列。
安装 accel-config 的方法参见 accel-config 安装。
以下示例展示如何配置并启用一个 IAA 设备。
#accel-config config-engine iax1/engine1.0 -g 0
#accel-config config-engine iax1/engine1.1 -g 0
#accel-config config-engine iax1/engine1.2 -g 0
#accel-config config-engine iax1/engine1.3 -g 0
#accel-config config-engine iax1/engine1.4 -g 0
#accel-config config-engine iax1/engine1.5 -g 0
#accel-config config-engine iax1/engine1.6 -g 0
#accel-config config-engine iax1/engine1.7 -g 0
#accel-config config-wq iax1/wq1.0 -g 0 -s 128 -p 10 -b 1 -t 128 -m shared -y user -n app1 -d user
#accel-config enable-device iax1
#accel-config enable-wq iax1/wq1.0
备注
IAX 是 IAA 的早期名称。
IAA设备索引为 1,可使用ls -lh /sys/bus/dsa/devices/iax*命令查询IAA设备索引。在组 0 中配置 8 个引擎和 1 个工作队列,因此提交到该工作队列的所有压缩任务可以由全部引擎同时处理。
设置工作队列属性,包括工作模式、工作队列大小等。
启用
IAA1设备和工作队列 1.0。
备注
将工作队列模式设为共享模式,因为 QPL 库只支持共享模式。
更详细的配置请参见 IAA 配置示例。
IAA 单元测试
在 Xeon 平台启用
IAA设备的方法参见 IAA 用户指南。IAA设备驱动为 Intel Data Accelerator Driver(idxd),建议 Linux 内核版本至少为 5.18。在内核命令行添加
"intel_iommu=on,sm_on"参数,以启用SVM功能。
以下是使用 iaa_test 验证 IAA 设备驱动和 SVM 的简单方法:
#./test/iaa_test
[ info] alloc wq 0 shared size 128 addr 0x7f26cebe5000 batch sz 0xfffffffe xfer sz 0x80000000
[ info] test noop: tflags 0x1 num_desc 1
[ info] preparing descriptor for noop
[ info] Submitted all noop jobs
[ info] verifying task result for 0x16f7e20
[ info] test with op 0 passed
为迁移分配 IAA 资源
迁移没有 IAA 资源配置参数,accel-config 工具的配置也不能直接指定迁移所使用的 IAA 资源。
采用 QPL 压缩方式的 multifd 迁移会使用所有已启用且处于共享模式的工作队列。
备注
默认情况下,访问 IAA 资源需要 sudo 命令或 root 权限。管理员可以修改 IAA 设备节点的所有者,使 QEMU 能以指定用户的权限使用 IAA。
例如:
#chown -R qemu /dev/iax
如何在迁移中使用 QPL 压缩
1 - 安装 QPL 库;如果使用 IAA,还需安装 accel-config 库。
2 - 通过 accel-config 配置并启用 IAA 设备和工作队列。
3 - 使用 --enable-qpl 参数构建 QEMU。
例如:configure --target-list=x86_64-softmmu --enable-kvm
--enable-qpl
4 - 在迁移过程中启用 QPL 压缩。
迁移时设置
migrate_set_parameter multifd-compression qpl。QPL压缩不支持配置压缩级别,只支持一个压缩级别。
QPL 与 ZLIB 的差异
虽然 QPL 和 ZLIB 都基于 deflate 压缩算法,而且 QPL 支持 ZLIB 的头部和尾部,但迁移中的 QPL 压缩仍无法与 ZLIB 完全兼容。
QPL 只支持 4K 历史缓冲区,而 ZLIB 默认使用 32K。ZLIB 压缩的数据可能无法由 QPL 正确解压,反之亦然。
QPL 不支持 ZLIB 流式压缩中的 Z_SYNC_FLUSH 操作。当前 ZLIB 实现使用 Z_SYNC_FLUSH,因此每个 multifd 线程都有一个 ZLIB 流上下文,所有页面的压缩和解压都基于此流。QPL 无法解压这类数据,反之亦然。
关于 Z_SYNC_FLUSH 的介绍,请参见 Zlib 手册。
最佳实践
用户启用 IAA 设备执行 QPL 压缩时,建议在目标端启动参数中添加 -mem-prealloc。此参数可以避免 I/O 缺页,减少 IAA 压缩和解压的开销。
带 -mem-prealloc 参数的启动示例:
$qemu-system-x86_64 --enable-kvm -cpu host --mem-prealloc ...
以下示例测量未使用 -mem-prealloc 时目标端的 I/O 缺页。svm_prq 表示 I/O 缺页发生次数和处理时间。
#echo 1 > /sys/kernel/debug/iommu/intel/dmar_perf_latency
#echo 2 > /sys/kernel/debug/iommu/intel/dmar_perf_latency
#echo 3 > /sys/kernel/debug/iommu/intel/dmar_perf_latency
#echo 4 > /sys/kernel/debug/iommu/intel/dmar_perf_latency
#cat /sys/kernel/debug/iommu/intel/dmar_perf_latency
IOMMU: dmar18 Register Base Address: c87fc000
<0.1us 0.1us-1us 1us-10us 10us-100us 100us-1ms 1ms-10ms >=10ms min(us) max(us) average(us)
inv_iotlb 0 286 123 0 0 0 0 0 1 0
inv_devtlb 0 276 133 0 0 0 0 0 2 0
inv_iec 0 0 0 0 0 0 0 0 0 0
svm_prq 0 0 25206 364 395 0 0 1 556 9