【提问】问一个关于用AIO库改善文件i/o性能的问题
时间:2011-01-05
来源:互联网
本帖最后由 almeydifer 于 2011-01-05 20:58 编辑
各位,本人现在遇到了一个实际的问题(属于应用层):
1.一个第三方的应用程序首先用O_DIRECT标志位打开了一个比较大的镜像文件,大约是8GB。
2.此时我因为我某种需要,将该应用程序的写请求全部截获,并且存放在自己设计的一个缓存中,每一个写操作的相关的脏数据存放在一个结构体里,不同的写操作的结构体之间用链表来相连接。
3.在某个时刻,我需要重新调用write操作,将截获的写请求重新刷入磁盘中盖镜像文件对应的位置。
现在问题来了,如果直接调用write的话,非常慢,因为此文件使用O_DIRECT标志位打开,
所以呢,我想利用AIO,也就是Linux提供的异步I/O库来提升其刷入磁盘的性能,也就是写性能。我现在的问题代码片段如下:
复制代码
中间那个list_for_each是将我前面提到的脏数据列表进行一个遍历,以刷新我所有缓存过的脏数据。
p是链表当中的结构体,pageaddr是我截获的写请求对应的offset,size是我截获的写请求对应的size
p当中还有个mybuf成员变量,用来缓存我截获的脏数据本身。
现在的问题是我感觉这个用法不大对劲,因为很可能我的用法不正确,
第一个问题是:性能几乎没有什么提高;
第二个问题是:狂占用内存,
各位如果有相关经验的话,恳请有劳指导一番。
各位,本人现在遇到了一个实际的问题(属于应用层):
1.一个第三方的应用程序首先用O_DIRECT标志位打开了一个比较大的镜像文件,大约是8GB。
2.此时我因为我某种需要,将该应用程序的写请求全部截获,并且存放在自己设计的一个缓存中,每一个写操作的相关的脏数据存放在一个结构体里,不同的写操作的结构体之间用链表来相连接。
3.在某个时刻,我需要重新调用write操作,将截获的写请求重新刷入磁盘中盖镜像文件对应的位置。
现在问题来了,如果直接调用write的话,非常慢,因为此文件使用O_DIRECT标志位打开,
所以呢,我想利用AIO,也就是Linux提供的异步I/O库来提升其刷入磁盘的性能,也就是写性能。我现在的问题代码片段如下:
- struct aiocb my_aiocb;
-
- bzero( (char *)&my_aiocb, sizeof(struct aiocb) );
-
- my_aiocb.aio_fildes = prv->fd;
-
- list_for_each(_s, this_list){
- p = list_entry(_s, page_node_t, list);
- my_aiocb.aio_buf = malloc(p->size + 1);
- my_aiocb.aio_nbytes = p->size;
- my_aiocb.aio_offset = p->pageAddr;
-
- aio_write(&my_aiocb);
- }
-
- while ( aio_error( &my_aiocb ) == EINPROGRESS );
-
- return 1;
p是链表当中的结构体,pageaddr是我截获的写请求对应的offset,size是我截获的写请求对应的size
p当中还有个mybuf成员变量,用来缓存我截获的脏数据本身。
现在的问题是我感觉这个用法不大对劲,因为很可能我的用法不正确,
第一个问题是:性能几乎没有什么提高;
第二个问题是:狂占用内存,
各位如果有相关经验的话,恳请有劳指导一番。
作者: almeydifer 发布时间: 2011-01-05
第二个问题:aio_buf的内存为什么要malloc呢?用完free了吗?
第一个问题:为什么aio_write要比write性能高?
我的理解是:
现在要做的事情是把数据写入磁盘,性能的瓶颈在于写磁盘。不管使用哪种系统调用,需要写的数据都是一样多的。那么aio_write的性能又能比write高多少呢?
不过,write是阻塞的,只能提交一块、等待写入磁盘、再提交下一块。而aio_write是不需要阻塞的,可以连续的把所有请求都提交了,再一起等待。这有什么好处呢?多次aio_write提交的请求就有可能得到合并,而如果请求得到合并,写盘效率势必会提高(请求合并减少了磁盘寻道的次数,而磁盘寻道又是写盘的瓶颈所在)。
那么,什么情况下两个请求能被合并呢?两个条件,一是两个请求的内存连续、二是两个请求的磁盘位置连续。这两个条件在LZ的测试代码中能满足吗?第一,内存连续的可能性不大,因为aio_buf是malloc出来的,malloc的内存是对齐的,且内存与内存之间还可能夹杂很多控制信息;而第二点,磁盘位置是否连续更是不可知的。所以,请求能够被合并的可能性实在很小。
第一个问题:为什么aio_write要比write性能高?
我的理解是:
现在要做的事情是把数据写入磁盘,性能的瓶颈在于写磁盘。不管使用哪种系统调用,需要写的数据都是一样多的。那么aio_write的性能又能比write高多少呢?
不过,write是阻塞的,只能提交一块、等待写入磁盘、再提交下一块。而aio_write是不需要阻塞的,可以连续的把所有请求都提交了,再一起等待。这有什么好处呢?多次aio_write提交的请求就有可能得到合并,而如果请求得到合并,写盘效率势必会提高(请求合并减少了磁盘寻道的次数,而磁盘寻道又是写盘的瓶颈所在)。
那么,什么情况下两个请求能被合并呢?两个条件,一是两个请求的内存连续、二是两个请求的磁盘位置连续。这两个条件在LZ的测试代码中能满足吗?第一,内存连续的可能性不大,因为aio_buf是malloc出来的,malloc的内存是对齐的,且内存与内存之间还可能夹杂很多控制信息;而第二点,磁盘位置是否连续更是不可知的。所以,请求能够被合并的可能性实在很小。
作者: kouu 发布时间: 2011-01-05
相关阅读 更多
热门阅读
-
office 2019专业增强版最新2021版激活秘钥/序列号/激活码推荐 附激活工具
阅读:74
-
如何安装mysql8.0
阅读:31
-
Word快速设置标题样式步骤详解
阅读:28
-
20+道必知必会的Vue面试题(附答案解析)
阅读:37
-
HTML如何制作表单
阅读:22
-
百词斩可以改天数吗?当然可以,4个步骤轻松修改天数!
阅读:31
-
ET文件格式和XLS格式文件之间如何转化?
阅读:24
-
react和vue的区别及优缺点是什么
阅读:121
-
支付宝人脸识别如何关闭?
阅读:21
-
腾讯微云怎么修改照片或视频备份路径?
阅读:28