io_uring介绍(4)library使用与高级特性

​对 https://kernel.dk/io_uring.pdf  的翻译:

内核异步IO  io_uring 介绍的第7章,第8章 ——library使用与高级特性

目录

7.0 liburing library

8.0 高级用例和特性

8.1 预注册文件集和缓冲区

8.2 轮询io

8.3 内核侧轮询


7.0 liburing library

初始化:io_uring_queue_init 包含了所有 setup SQ and CQ ring信息的逻辑;

struct io_uring ring;
io_uring_queue_init(ENTRIES, &ring, 0);

一旦执行完 ,要调用:

io_uring_queue_exit(&ring);

基本提交场景

提交一个请求然后等待他完成,使用 liburing 就是下边这个样子

struct io_uring_sqe sqe;
struct io_uring_sqe cqe;

// sqe并填充 READV operation
sqe = io_uring_get_sqe(&ring);
io_uring_prep_readv(sqe, fd, &iovec, 1, offset);

// 告知kernel 我们有一个请求已经准备好被消费
io_uring_submit(&ring);

// io_uring_wait_cqe 等待刚才提交到sqe的事件完成
//completion event 可用于另外一个sqe
io_uring_wait_cqe(&ring, &cqe);

// 得到event并处理
app_handle_cqe(cqe);
io_uring_cqe_seen(&ring, cqe);


8.0 高级用例和特性

8.1 预注册文件集和缓冲区

产生原因:每次将fd(文件描述符)填充到sqe中并提交给内核时,内核必须监测对应文件IO完成后,再次删除文件引用。由于此文件引用的原子性质,因此对于高IOPS工作负载,速度会明显减慢。为了缓解这个问题,io_uring 提供了一种注册文件集合的方法:

int io_uring_register(unsigned int fd, unsigned int opcode, void *arg,
unsigned int nr_args);
  • fd:文件描述符
  • opcode:正在进行的注册类型
  • IORING_REGISTER_FILES:要注册文件集必须使用IORING_REGISTER_FILES;
  • arg:指向应用已经打开的文件fd数组;
  • nr_args:数组大小;

        一旦 io_uring_register 成功将文件集合注册后,应用就可以将文件集数组的索引(而不是使用实际的文件描述符)赋值给 sqe->fd 了,并设置 sqe->flags 字段为 IOSQE_FIXED_FILE 来标记 sqe->fd 是一个文件集索引。

8.2 轮询io

        对于追求低延迟的应用,io提供了对文件轮询io的支持。轮询指的是在不依赖硬件中断的情况下执行IO以发出完成事件的信号。当IO被轮询时,应用程序将重复向硬件驱动程序询问提交的IO请求的状态。而在非轮询IO中,应用程序通常会进入睡眠状态,等待硬件中断唤醒。对于延迟非常低的设备和IOPS非常高的应用,轮询可以显著提高性能。对于程序也是如此,高中断率使得非轮询负载的开销要高得多。轮询对延迟or总体IOPS速率的影响,根据应用程序、IO设备和机器的性能而有所不同。

        要使用IO轮询,必须在调用io_uring_setup时将io_uring_params->flags设置为IORING_SETUP_IOPOLL,或者使用liburing的io_uring_queue_init。使用轮询后,应用不能通过CQ环的尾部 来检查可用的“完成事件”了,因为不会自动触发异步硬件的“完成事件”了。应用程序必须通过调用io_uring_enter(2)来主动查找和获取这些事件,设置IORING_ENTER_GETEVENTS 和min_complete 设置为所需的事件数。 对于polled IO,要求kernel 在驱动侧简单的检查 “完成事件” ,不是持续循环执行。

  在使用IORING_SETUP_IOPOLL的实例上 ,只有下列 op-codes 可以使

  • IORING_OP_READV
  • IORING_OP_WRITEV,
  • IORING_OP_READ_FIXED
  • IORING_OP_WRITE_FIXED

不可轮询的op-code 码不可用,io_uring_enter会返回-EINVAL,因为内核不知道该sleep

waiting还是该进行轮询。

8.3 内核侧轮询

        尽管io_uring可以发出更少的系统调用来完成更多的请求。在某些情况下,我们可以通过进一步减少执行IO所需的系统调用数量来提高效率。其中一个特性是内核端轮询。启用后,io_uring不需要在通过io_uring_enter来提交。当应用程序更新SQ环并填写新的sqe时,内核端将自动通知新entry并提交它们。这是通过特定于该io的内核线程完成的。

        要使用这个特性,io_uring 实例必须使用flags IORING_SETUP_SQPOLL 注册,或者传给 io_uring_queue_init 。另外,如果应用程序希望将此线程限制为特定CPU,可以通过IORING_SETUP_SQ_AFF实现,并且设置sq_thread_cpu 为指定的CPU。设置IORING_SETUP_SQPOLL需要特殊权限,如果用户没有权限,io_uring_queue_init会报错-EPERM。

        为了避免在io_uring实例处于非活动状态时浪费太多CPU,内核端线程在空闲一段时间后将自动进入睡眠状态。当这种情况发生时,线程将在SQ ring标志成员设置IORING_SQ_NEED_WAKEUP。如果设置了这个值,应用程序就不能依赖内核自动查找新条目,它必须在设置IORING_ENTER_SQ_WAKEUP的情况下调用io_uring_enter,如下:

/* 填充 sqe entries */
add_more_io();
/*
* 当轮询线程正在sleep, 需要调用 io_uring_enter() 使得kernel 发现 the new IO
* 
*/
if ((*sqring→flags) & IORING_SQ_NEED_WAKEUP)
io_uring_enter(ring_fd, to_submit, to_wait, IORING_ENTER_SQ_WAKEUP);

        只要应用程序继续执行IO,就永远不会设置IORING_SQ_NEED_WAKEUP,我们可以在不执行单个系统调用的情况下有效地执行IO。但是,在应用程序中始终保持与上面类似的逻辑非常重要,以防线程进入睡眠状态。可以设置sq_thread_idle(单位ms)。如果未设置此成员,内核默认为在使线程进入睡眠状态之前的一秒钟空闲时间。

        对于IRQ 驱动的 IO,“完成事件“ 可以被应用程序在CQ ring中直接找到。如果 io_uring 实例使用IORING_SETUP_IOPOLL注册,内核线程将负责获取 完成的events。因此,对于这两种情况,除非应用程序希望等待IO发生,否则它可以简单地查看CQ环以查找完成事件。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Mac Rust io-uring是一种在Mac操作系统上使用Rust语言进行开发的io-uring库。 io-uringLinux内核中的一个新特性,它为应用程序提供了一种高性能、高效率的异步I/O操作方式。它通过使用事件驱动和无锁技术,实现了在高并发环境下进行文件操作的优化。io-uring提供了更低的系统开销和更高的吞吐量,特别适用于需要大量I/O操作的应用程序。 虽然io-uring最初是为Linux内核设计的,但由于其高性能的特性,一些开发者试图将其移植到其他操作系统上。其中,Mac Rust io-uring就是一个在Mac操作系统上使用Rust语言实现io-uring的库。 使用Mac Rust io-uring,开发者可以在Mac环境下利用io-uring特性来提高文件操作的性能。这对于需要进行大量I/O操作的应用程序来说,是一个很有价值的工具。例如,对于数据库、Web服务器或文件传输等应用,通过使用Mac Rust io-uring,可以显著提高其性能和吞吐量。 Mac Rust io-uring不仅提供了对io-uring的封装,还提供了一些更高级别的功能和接口,以方便开发者使用。开发者可以使用Mac Rust io-uring来实现一些高级的文件操作,例如批量读取或写入文件,提高数据处理的效率。 总之,Mac Rust io-uring是一个在Mac操作系统上使用Rust语言开发的io-uring库,它能够为开发者提供高性能的异步I/O操作方式,从而提高应用程序的性能和吞吐量。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值