gpt4 book ai didi

c - aio_write 比 ext4 上的普通写入需要更多时间?

转载 作者:行者123 更新时间:2023-12-02 03:29:14 24 4
gpt4 key购买 nike

我有一个 C 程序,它写入 32768 个 block ,每个 block 大小为 16K(总大小为 512MB),到运行 3.18.1 内核的系统上的 ext4 文件系统。该程序的常规写入系统调用版本需要 5.35 秒才能完成写入(由 for 循环前后的 gettimeofday 测量)。然而,该程序的异步 io 版本需要以下时间:

  1. 对所有 aio_writes 进行排队(32768 aio_writes):7.43 秒
  2. 轮询以完成每个 IO 请求:额外 4.93 秒

输出文件使用这些标志打开:O_WRONLY、O_CREAT、O_NONBLOCK

为什么 async io 花费的 write() 时间是原来的两倍多?甚至 Time-to-queue-async-io-request/time-to-write-sync-io 也是 1.4。

由于有人将其标记为题外话,我查看了定义并决定粘贴代码 - 这似乎是将其标记为题外话的唯一原因。我不是在问为什么代码不工作,只是为什么 aio 比常规写入慢得多,特别是因为所有并行写入都是针对不同的 block 。这是 aio 代码,后面是非 aio 代码:

AIO程序

#define MAX_AIO        (16384*2)
#define BUFSIZE 16384

struct mys {
int status;
struct aiocb aio;
};

void set_aiocb(struct mys *aio, int num, int fd)
{
int i;

for (i = 0; i < num; i++) {
aio[i].aio.aio_fildes = fd;
aio[i].aio.aio_offset = BUFSIZE * i;
aio[i].aio.aio_buf = malloc(BUFSIZE);
set_buf(aio[i].aio.aio_buf, BUFSIZE, i);
aio[i].aio.aio_nbytes = BUFSIZE;
aio[i].aio.aio_reqprio = fd;
aio[i].aio.aio_sigevent.sigev_notify = SIGEV_NONE;
aio[i].aio.aio_sigevent.sigev_signo = SIGUSR1;
aio[i].aio.aio_sigevent.sigev_value.sival_ptr = &aio[i];
aio[i].aio.aio_lio_opcode = 0;
aio[i].status = EINPROGRESS;
}
}

void main(void)
{
int fd = open("/tmp/AIO", O_WRONLY | O_CREAT, 0666);
int i, open_reqs = MAX_AIO;
struct mys aio[MAX_AIO];
struct timeval start, end, diff;

set_aiocb(aio, MAX_AIO, fd);

gettimeofday(&start, NULL);
for (i = 0; i < MAX_AIO; i++)
aio_write(&aio[i].aio);

while (open_reqs > 0) {
for (i = 0; i < MAX_AIO; i++) {
if (aio[i].status == EINPROGRESS) {
aio[i].status = aio_error(&(aio[i].aio));
if (aio[i].status != EINPROGRESS)
open_reqs--;
}
}
}
gettimeofday(&end, NULL);
timersub(&end, &start, &diff);
printf("%d.%d\n", (int)diff.tv_sec, (int)diff.tv_usec);
}

常规IO程序

#define MAX_AIO        (16384*2)
#define BUFSIZE 16384

char buf[MAX_AIO][BUFSIZE];
void main(void)
{
int i, fd = open("/tmp/NON_AIO", O_WRONLY | O_CREAT, 0666);
struct timeval start, end, diff;

gettimeofday(&start, NULL);
for (i = 0; i < MAX_AIO; i++)
write(fd, buf[i], BUFSIZE);
gettimeofday(&end, NULL);
timersub(&end, &start, &diff);
printf("%d.%d\n", (int)diff.tv_sec, (int)diff.tv_usec);
}

最佳答案

您并没有真正将苹果与苹果进行比较。

在 AIO 代码中,您为每个写操作单独分配了一个缓冲区,因此该程序分配了 512 MiB (16 * 16 * 2 KiB) 内存,外加 AIO 控制结构的 32 K 副本。必须分配、初始化该内存(如果 set_buf() 函数(未显示)将缓冲区的每个字节设置为第三个参数的值,则每个缓冲区都会获得不同的值),然后由内核复制到驱动程序,可能通过内核缓冲池。

在常规 IO 代码中,你有一个大的、连续的缓冲区,它被初始化为你写入磁盘的全零。

为了使比较公平,您应该在两个程序中使用相同的基础结构,创建 AIO 结构,但是常规 IO 代码随后将简单地遍历结构,写入每个结构的数据部分(而 AIO 代码将表现或多或少如图所示)。我希望您这样做时会发现性能更加接近。

关于c - aio_write 比 ext4 上的普通写入需要更多时间?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28170110/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com