我正在尝试使用Linux libaio来优化服务器应用程序中的IO性能。我相信我已经完成了所有必要的工作(使用O_DIRECT,将缓冲区与内存页面对齐...)。我期待立即调用io_submit返回,但是一个简单的测试显示它实际需要大约80微秒才能在我的核心i7笔记本电脑上返回。我期待太多或我的测试程序有什么问题吗? (用g ++编译--std = c ++ 0x -laio)
#include <unistd.h>
#include <fcntl.h>
#include <libaio.h>
#include <errno.h>
#include <cstdlib>
#include <cstdio>
#include <iostream>
#include <chrono>
// Open the file for write, return the file descriptor
int open_write(char const* file)
{
int fd = open(file, O_DIRECT|O_CREAT|O_WRONLY, S_IRWXU|S_IRWXG|S_IROTH);
if (fd < 0) {
perror("open_write");
exit(1);
}
}
// Make a buffer of _size_ byte, fill with 'a', return the buffer, it should be aligned to memory page
void* make_write_buffer(size_t size)
{
void* buf = 0;
int ret = posix_memalign((void**)&buf, sysconf(_SC_PAGESIZE), size);
if (ret < 0 || buf == 0) {
perror("make_write_buffer");
exit(1);
}
memset(buf, 'a', size);
return buf;
}
int main (int argc, char *argv[])
{
static const size_t SIZE = 16 * 1024;
// Prepare file and buffer to write
int write_fd = open_write("test.dat");
void* buf = make_write_buffer(SIZE);
// Prepare aio
io_context_t ctx;
memset(&ctx, 0, sizeof(ctx));
const int maxEvents = 32;
io_setup(maxEvents, &ctx);
iocb *iocbpp = new iocb;
io_prep_pwrite(iocbpp, write_fd, buf, SIZE, 0);
using namespace std::chrono;
// Submit aio task
auto start = monotonic_clock::now();
int status = io_submit(ctx, 1, &iocbpp);
if (status < 0) {
errno = -status;
perror("io_submit");
exit(1);
}
auto dur = duration_cast<microseconds>(monotonic_clock::now() - start);
std::cout << "io_submit takes: " << dur.count() << " microseconds." << std::endl;
io_event events[10];
int n = io_getevents(ctx, 1, 10, events, NULL);
close(write_fd);
io_destroy(ctx);
delete iocbpp;
free(buf);
return 0;
}
答案 0 :(得分:5)
简而言之:io_submit
阻止,除了修复内核之外,你无能为力。
here是来自kernel-aio的一个帖子。
正如该主题中所指出的,您可以尝试增加/sys/block/xxx/queue/nr_requests
答案 1 :(得分:0)
io_getevents
需要多长时间?如果大部分时间都花费在io_submit而不是io_getevents
中,那么io实际上可能已经在io_submit
期间执行了。 (在我的情况下,我怀疑是ext4s的错...)
您可以尝试的另一件事是使用taskset
将您的流程固定到核心?
顺便说一下,你也可以使用strace -T
来获得这些时间。
编辑:我在怀疑ext4时错了,原来缺少O_DIRECT标志导致了同步行为。
答案 2 :(得分:0)
由于pointed out in the other answer by @Arvid,io_submit()
可能会阻止。 non-exhaustive list of reasons why io_submit()
can block上有一个asynchronous IO io_submit latency in Ubuntu Linux,在这里我猜想是在ext4文件系统上执行文件扩展写操作,从而导致io_submit()
在写入文件系统元数据时同步...