文件系统性能

时间:2012-12-02 23:14:19

标签: c performance file

我正在尝试通过应用程序的访问特性来探索文件系统性能如何受到很大影响。我想将请求大小从1KB(1024)改为64KB(65536)。

当我得到8KB时,我得到写入文件错误。我没有分配足够的空间吗?

./test
error writing file (rc = 200704, errno 0)

我在这里调整1KB - 64KB的大小:

request_size = 32*(1<<13); /* 1KB is 1^10 (or 1<<10) */

所以,这应该是8kb = 8192

我现在应该申请4mb文件吗?我不确定会发生什么样的转变?

int main(int c, char *argv[]) {

    int fd;
    void *buffer, *buffer_aligned;
    int i, rc;
    unsigned long file_size, request_size;
    struct timeval start, stop;
    double seconds;

    /* allocate a 64KB page-aligned buffer */
    buffer = malloc(65536+4096);
    buffer_aligned = buffer+(4096-(((unsigned long)buffer)%4096));

    /* write a 1MB file with 32KB requests  */
    fd = open("foo", O_CREAT|O_RDWR, 0644);
    file_size = 1*(1<<20);  /* 1MB is 2^20 (or 1<<20). 1GB is 2^30 (or 1<<30) */
    request_size = 32*(1<<13); /* 1KB is 1^10 (or 1<<10) */
    gettimeofday(&start, NULL);
    for (i=0; i<file_size/request_size; i++) {
            if ((rc=write(fd, buffer_aligned, request_size))!=request_size) {
                    fprintf(stderr, "error writing file (rc = %i, errno %i)\n", rc, errno);
                    return 1;
            }
    }       
    gettimeofday(&stop, NULL);
    seconds = ((stop.tv_sec*1e6+stop.tv_usec)-(start.tv_sec*1e6+start.tv_usec))/1e6;
    printf("file size is %uMB\n", file_size>>20);
    printf("request size is %uKB\n", request_size>>13);
    printf("elapsed time is %.2lf seconds\n", seconds);
    printf("bandwidth is %.2lf MB/sec\n", file_size/seconds/(1<<20));
    close(fd);

    /* free buffer */
    free(buffer);

    return 0;
}

这不是8KB吗?

request_size = 32*(1<<13); /* 1KB is 1^10 (or 1<<10) */

1 个答案:

答案 0 :(得分:1)

可能发生的事情是,您在write的一次调用中写入的数据量已经变得太多,以至于无法在第一次调用时完全写入。来自write的GNU libc文档:

  

返回值是实际写入的字节数。这可能是尺寸,但总是可以更小。你的程序应该总是在循环中调用write,迭代直到写完所有数据。

(我试图检查其他libc实现的文档,但是它们都没有像GNU那样详细描述这种行为。他们只是说该函数“尝试写入nbytes数据,并返回字节数有些人提到它取决于文件描述符是否处于非阻塞模式。在任何情况下,write通常直接映射到操作系统调用,因此行为也取决于操作系统。)

基本上,你需要在write周围放一个循环,检查它是否写入request_size个字节。类似的东西:

unsigned long data_remaining = request_size;
void *data_offset = buffer_aligned;
while (data_remaining > 0)
{
    rc = write(fd, data_offset, data_remaining);
    if (rc == -1) {
        fprintf(stderr, "error writing file (rc = %i, errno %i)\n", rc, errno);
        return 1;
    }
    data_remaining -= rc;
    data_offset += rc;  /* you don't care about the data being written, so this is kind of unnecessary in your case */
}