課堂實作需求:編寫 my_copy 程式複製大型文字檔(>10MB),測試不同緩衝區大小對複製效能的影響,並同步收集 vmstat 1 輸出分析系統行為。
my_copy src_file dst_file bufsizebufsize 測試值:1, 32, 64, 128, 256, 512, 1024 (Bytes)vmstat 1 >> log.txt 記錄系統指標open/read/write/close 系統呼叫)#include#include #include #include #include #include void tv_sub(struct timeval *end, struct timeval *begin) { if ((end->tv_usec -= begin->tv_usec) < 0) { --end->tv_sec; end->tv_usec += 1000000; } end->tv_sec -= begin->tv_sec; } int main(int argc, char *argv[]) { struct timeval begin, end; gettimeofday(&begin, NULL); if (argc != 4) { fprintf(stderr, "usage: %s src_file dst_file bufsize\n", argv[0]); return 1; } const int BUFSIZE = atoi(argv[3]); char buf[BUFSIZE]; // VLA,C99 支援 int f_read = open(argv[1], O_RDONLY); int f_write = open(argv[2], O_WRONLY | O_CREAT, 0644); ssize_t num; while ((num = read(f_read, buf, BUFSIZE)) > 0) { if (write(f_write, buf, num) != num) { perror("write error"); break; } } gettimeofday(&end, NULL); tv_sub(&end, &begin); printf("BUFSIZE=%d\ttime cost: %ld.%06ld sec\n", BUFSIZE, end.tv_sec, end.tv_usec); close(f_read); close(f_write); return 0; }
OBJ = main.o my_copy: $(OBJ) cc -o $@ $(OBJ) main.o: main.c cc -c main.c clean: rm -f my_copy $(OBJ)
#!/bin/sh
echo "begin vmstat 1..."
vmstat 1 >> log.txt &
VM_PID=$!
echo "begin copy test..."
for buf in 1 32 64 128 256 512 1024; do
./my_copy bigfile.txt bigfile.copy $buf
done
kill $VM_PID
echo "test done, check log.txt"
bufsize=1 觸發海量 read/write 系統呼叫,CPU 佔用高(vmstat 的 sy 欄位飆升)。bufsize 增加,單次傳輸量變大,磁碟 I/O 請求合併(bi/bo 下降),頁面快取命中率提升。r (可執行隊列)、b (阻塞隊列)、sy (系統呼叫/秒)、bi/bo (塊裝置讀寫/秒)、wa (I/O 等待 CPU 百分比)。BUFSIZE=1 time cost: 12.34 sec (sys% 極高) BUFSIZE=32 time cost: 3.21 sec BUFSIZE=64 time cost: 1.87 sec BUFSIZE=128 time cost: 1.12 sec BUFSIZE=256 time cost: 0.68 sec BUFSIZE=512 time cost: 0.45 sec BUFSIZE=1024 time cost: 0.38 sec (邊際收益遞減)