FAST‘23《λ-IO: A Unified IO Stack for Computational Storage》论文解读

news/2024/4/26 17:06:57/文章来源:https://blog.csdn.net/m0_37340681/article/details/129251155

FAST’23《λ-IO: A Unified IO Stack for Computational Storage》论文解读

Data:2023-2-27

Ref: Z. Yang et al., “λ-IO: A Unified IO Stack for Computational Storage,” in 21st USENIX Conference on File and Storage Technologies (FAST 23), Santa Clara, CA, Feb. 2023, pp. 347–362.

省流版:计算型存储通过减少数据搬运的方式提高了数据处理的性能,但是当前的计算型存储缺乏高效的软件栈,增大了开发难度,无法充分发挥性能。这个工作的核心是修改并移植eBPF到CSD和内核中,为主机和CSD提供了相同的运行时环境。为了解决不同应用在不同平台执行效率不同的问题,通过动态性能监测和时延评估模型将任务选择性地分发给主机或者CSD以最大化系统性能。同时提供了基于现有I/O栈的API。这篇论文是清华大学舒继武教授团队在NDP领域耕耘数年的最新成果,是目前近数据领域为数不多的全栈开发框架,让近数据处理技术距离广泛应用更近了一步,期待开源代码!开源地址(截至2023-2-27还没有内容):https://github.com/thustorage/lambda-io

文章目录

  • FAST'23《λ-IO: A Unified IO Stack for Computational Storage》论文解读
      • 背景及问题
      • λ-IO
        • API与工作流程
        • 运行时环境移植
          • eBPF扩展(sBPF)
          • 文件管理
        • 请求分发器
          • 评估模型
          • 性能监测
      • 实验
      • 总结

背景及问题

NDP(Near-Data Processing)技术通过在存储器内部支持数据处理,减少了数据搬移的开销。支持NDP技术的SSD称为计算型存储(CSD,Computational Storage)。

但是计算型存储器内通常使用低功耗的嵌入式处理器,计算性能低。如果盲目地将任务交给CSD执行,可能会造成性能低下;同时即便有的任务在CSD内执行更快,CSD内资源紧张时将这个任务交给主机处理也更好。本文进行了2项实验证明以上2点:1)如下图a所示。Stats64和32分别是将一个文件视为64或者32位的整数并进行求和等操作。可以看出Stats64在盘内执行效率更高,32在主机执行效率更高(文内没有解释原因,猜测是因为本文所用的开发板是64位的A53导致的,64位计算效率较高)2)如下图b所示,横轴代表分别在主机和CSD执行任务的不同阶段的时延,可以看到主机在一开始时延很高但是后面时延就低于CSD了,因为主机在刚开始时并没有缓存数据。

image-20230225164414245

λ-IO

本文的主要工作包含3个方面:API、eBPF运行时移植(sBPF)、请求分发调度。λ-IO的架构图如下所示。

image-20230227111819907

API与工作流程

λ-IO的一个设计原则是尽量兼容以及利用现有的IO栈,因此调用方法上也尽量与现有接口保持一致以降低开发和学习成本。API列表以及示例程序如下所示,接下来介绍API含义及工作流程:

  • 首先需要定义算子。用户在compute内自定义数据处理方法(代码第1-9行),λ-IO运行时系统会将数据放入input内,并且会开辟一个空间用于返回数据由output参数所指向,length_i代表了input内的数据长度。定义好算子后编译为sBPF字节码。
  • 在使用时,首先需要利用load加载算子文件(代码第13行)。load根据提供的sBPF字节码程序的路径读取程序,然后分别发送给内核和CSD内的执行环境,并返回一个λ_id。然后两个运行时环境进行程序检查后翻译为各自平台的可执行二进制程序*(这里有点不太理解为什么要CSD来执行字节码翻译,移植翻译器复杂并且CSD性能低,为什么不在主机翻译好后直接发送给CSD呢?)*
  • 打开与关闭文件的API与POSIX完全相同(代码第24,26行),λ-IO复用了其文件句柄。
  • 读文件时,使用pread_λ进行读取操作代替pread(代码第17行)。pread_λ多出来了一个λ_id参数,作用就是传入之前通过load加载的算子。当数据读出来了之后,λ-IO就会调用之前定义的算子,将读出来的原始数据传入compute,并将计算完成后存储在output中的数据存储到pread_λ给的buf中。这个步骤的一个核心问题是,如何在盘内进行这一过程,因为盘内并没有文件系统的语义信息,也就是说盘内无法通过句柄、路径等参数在盘内将数据加载到compute的参数中。解决方法在下一节中介绍。
  • 写文件与读文件类似,不过输入输出是反过来的。调用pwrite_λ时传入的buf是作为computeinput,计算出需要写入的数据后写入到output中,λ-IO会将其写入文件的offset处。

image-20230227112058792

// sum.c 
ssize_t compute(void *output, void *input, size_t length_i) { int sum = 0; for (int i = 0; i < length_i / sizeof(int); i++) { sum += ((int *)input)[i]; } *output = sum; return sizeof(int); // return the output size
}// main.c 
int lambda_io_sum(int fd, int file_size) {int l_id = load_l("sum.sbpf"); char buf[sizeof(int)]; int sum = 0; for (int i = 0; i < file_size; i += BUF_SIZE) {pread_l(fd, buf, BUF_SIZE, i, l_id);sum += *(int *)buf; } return sum;
}int main() { int fd = open("path/to/file"); lambda_io_sum(fd, FILE_SIZE); close(fd); return 0; 
}

运行时环境移植

为了在主机和CSD两种完全不同的平台和系统内提供相同的执行环境,λ-IO选择了时下流行的eBPF技术。根据我的理解,eBPF是一种程序翻译技术,可以将用户按规范编写的程序编译为eBPF字节码,然后经过检查校验后发送到执行环境内翻译为平台特定的二进制程序。

λ-IO为了解决eBPF应用在CSD内的问题,将eBPF修改扩展为了sBPF。运行时环境的移植主要包含2部分的工作,eBPF扩展以及文件管理:

eBPF扩展(sBPF)

eBPF应用在CSD内主要面临2个问题,一个是指针检查的问题,其次是循环限制的问题。

  • 指针访问:由于eBPF最初是为内核设计的,因此对指针数据访问的检查很严格。eBPF提供了函数bpf_probe_read来检查指针访问,但是开销很大。因此λ-IO采用一个简单的检查机制,当访问一个地址时,检查其是否是在[input,input+length_i)或者[output,output+length_i)范围内,如果不是的话就返回错误码。
  • 循环限制:由于eBPF在内核中执行,因此需要严格控制其循环数以避免其执行时间过长。eBPF会在静态检查时检查其循环次数,超过循环次数限制时会不通过。但是在CSD内其循环次数往往难以确定,是动态变化的,无法通过静态检查解决。因此sBPF在运行时动态检查循环次数,在每个循环后添加一个计数器,当循环次数超过阈值时停止执行。通常阈值设置为输入数据长度相同数量级的数值,可以尽量避免干扰正常程序执行同时可以终止bug。
文件管理

λ-IO为了尽量少修改现有IO栈以及复用现有架构,实现对不同文件系统的兼容,基于VFS和页缓存构建了文件访问机制。文件管理的主要目的是为pread_λpwrite_λ提供inputoutput参数的地址。

在主机端,访问文件很简单,λ-IO打开文件后通过mmap映射所需的数据到用户态,然后作为input参数传入即可。但是在CSD端,CSD内部是没有文件索引信息的,因此需要主机先读取出所需文件的元数据(通过filefrag工具),然后通过自定义接口发送给盘内的运行时环境。

对于写入请求,可能会需要扩展文件长度。这时需要主机先利用fallocate提前分配好空间再发送请求给CSD。并且分配空间后需要将extent的unwritten标志位重置,否则主机读到这个extent时会认为里面没有数据直接返回空,但是其实CSD可能已经在盘内往里面写入了数据。

对于数据一致性的问题,主要是主机和CSD间的一致性。λ-IO采取了加锁的方式,再进行λ操作时将文件锁住避免执行请求时数据被主机修改导致数据不一致。

请求分发器

一个请求可能在主机也可以在CSD中执行更快,同时随着工作负载的变化,在CSD执行更快的请求可能暂时交给主机执行也会更快。为了解决这个问题实现性能的最大化,本文设计了一个动态请求分发器。

动态请求分发器的核心思想是将一个请求切分为多个子请求,并且实时获取系统性能参数,然后通过一个简单的时延评估模型定期评估在主机和在CSD的执行时间,然后分发到耗时最短的平台上。

评估模型

λ-IO定义了几个模型参数:

  • DDD:需要从存储单元中读取出来的数据大小
  • BsB_sBs:存储单元到CSD控制器的传输带宽,也就是存储单元的速度
  • BdB_dBd:CSD到主机间的传输带宽,也就是硬盘接口的速度
  • BhB_hBh:主机的计算带宽,也就是主机端的数据处理速度
  • th,tdt_h,t_dth,td:主机与CSD的执行时间
  • α\alphaα:数据放大率,也就是原始数据经过处理后结果数据的大小比值。例如在盘内进行数据处理后,传输到主机的数据量就为αD\alpha DαD
  • β\betaβ:性能比率,CSD相比主机性能的比值。即CSD的处理能力为βBh\beta B_hβBh
  • ccc:缓存命中率

根据这些参数,评估模型如下:
th=(1−c)DBs+(1−c)DBd+DBht_h=\frac{(1-c)D}{B_s} + \frac{(1-c)D}{B_d} + \frac{D}{B_h} th=Bs(1c)D+Bd(1c)D+BhD

td=DBs+αDBd+DβBht_d=\frac{D}{B_s} + \frac{\alpha D}{B_d} + \frac{D}{\beta B_h} td=BsD+BdαD+βBhD

性能监测

只要获取到模型中各个参数的值,即可评估出某个任务在某一端上的执行时间。但是这些值有的并不是能快速获得精确值的,本文将这些参数分为了2个部分来获取:

  • 直接获取参数

    有一些参数是可以直接获取的,包括数据量D可以直接从请求中获取的,缓存命中率c可以通过查询page cache获取(不断遍历访问page cache个人认为开销有点高了)

  • 估计参数

    有一些参数是没法直接获取的,因此需要通过监测系统状态得到,包括各个带宽和比率。λ-IO并不测量整个系统的可用资源,而是以请求为单位分别测量他们的参数。具体的测量方法文中没有提及。为了避免为每个请求都测量参数而引发巨大的开销,λ-IO采取的周期测量的方法。在一个时间段内的前数个请求中,将请求同时发送给主机和CSD以获取两端的参数,从而进行评估后决定这个周期剩余的请求应该交给哪端执行。在一个周期结束后重新进行评估。

实验

本文的实验基于可编程SSD Daisy开发板完成。实验部分简单介绍,详情大家可以去看论文。

在单应用的测试中,λ-IO分别与有缓存的IO(B),无缓存的直接IO(I),MMAP(M),全部在主机端执行(K),全部在设备端执行(D),动态执行(λ)几种方式进行了对比。并且在进行了预热有缓存数据(w/o)和没有预热没有缓存数据(w/)的2种情况下进行了对比,结果表明在各种情况下λ-IO都能取得几乎最佳的性能。

image-20230227215235100

同时本文将λ-IO移植到了Spark SQL中分析在实际系统中的性能。可以看到在IO密集的查询中能够取得比较好的效果,在CPU密集型任务中能够获得与主机近似的性能。

image-20230227215742872

总结

这篇文章为计算型存储设计了一个完整的I/O栈,涉及到用户态、内核态、存储器固件等多个层面的开发与移植工作,做的工作非常多,具备较高的实用价值。我认为这项工作还能从以下几个方面进一步研究或者优化:

  • 文件系统部分为了与现有IO栈兼容,牺牲了部分的性能可优化空间。例如文件系统的元数据仍然需要在主机端进行管理,在存储器数量较多或者高并发请求时可能会成为瓶颈。采取盘内文件系统(DevFS,FAST‘18)的方式管理也许可以解决这一问题。

  • 性能评估的准确性应该可以进一步优化。首先对于单个请求来说,需要两端同时执行一个任务以获取参数,但是同时执行时两端发出的IO请求会相互影响;其次对于多应用并发时,评估的结果与两端分别正在执行的任务息息相关,可能评估结束后系统状态就变化了。获取的性能评估结果可能偏差较大。

  • API不支持多文件的数据联合处理。输入输出数据都来自于单个文件的读写操作,某些任务(例如将多个文件的内容读取出来合并到一个文件中)无法在CSD内完成,限制了能处理的任务类型。

  • 当文件规模很大时,输入输出缓冲区可能会放不下。主机端可以采用虚拟内存的方式进行swap操作,但是CSD内没有OS的支持,物理内存的大小限制了能处理的数据大小。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.luyixian.cn/news_show_75042.aspx

如若内容造成侵权/违法违规/事实不符,请联系dt猫网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

数据可视化第二版-03部分-06章-比较与排序

文章目录数据可视化第二版-03部分-06章-比较与排序总结可视化视角-比较与排序代码实现创建虚拟环境1. python版本管理2.切换到指定版本后安装虚拟环境切换路径到文件当前路径柱形图环形柱状图子弹图哑铃图雷达图词云图教材截图数据可视化第二版-03部分-06章-比较与排序 总结 …

Java 多线程 --- 多线程的相关概念

Java 多线程 --- 多线程的相关概念Race Condition 问题并发编程的性质 --- 原子性, 可见性, 有序性上下文切换 (Context Switch)线程的一些故障 --- 死锁, 活锁, 饥饿死锁 (Deadlock)活锁(Livelock)死锁和活锁的区别饥饿(Starvation)背景: 操作系统 — 线程/进程 同步 Race Co…

【unity学习记录】Canvas Group组件

&#x1f497; 未来的游戏开发程序媛&#xff0c;现在的努力学习菜鸡 &#x1f4a6;本专栏是我关于游戏开发的学习笔记 &#x1f236;本篇是unity的Canvas Group组件 Canvas Group画布组介绍详解1. Alpha2. Interactable3. Blocks Raycasts4. Ignore Parent Groups介绍 画布组…

6.0.4:GrapeCity Documents for Excel GcExcel Crack

在更短的时间内生成 Excel 电子表格&#xff0c;不依赖于 Excel&#xff01; 在任何应用程序中转换、计算、格式化和解析电子表格。 快速高效&#xff1a;其轻巧的尺寸意味着 Documents for Excel 针对快速处理大型 Excel 文档进行了优化 使用适用于 Windows、Linux 和 Mac 的…

JVM 学习(2)—简单理解强、软、弱、虚 Java 四大引用

一、Java 引用概述 Java 中出现四种引用是为了更加灵活地管理对象的生命周期&#xff0c;以便在不同场景下灵活地处理对象的回收问题。不同类型的引用在垃圾回收时的处理方式不同&#xff0c;可以用来实现不同的垃圾回收策略。Java 目前将其分成四类&#xff0c;类图如下&…

mysql一两种索引方式hash和btree

1. Hash索引&#xff1a; Hash 索引结构的特殊性&#xff0c;其检索效率非常高&#xff0c;索引的检索可以一次定位&#xff0c;不像B-Tree 索引需要从根节点到枝节点&#xff0c;最后才能访问到页节点这样多次的IO访问&#xff0c;所以 Hash 索引的查询效率要远高于 B-Tree 索…

信息安全概论之《密码编码学与网络安全----原理与实践(第八版)》

前言&#xff1a;在信息安全概论课程的学习中&#xff0c;参考了《密码编码学与网络安全----原理与实践&#xff08;第八版&#xff09;》一书。以下内容为以课件为主要参考&#xff0c;课本内容与网络资源为辅助参考&#xff0c;学习该课程后作出的总结。 一、信息安全概述 1…

力扣Top100题之两数相加(Java解法)

0 题目描述 给你两个 非空 的链表&#xff0c;表示两个非负的整数。它们每位数字都是按照 逆序 的方式存储的&#xff0c;并且每个节点只能存储 一位 数字。 请你将两个数相加&#xff0c;并以相同形式返回一个表示和的链表。 你可以假设除了数字 0 之外&#xff0c;这两个数…

MVCC 当前读 快照读 RC read view RR下事务更新不会丢失

MVCC(multi-version-concurrent-control) MVCC是行锁的一个变种&#xff0c;但MVCC在很多情况下它避免了加锁。不是buffer块&#xff0c;而是buffer中的记录行。 MVCC (Multi-Version Concurrency Control) (注&#xff1a;与MVCC相对的&#xff0c;是基于锁的并发控制&#x…

【无限思维画布】制作思维导图第五步,节点创建与连接,拖拽对齐与双击缩放

正在为无限词典制作单词思维导图功能&#xff0c;实现无限单词导图&#xff0c;无限思维画布。目前制作到第五步&#xff0c;实现节点创建、节点连接、节点拖拽对齐&#xff1a; 节点创建与连接&#xff0c;拖拽对齐Details 第四步&#xff0c;推倒重来。 一开始受vue-mindma…

【Python小程序】这款成语接龙小程序,让小孩儿轻松记住500个成语,在家里常玩,语文直上135,仅此一份,快收藏~(太强大了)

前言 学习路上&#xff0c;那我同行。 哈喽~大家晚上好呀&#xff0c;我是你们的栗子同学。 所有文章完整的素材源码都在&#x1f447;&#x1f447; 粉丝白嫖源码福利&#xff0c;请移步至CSDN社区或文末公众hao即可免费。 成语接龙是一个传统的文字游戏。很多孩子都喜欢玩。…

Lesson9---回归问题

9.1 机器学习基础 课程回顾 Python语言基础Numpy/Matplotlib/Pandas/Pillow应用TensorFlow2.0 低阶API 即将学习 机器学习、人工神经网络、深度学习、卷积神经网络典型模型的TensorFlow2.0实现 9.1.1 机器学习 机器学习&#xff08;Machine Learning&#xff09;&#xf…

关于C语言中最大公因数的思考

目录 如何去求最大公因数利用枚举法&#xff1a; 如何去求最大公因数利用辗转相除法&#xff1a; 例1&#xff1a;最大公因数使用for循环和if语句 示例2&#xff1a;最大公因数使用while循环和if ... else语句 例3&#xff1a;正负数均为最大公因数 如何去求最大公因数利用…

【2023-02-27】349.两个数组的交集

题目链接&#xff1a;349.两个数组的交集 解题思路&#xff1a;点我 class Solution { public:vector<int> intersection(vector<int>& nums1, vector<int>& nums2) {unordered_set<int>res_set;unordered_set<int>nums1_set(nums1.beg…

qt-c++进阶1-window、linux下获取本机所有网卡ip信息、根据网卡名获取ip地址。

系列文章目录 例如&#xff1a;第一章 主要是通过qt-c实现获取本机电脑的网卡信息或者是IP信息 文章目录系列文章目录前言一、获取本机网卡IP信息1.1 获取ip地址方法1.2 代码实例总结前言 总结c获取本机网卡信息的方法 第一章&#xff1a;适用于windows操作系统、linux操作系…

Aspose.Slides for .NET 授权须知

Aspose.Slides是一款用于生成&#xff0c;管理和转换PowerPoint幻灯片的本机API&#xff0c;可以使用多种格式&#xff0c;而不需要Microsoft PowerPoint。并且可在任何平台上操作PowerPoint演示文稿。 Aspose.Slides for .NET是一款.NET PowerPoint管理API&#xff0c;用于读…

常用逻辑运算符

逻辑符号表格 逻辑符号含义描述&按位与将数字转成二进制计算&#xff0c;两个位都为1时&#xff0c;结果才为1|或两个位都为0时&#xff0c;结果才为0 &#xff0c;反知任何一个为1结果为1^异或两个位相同为0&#xff0c;不同为1<<左移整体二进位全部左移若干位&…

webrtc音视频通话(一)搭建turn服务器

全球定位&#xff1a;webrtc音视频通话&#xff08;一&#xff09;搭建turn服务器webrtc音视频通话&#xff08;二&#xff09;简单音视频通话webrtc音视频通话&#xff08;三&#xff09;整合websocket在学习webrtc之前呢&#xff0c;需要对websocket有一定基础&#xff0c;如…

腾讯云卖向“有币”区块链

曾经坚决“不涉币”的腾讯云将业务延伸向“有币区块链”。 在首届 Web3 全球峰会“腾讯云Web3构建日”上&#xff0c;腾讯云宣布进军Web3&#xff0c;并公开了与Ankr、Avalanche、Scroll和Sui 四个原生区块链项目的合作&#xff0c;其中前两个项目都发行了加密货币&#xff0c…

比特数据结构与算法(第四章_中_续②)堆解决Topk问题(最小的k个数)

TopK问题介绍&#xff1a;在N个数中找出最大/小的前K个 &#xff08;比如在1000个数中找出最大/小的前10个&#xff09;以前的方法&#xff1a;冒泡排序。时间复杂度&#xff1a; O(N^2)现在找最大的k个数的方法&#xff1a;方法1&#xff1a;堆排序降序&#xff0c;前N个就是最…