跳转至

4.3 I/O Prac

Workshop

在这个研讨会中,你将学习如何测量读取文件所需的时间,包括系统调用的时间和不同大小输入缓冲区的读写时间。首先,你需要一个很大的文件以便进行测试。可以使用以下命令生成一个大约1GB的文件:

for i in {1..1000} ; do cat /bin/bash >> /tmp/huge ; done

你的程序需要接受两个命令行参数:

  • 文件路径(例如 /tmp/huge)

  • 输入缓冲区的大小(例如 1000 字节)

./readtest /tmp/huge 1000

Time measurement

  • 打开文件的时间

  • 读取文件的时间(按不同的缓冲区大小)

Sample solution

#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/time.h>

void measure_time(const char* filename, size_t buffer_size) {
    int fd = open(filename, O_RDONLY);
    if (fd < 0) {
        perror("open");
        exit(EXIT_FAILURE);
    }

    char *buffer = malloc(buffer_size);
    if (buffer == NULL) {
        perror("malloc");
        exit(EXIT_FAILURE);
    }

    ssize_t bytes_read;
    struct timeval start, end;

    // Start time measurement
    gettimeofday(&start, NULL);

    while ((bytes_read = read(fd, buffer, buffer_size)) > 0) {
        // Do nothing with the data, just measure read time
    }

    // End time measurement
    gettimeofday(&end, NULL);

    close(fd);
    free(buffer);

    if (bytes_read < 0) {
        perror("read");
        exit(EXIT_FAILURE);
    }

    long seconds = end.tv_sec - start.tv_sec;
    long microseconds = end.tv_usec - start.tv_usec;
    double elapsed = seconds + microseconds*1e-6;

    printf("Time taken: %.6f seconds\n", elapsed);
}


int main(int argc, char *argv[]) {
    if (argc != 3) {
        fprintf(stderr, "Usage: %s <filename> <buffer_size>\n", argv[0]);
        exit(EXIT_FAILURE);
    }

    const char *filename = argv[1];
    size_t buffer_size = atoi(argv[2]);

    measure_time(filename, buffer_size);

    return 0;
}

实现的核心就是用 gettimeofday 函数计算当天时间点,相关使用细节查看 section 2.4, 最后教授用 google js 的一个工具结合 bash 文件生成了一个数据可视化图表,毫秒 vs buffersize, 也可以用 Excel 或者 python matplotlib 做

open plot.html 会直接在默认浏览器中打开文件

import matplotlib.pyplot as plt

sizes = []
times = []

with open('results.txt', 'r') as file:
    for line in file:
        size, time = line.split()
        sizes.append(int(size))
        times.append(float(time))

plt.plot(sizes, times, 'o-')
plt.xlabel('Buffer Size (bytes)')
plt.ylabel('Time Taken (seconds)')
plt.title('Time Taken vs Buffer Size')
plt.show()

这种程序在日后能够用于分析程序的内存占用的工具的设计思路

Lab

没时间,后续补上,先看 sample 题目