问题标签 [io-uring]
For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.
linux - Linux 上真的没有异步块 I/O 吗?
考虑一个受 CPU 限制但也具有高性能 I/O 要求的应用程序。
我正在将 Linux 文件 I/O 与 Windows 进行比较,我根本看不出 epoll 将如何帮助 Linux 程序。内核会告诉我文件描述符“准备好读取”,但我仍然必须调用阻塞 read() 来获取我的数据,如果我想读取兆字节,很明显这会阻塞。
在 Windows 上,我可以创建一个设置了 OVERLAPPED 的文件句柄,然后使用非阻塞 I/O,并在 I/O 完成时收到通知,并使用该完成函数中的数据。我不需要花费应用程序级的挂钟时间来等待数据,这意味着我可以将线程数精确调整到我的内核数,并获得 100% 的有效 CPU 利用率。
如果我必须在 Linux 上模拟异步 I/O,那么我必须分配一些线程来执行此操作,而这些线程将花费一些时间来处理 CPU 的事情,并且会花费大量时间阻塞 I/O,另外,与这些线程之间的消息传递也会产生开销。因此,我将过度订阅或未充分利用我的 CPU 内核。
我将 mmap() + madvise() (WILLNEED) 视为“穷人的异步 I/O”,但它仍然没有到达那里,因为完成后我无法收到通知——我有“猜”,如果我猜“错”了,我最终会阻塞内存访问,等待数据来自磁盘。
Linux 似乎在 io_submit 中有异步 I/O 的开始,而且它似乎也有一个用户空间 POSIX aio 实现,但是这种方式已经有一段时间了,我知道没有人会为这些系统的关键性担保, 高性能应用。
Windows 模型的工作原理大致如下:
- 发出异步操作。
- 将异步操作绑定到特定的 I/O 完成端口。
- 等待该端口上的操作完成
- 当 I/O 完成时,等待端口的线程解除阻塞,并返回对挂起的 I/O 操作的引用。
步骤 1/2 通常作为一件事情完成。步骤 3/4 通常使用工作线程池完成,而不是(必然)与发出 I/O 的线程相同。这个模型有点类似于 boost::asio 提供的模型,除了 boost::asio 实际上并没有给你异步的基于块的(磁盘)I/O。
与 Linux 中的 epoll 不同的是,在第 4 步中,还没有发生任何 I/O——它将第 1 步提升到第 4 步之后,如果您已经确切知道自己需要什么,那么这是“倒退”。
在编写了大量嵌入式、桌面和服务器操作系统之后,我可以说这种异步 I/O 模型对于某些类型的程序来说是非常自然的。它也是非常高吞吐量和低开销的。我认为这是 Linux I/O 模型在 API 级别上剩下的真正缺点之一。
io - io_uring 到底是什么?
最近我在不同的论坛上看到了这个。据我通过阅读一些论坛讨论可以看出,这与输入和输出有关。io_uring 到底是什么?
linux - 使用 io_uring 进行多路复用
我最近使用 epoll 编写了一个简单的 TCP 服务器,但我想探索高性能多路复用的其他机制,为此我遇到了 io_uring,并计划使用它制作另一个简单的 TCP 服务器。
但是我读到这里https://kernel.dk/io_uring.pdf中 io_uring 的条目数限制为 4096 ,这似乎意味着理论上我将无法拥有超过该数量的持久连接。
据我了解,通常我会使用诸如epoll_wait()
等待 epoll 事件之类的东西,而是在 io_uring 中提交特定请求,并在请求完成/失败时收到通知,这是否意味着我最多可以提交 4096 读取( ) 请求例如?
我误解了 io_uring 的用例还是误解了如何使用它?
linux - io_uring 内部如何工作?
显然,Linux 已经有了一个 Asyn-IO (AIO) API。我相信它不是完全异步的。那么 AIO 的问题是什么?以及 io_uring 如何克服它?
PS:我试图阅读https://kernel.dk/io_uring.pdfC
但由于我与该语言脱节而无法完全理解。
c - 如何使用 IORING_OP_READ_FIXED?
在以下页面https://lwn.net/Articles/810414/
IORING_OP_READ_FIXED IORING_OP_WRITE_FIXED 这些操作码也提交 I/O 操作,但它们使用已经映射到内核的“注册”缓冲区,从而减少了总开销。
但是我在网上找不到一个关于如何使用它的例子。在 io_uring_enter 它说
在提交队列条目的操作码字段中指定了 EFAULT IORING_OP_READ_FIXED 或 IORING_OP_WRITE_FIXED,但要么没有为此 io_uring 实例注册缓冲区,要么 addr 和 len 描述的地址范围不适合在 buf_index 处注册的缓冲区。
在我看来,我应该选择一个内存地址并阻止它使用,但是使用像 0x555555500000 和 len as 4096 这样的地址会给我同样的错误。
IORING_OP_READ_FIXED 是如何工作的?下面是 IORING_OP_READ 的一个工作示例
c - IORING_ENTER_SQ_WAKEUP - 对“io_uring_enter”的未定义引用
我正在尝试使用 IORING_SETUP_SQPOLL 运行一些测试,但是当它设置并调用时,io_uring_cqe_get_data(cqe);
我得到“cqe failed: Bad file descriptor”。阅读io_uring.pdf中的内核端轮询,看来我可能不得不打电话:
但是当我尝试编译它时,gcc 找不到 io_uring_enter() (未定义对 `io_uring_enter' 的引用)
- 我正在使用 Ubuntu 18.04.5 LTS - 内核:5.4.0-62-generic。
- 代码可以在这里找到
有没有人对此选项/标志有一些经验?
linux - io_uring_setup 需要多少锁定内存?
使用io_uring_queue_init
时调用io_uring_setup。ENOMEM
当进程可用的锁定内存量不足时,会返回一个。
一个 strace 看起来像:
每个条目(第一个参数)需要多少锁定内存的公式是什么?如果可能的话,基于 params 结构中的 sq_entries/cq_entries?对于内核代码特别热衷。请不要从公式中扩展内核页面大小,因为我确实希望这是一个依赖于架构的答案(如果是的话)。
我不想要一个狡猾的只是将 ulimit -l 设置为无限制作为答案。有这个出色的功能请求功能请求在实施时会有所帮助。
c - io_uring user_data 字段始终为零
我正在玩 io_uring,https: //kernel.dk/io_uring.pdf,看看它是否可以用于异步文件 I/O 以进行日志记录。这是一个简单的程序,它打开一个文件,统计文件,然后从文件中读取前 4k。当文件存在并且可读时,该程序成功运行完成。但完成队列条目中的 user_data 字段始终为零。io_uring 的文档说:
user_data 在操作码中很常见,并且不受内核影响。当为此请求发布完成事件时,它只是简单地复制到完成事件 cqe。
由于完成没有排序,因此需要 user_data 字段来匹配完成与提交。如果该字段始终为零,那么如何使用它?
输出
I/O 初始化成功。
用户数据 0 条目 ptr 0x7f4e3158c140 ret 5
大小 1048576
用户数据 0 条目 ptr 0x7f4e3158c150 ret 0
大小 1048576
读取用户数据 0 完成 4096
c - 为什么 gdb 不能读取 io_uring_cqe 内容?
我正在使用主线内核 5.12 在 Ubuntu 20.04 上尝试loti-examples(Uring 之王)提交 8724d47 和 liburing 提交 7ff4fee。
我将以下补丁用于 loti-examples 以获得更好的调试体验:
构建后,我启动gdb build/webserver_liburing
了,这就是我正在做的事情:
我正在尝试验证request
在提交队列上发送的指针是否与在完成队列上返回的指针相同。
因此,在第 441 行的断点处,您可以从 gdb 输出的最后一行看到,调用io_uring_wait_cqe
成功,因为它的返回值ret
为零。那么为什么我不能cqe->user_data
用 gdb 阅读呢?我希望它包含与在第一个断点上提交到提交队列的地址相同的地址,并绑定到当时的名称data
。
编辑 5 月 12 日:
Mark Plotnick 暗示该地址可以是 I/O 映射的,实际上它是:
c - 编译 io_uring 时遇到问题
我一直在阅读https://kernel.dk/io_uring.pdf并且我想尝试实际的系统调用(io_uring_setup,io_uring_enter)来检查我的理解,但我无法编译以下简单程序:
我收到 io_uring_setup 函数的隐式声明错误。手册页https://manpages.debian.org/unstable/liburing-dev/io_uring_setup.2.en.html建议包含的唯一文件是 linux/io_uring.h,但是当我查看源代码时,我看不到io_uring_setup的定义。