前面两篇文章都在围绕着文件IO来展开的,分别介绍了buffer/cache
、内核态/用户态
怎么优化IO。之前我们讨论的都是同步IO,今天我们就在聊一聊异步IO。
说到异步IO,大家都会想到 同步/异步, 阻塞非阻塞这两个话题。关于这方面的介绍文章有太多了,我这里就不展开介绍了,大家可以自行查阅相关文档。
linux
下有一个 aio_*
系列的函数提供了异步IO能力。我们今天就用异步IO来做一些实验,看看到底是不是 “银弹”。
废话不多说了,线上一部分代码
#define BUFSIZE 1024int fd = 0;int ret = 0;fd = open("../disk-io/direct_io.data", O_RDONLY);if (fd < 0)perror("open");struct aiocb my_aiocb = {0};struct stat file_stat;获取文件大小fstat(fd, &file_stat);printf("st_size %ld\n", file_stat.st_size);填充结构体my_aiocb.aio_buf = malloc(BUFSIZE);my_aiocb.aio_fildes = fd;my_aiocb.aio_nbytes = BUFSIZE;my_aiocb.aio_offset = 0;循环读取for (int i = 0; i < file_stat.st_size; i += ret) {my_aiocb.aio_offset = i;ret = aio_read(&my_aiocb);if (ret < 0) {perror("aio_read");}用户态循环等待IO状态while (aio_error(&my_aiocb) == EINPROGRESS);读取数据if ((ret = aio_return(&my_aiocb)) > 0) {char *p0=(char *)my_aiocb.aio_buf; 返回字符} else {* read failed, consult errno */}}
先使用 read 做同步IO读取文件,查看效果。发现有大量的 iowait 状态。

再次使用aio_read 做异步IO读取文件查看效果。iowait 状态明显变少,但是用户态CPU和内核态CPU占用也有了显著的升高,甚至总体的CPU使用率还高于同步的CPU。

讲到这里我们我们就发现了linux需要有两个问题去改善
优化aio_*系列函数,降低使用门槛与优化性能。不过看起来内核不准备优化aio_*了,准备引入全新的异步IO模式 io_uring
丰富select/poll/epoll 等网络模型,支持监听本地文件。
总结
| IO类型 | 程序执行空间 | 调用方式 | ||
| 内核/用户态切换 | 内核态 | 同步 | 异步 | |
| 缓存IO | read | sendfile | read | aio_read |
| 直接IO | read + O_DIRECT | - | - | - |
如上图所示,性能优先级 sendfile > read > aio_read = read + O_DIRECT 。
所以缓存IO才是 IO性能提升的 “银弹”
文章转载自彪哥分晓,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。




