首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> 關於C語言

操作系統實驗:C++ 實現大文件初始化(32MB 零填充)的兩種方案對比

     編輯:關於C語言

實驗目標

創建一個 32MB (65536 塊 × 512 字節/塊) 的二進制文件 cq.dat,全部填充 0x00,模擬磁盤鏡像初始化。對比逐字節寫入與內存塊寫入兩種方案的實現差異與性能。

方案一:逐字節 fprintf(教學演示,極慢)


// 註釋掉的代碼
for (i = 0; i < BLOCK_NUM; i++) {
    for (j = 0; j < BLOCK_SIZE; j++) {
        fprintf(fp, "%c", '\0'); // 每字節一個系統調用 + 格式化解析開銷
    }
}

缺點:fprintf 解析格式字符串、調用 write 系統調用,每字節一次,32MB 需 3355 萬次調用,極其低效,僅供邏輯驗證。

方案二:內存塊分配 + memset + fwrite(工程標準,極快)

核心代碼


#include 
#include  // Windows 內存泄漏檢測
#include 
#include 

using namespace std;

FILE *fp;
const char SP_NAME[] = "cq.dat";
const int BLOCK_NUM = 65536;  // 64K 塊
const int BLOCK_SIZE = 512;   // 512 字節/塊
const int BITE_NUM = 33554432; // 總字節 = 64K * 512 = 32MB

void init() {
    fp = fopen(SP_NAME, "wb"); // 二進制寫入模式
    if (!fp) return;

    // 1. 一次性分配 32MB 內存
    char *memory = (char *)malloc(BITE_NUM);
    if (!memory) { fclose(fp); return; }

    // 2. 內存中高效置零 (memset 優化為向量化指令)
    memset(memory, 0, BITE_NUM);

    // 3. 一次性寫入文件 (單次 fwrite 系統調用)
    fwrite(memory, 1, BITE_NUM, fp);

    fclose(fp);
    free(memory); // 釋放內存
}

int main() {
    init();
    return 0;
}

關鍵技術點解析

技術點 說明
fopen(..., "wb") 二進制寫入模式,Windows 下關鍵:禁用 \n→\r\n 轉換,確保字節流純粹。
malloc(BITE_NUM) 堆上分配 32MB 連續內存。32 位程序需注意地址空間;64 位無壓力。
memset(memory, 0, size) 編譯器內建函數,通常優化為 rep stosb 或 AVX/SSE 向量化存儲,GB/s 級速度。
fwrite(ptr, 1, size, fp) 以字節為單位寫入,實際調用 WriteFile (Win) / write (Linux) 一次性傳輸 32MB,極少上下文切換。
free(memory) 及時釋放,防內存洩漏。配合 crtdbg.h 可在調試時自動檢測泄漏。

性能對比 (估算)

方案 系統調用次數 用戶態 CPU 預估耗時
逐字節 fprintf 33,554,432 極高 (格式化解析) 數秒 ~ 數十秒
塊內存 fwrite 1 (fwrite) + 少量 malloc/free 極低 (memset 向量化) < 10 ms

工程最佳實踐總結

  1. 大數據塊操作必須用二進制模式 + 塊 I/O,禁用格式化 I/O (fprintf/fscanf)。
  2. 用戶態緩衝區 + memset/memcpy + 單次 fwrite/read 是高性能文件處理的標準模式。
  3. 內存對齊:分配緩衝區時建議對齊 4KB/64KB (頁大小/磁盤扇區),配合 posix_memalign 或 _aligned_malloc,可啟用 DMA/直接 I/O 進一步提速。
  4. 錯誤處理:生產代碼必須檢查 fopen/malloc/fwrite 返回值,記錄 errno/GetLastError。
  5. 跨平台:Windows 用 _O_BINARY 確保二進制模式;Linux 默認即二進制,無差異。

結語

本實驗以 32MB 零填充文件為例,直觀對比了「逐字節高級 I/O」與「塊內存低級 I/O」的天壤之別。操作系統實驗乃至所有系統級編程的核心原則:**減少用戶態/內核態切換、利用硬件向量化指令、以空間換時間 (大緩衝區)**。掌握 malloc + memset + fwrite 這一「鐵三角」模式,是高性能文件/網絡/設備 I/O 開發的入門必修課。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved