C中的文件系统VS原始磁盘基准测试

时间:2015-03-01 21:40:06

标签: c filesystems disk raw-disk

我正在做一些基准测试(在OS X上),看看文件系统的使用如何影响带宽等。我正在使用并发,希望在FS中创建碎片。

但是,看起来使用FS比原始磁盘访问更有效。为什么呢?

这是我的代码:

#include <pthread.h>
#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>

#define NO_THREADS (2)
#define PACKET_SIZE (1024 * 4)
#define SIZE_TO_WRITE (1024 * 1024 * 1024)

void write_buffer(void *arg) {
    int *p_start = arg;
    int start = *p_start;
    char buffer[PACKET_SIZE];


    char path[50];
    sprintf(path, "file%d", start);
    int fd = open(path, O_CREAT | O_WRONLY | O_APPEND);

    //int fd = open("/dev/rdisk0s4", O_WRONLY);

    if (fd < 0) {
        fprintf(stderr, "Cound not open.\n", stderr);
        goto end;
    }

    //lseek(fd, start * SIZE_TO_WRITE, SEEK_SET);

    int current;
    for (current = start; current < start + SIZE_TO_WRITE; current += PACKET_SIZE) {

        int i;
        for (i = 0; i < PACKET_SIZE; ++i) {
            buffer[i] = i + current;
        }

        if (PACKET_SIZE != write(fd, buffer, PACKET_SIZE)) {
            fprintf(stderr, "Could not write packet %d properly.", current);
            goto close;
        }
    }

    fsync(fd);

  close:
    close(fd);
  end:
    pthread_exit(0);
}

void flush(void) {
    fflush(stdout);
    fflush(stderr);
}

int main(void) {
    pthread_t threads[NO_THREADS];
    int starts[NO_THREADS];
    int i;

    atexit(flush);

    for (i = 0; i < NO_THREADS; ++i) {

        starts[i] = i;

        if(pthread_create(threads + i, NULL, (void *) &write_buffer, (void *)(starts + i))) {
            fprintf(stderr, "Error creating thread no %d\n", i);
            return EXIT_FAILURE;
        }
    }

    for (i = 0; i < NO_THREADS; ++i) {
        if(pthread_join(threads[i], NULL)) {
            fprintf(stderr, "Error joining thread\n");
            return EXIT_FAILURE;
        }
    }

    puts("Done");

    return EXIT_SUCCESS;
}

在FS的帮助下,2个线程在31.33秒内写入文件。没有,它会在几分钟后实现......

1 个答案:

答案 0 :(得分:0)

当您使用/dev/rdisk0s4而不是/path/to/normal/file%d时,对于您执行的每次写操作,操作系统都会发出磁盘I / O.即使该磁盘是SSD,这意味着往返时间平均可能至少为几百微秒。当您写入文件时,文件系统实际上不会向磁盘发送写入,直到稍后。 Linux man page很好地描述了这一点:

  

从write()成功返回并不能保证数据已提交到磁盘。事实上,在一些错误的实现上,它甚至不能保证已成功为数据保留空间。唯一可以确定的方法是在写完所有数据后调用fsync(2)。

因此,您编写的数据正在被文件系统缓冲,这只需要在内存中进行复制 - 这可能最多需要几微秒。如果您想进行同类比较,则应确保为两个测试用例进行同步I / O.在完成整个测试之后,即使运行fsync也可能会使文件系统更快,因为它会将I / O批量转换为一个连续的流式写入,这可能比直接在磁盘上的测试更快可以实现。

一般而言,编写好的系统基准测试非常困难,尤其是当您不了解有关您尝试测试的系统的批次时。如果你想要高质量的结果,我建议使用现成的Unix文件系统基准测试工具包 - 否则,你可以花一辈子的时间学习你正在测试的操作系统和FS的性能病态。如果你像我一样对它感兴趣,那不是那么糟糕的事情: - )