首页 > 解决方案 > 直接 I/O 性能

问题描述

我正在尝试测量 DIRECT IO 性能。据我了解,DIRECT I/O 会忽略页面缓存并转到底层设备来获取数据。因此,如果我们一遍又一遍地读取同一个文件,与涉及页面缓存的访问相比,DIRECT I/O 会更慢,因为文件将被缓存。

#define _GNU_SOURCE

#include <stdio.h>
#include <errno.h>
#include <fcntl.h>
#include <time.h>

char *DIRECT_FILE_PATH = "direct.dat";
char *NON_DIRECT_FILE_PATH = "no_direct.dat";
int FILE_SIZE_MB = 100;
int NUM_ITER = 100;

void lay_file(int direct_flag) {
    int flag = O_RDWR | O_CREAT | O_APPEND | O_DIRECT;
    mode_t mode = 0644;

    int fd;
    if (direct_flag) {
        fd = open(DIRECT_FILE_PATH, flag, mode);
    } else {
        fd = open(NON_DIRECT_FILE_PATH, flag, mode);
    }

    if (fd == -1) {
        printf("Failed to open file. Error: \t%s\n", strerror(errno));
    } 

    ftruncate(fd, FILE_SIZE_MB*1024*1024);
    close(fd);
}

void read_file(int direct_flag) {

    mode_t mode = 0644;
    void *buf = malloc(FILE_SIZE_MB*1024*1024);

    int fd, flag;
    if (direct_flag) {
        flag = O_RDONLY | O_DIRECT;
        fd = open(DIRECT_FILE_PATH, flag, mode);
    } else {
        flag = O_RDONLY;
        fd = open(NON_DIRECT_FILE_PATH, flag, mode);
    }

    for (int i=0; i<NUM_ITER; i++) {
        read(fd, buf, FILE_SIZE_MB*1024*1024);
        lseek(fd,0,SEEK_SET);
    }
    close(fd);
}

int main() {

    lay_file(0);
    lay_file(1);

    clock_t t;
    t = clock();
    read_file(1);
    t = clock() - t;
    double time_taken = ((double)t)/CLOCKS_PER_SEC; // in seconds
    printf("DIRECT I/O read took %f seconds to execute \n", time_taken);

    t = clock();
    read_file(0);
    t = clock() - t;
    time_taken = ((double)t)/CLOCKS_PER_SEC; // in seconds
    printf("NON DIRECT I/O read took %f seconds to execute \n", time_taken);

    return 0;
}

使用上面的代码测量 DIRECT I/O 性能告诉我,DIRECT I/O 比涉及页面缓存的常规 IO 更快。这是输出

** DIRECT I/O 读取执行耗时 0.824861 秒 NON DIRECT I/O 读取执行耗时 1.643310 秒 **

如果我遗漏了什么,请告诉我。我有一个 NVMe SSD 作为存储设备。我想知道是否太快无法真正显示使用和不使用页面缓存时的性能差异。

更新:

将缓冲区大小更改为 4KB 表明 DIRECT I/O 速度较慢。大缓冲区大小可能正在对底层设备进行大量顺序写入,这更有帮助,但仍需要一些见解。

** DIRECT I/O 读取执行耗时 0.000209 秒 NON DIRECT I/O 读取执行耗时 0.000151 秒 **

标签: clinuxoperating-system

解决方案


推荐阅读