OSDI 2022 Paper 论文阅读笔记整理
问题
零拷贝IO一直是一个长期的性能目标。复制会引入内存和CPU开销,限制IO密集型应用程序的性能。IO数据复制在IO堆栈内、通过其应用程序编程接口(API)和应用程序内执行。现有工作的重点是开发零拷贝IO API [1,11,12,15,17,28,32]来消除IO堆栈[27,28]和IO堆栈API内的拷贝,但IO的数据仍然被复制。
挑战
IO密集型应用程序为每个IO请求执行多达8个请求数据副本。其中许多副本发生在应用程序本身的子系统之间(应用程序副本)。在IO堆栈API上只执行一部分(例如,在系统和用户提供的缓冲区之间复制数据)。因为使用副本可以简化开发,便于子系统内部处理,简化异步IO,简化数据处理。
本文方法
本文提出了zIO,用于IO密集型应用程序的透明零拷贝IO机制。关键思路是:应用程序通常只修改其处理的数据的一部分。
-
zIO乐观地假设大多数数据保持不变,通过插入IO系统调用和C标准库调用(如memcpy和memmove)来消除副本。为了保持一致性,中间数据区域都保持未映射状态。如果应用程序试图修改任何中间数据区域,zIO会通过页面故障拦截访问,并对页面执行复制和重映射。为了处理未对齐的内存区域,zIO执行未对齐区域的复制,只保留未映射的页面对齐部分。因为未对齐的节很小,复制它们不会损害性能。
-
为了避免数据跟踪开销损害应用程序性能,zIO根据每个IO动态决定何时跟踪和何时复制。如果IO缓冲区的大小小于16KB,则zIO会复制该缓冲区。zIO还跟踪页面错误的平均数量,并消除每个缓冲区的复制字节。如果访问的字节与从副本中消除的字节的比率超过6%,zIO会复制缓冲区。
-
为了消除跨IO堆栈API的副本,使用内核旁路IO堆栈。内核旁路堆栈使用共享内存来实现它们的API,允许zIO在IO从IO设备到达时跟踪,并消除副本。
-
利用非易失性存储器(NVM)实现了进一步的优化:乐观输入持久化。如果从IO堆栈接收的输入由应用程序通过存储堆栈持久化在NVM中,则乐观输入持久化可以实现副本到存储的端到端透明消除。为此扩展了zIO以识别NVM映射。如果原始数据已经存在于NVM中,则可以消除到NVM的数据拷贝。否则,拷贝是强制持久性所必需的。
通过Redis、Icecast、MongoDB等IO密集型应用程序来评估zIO。zIO将应用程序吞吐量提高了1.8倍,使用内核旁路IO堆栈和乐观的网络接收器持久性将应用程序吞吐率提高了2.5倍。与常见的零拷贝IO堆栈API(如内存映射文件)相比,由于减少了TLB未命中开销,zIO可以将性能提高17%。
实验
实验环境:在双插槽Intel Cascade Lake SP系统的单个插槽上评估,系统运行频率为2.2GHz,每个插槽有24个内核,并配有100 GbE ConnectX-5 NIC,每个插槽都有192 GB DDR4 DRAM、3 TB Intel Optane DC NVM,每个插槽有6个DRAM和NVM DIMM,机器运行Fedora 27,Linux内核版本为5.10.0。
数据集:微基准测试、Redis redis-benchmark [21]、Icecast、MongoDB YCSB
实验对比:吞吐量
实验参数:副本数量、IO大小、线程数、页错误数、消融实验
总结
针对IO密集型应用的零拷贝IO。本文提出zIO,关键思路是:应用程序通常只修改其处理的数据的一部分。(1)乐观地假设大多数数据保持不变。为了保持一致性,中间数据区域保持未映射状态,如果应用程序试图修改任何中间数据区域,zIO通过页面故障拦截访问,并对页面执行复制和重映射。为了处理未对齐的内存区域,zIO执行未对齐区域的复制,只保留未映射的页面对齐部分。(2)避免数据跟踪开销损害应用程序性能,zIO根据每个IO动态决定何时跟踪和何时复制。如果IO缓冲区的大小小于16KB,则zIO会复制该缓冲区。zIO跟踪页面错误的平均数量,并消除每个缓冲区的复制字节。如果访问的字节与从副本中消除的字节的比率超过6%,zIO会复制缓冲区。(3)使用内核旁路IO堆栈,消除跨IO堆栈API的副本。内核旁路堆栈使用共享内存实现,允许zIO在IO从IO设备到达时跟踪,并消除副本。(4)利用非易失性存储器(NVM)实现:乐观输入持久化。如果从IO堆栈接收的输入由应用程序通过存储堆栈持久化在NVM中,则实现副本到存储的端到端透明消除。为此扩展了zIO以识别NVM映射。如果原始数据已经存在于NVM中,则可以消除到NVM的数据拷贝。