基本信息
源码名称:高效 IO test 压力测试程序
源码大小:6.66KB
文件格式:.cpp
开发语言:C/C++
更新时间:2026-05-28
   友情提示:(无需注册或充值,赞助后即可获取资源下载链接)

     嘿,亲!知识可是无价之宝呢,但咱这精心整理的资料也耗费了不少心血呀。小小地破费一下,绝对物超所值哦!如有下载和支付问题,请联系我们QQ(微信同号):78630559

本次赞助数额为: 2 元 
   源码介绍


  模拟 dd 命令测试磁盘 IO 性能 (IOPS 和 吞吐量)。
  使用 O_DIRECT 绕过系统缓存,以测试物理磁盘性能。


root@ubuntu:/tmp/iotest# ./io_test
检查目录: /tmp
剩余空间: 9.48 GB
错误: 空间不足!需要至少 10 GB。
root@ubuntu:/tmp/iotest# ./io_test /data
检查目录: /data
剩余空间: 208.31 GB
------------------------------------------------
正在执行: 写入测试 (Write)...
参数模拟: bs=1M count=10000 (Total 10GB)
耗时    : 183.99 秒
IOPS    : 54.35
吞吐量  : 54.35 MB/s
------------------------------------------------
------------------------------------------------
正在执行: 读取测试 (Read)...
参数模拟: bs=1M count=10000 (Total 10GB)
耗时    : 37.93 秒
IOPS    : 263.63
吞吐量  : 263.63 MB/s
------------------------------------------------
正在清理测试文件...
测试完成。
root@ubuntu:/tmp/iotest# 


参数:
  TARGET_DIR   (可选) 测试文件的存放目录。默认为 /tmp。

流程:
  1. 检查剩余空间 (需 > 10GB)。
  2. 写入测试: 模拟 dd if=/dev/zero of=... bs=1M count=10000
  3. 读取测试: 模拟 dd if=... of=/dev/zero bs=1M
  4. 清理测试文件。




// 执行 IO 测试核心逻辑
// is_write: true 为写测试,false 为读测试
void perform_test(const std::string& filepath, bool is_write) {
    int fd;
    void* buffer;
    
    // 1. 分配对齐的内存 (O_DIRECT 要求)
    if (posix_memalign(&buffer, ALIGNMENT, BLOCK_SIZE) != 0) {
        std::cerr << "错误: 内存分配失败" << std::endl;
        exit(1);
    }
    
    // 初始化缓冲区数据 (模拟 /dev/zero)
    memset(buffer, 0, BLOCK_SIZE);

    // 2. 打开文件
    int flags = O_DIRECT;
    if (is_write) {
        flags |= O_WRONLY | O_CREAT | O_TRUNC;
        // 使用 sync 确保数据落盘,更接近物理 IO 语义
        flags |= O_SYNC; 
        fd = open(filepath.c_str(), flags, 0644);
    } else {
        flags |= O_RDONLY;
        fd = open(filepath.c_str(), flags);
    }

    if (fd < 0) {
        std::cerr << "错误: 无法打开文件 " << filepath << " (模式: " << (is_write ? "Write" : "Read") << ")" << std::endl;
        std::cerr << "原因: " << strerror(errno) << std::endl;
        if (errno == EINVAL) {
            std::cerr << "提示: 目标文件系统可能不支持 O_DIRECT (例如 tmpfs),请尝试指定物理磁盘挂载点。" << std::endl;
        }
        free(buffer);
        exit(1);
    }

    std::cout << "------------------------------------------------" << std::endl;
    std::cout << "正在执行: " << (is_write ? "写入测试 (Write)" : "读取测试 (Read)") << "..." << std::endl;
    std::cout << "参数模拟: bs=1M count=" << BLOCK_COUNT << " (Total 10GB)" << std::endl;
    
    // 3. 计时开始
    auto start_time = std::chrono::high_resolution_clock::now();

    // 4. 执行循环 IO
    ssize_t ret;
    for (size_t i = 0; i < BLOCK_COUNT; i) {
        if (is_write) {
            ret = write(fd, buffer, BLOCK_SIZE);
        } else {
            ret = read(fd, buffer, BLOCK_SIZE);
        }

        if (ret != (ssize_t)BLOCK_SIZE) {
            std::cerr << "错误: IO 操作失败,在块 " << i << std::endl;
            std::cerr << "原因: " << strerror(errno) << std::endl;
            close(fd);
            free(buffer);
            exit(1);
        }
    }

    // 5. 计时结束
    // 如果是写操作,再次 sync 确保所有元数据也完成
    if (is_write) fsync(fd);
    
    auto end_time = std::chrono::high_resolution_clock::now();
    close(fd);
    free(buffer);

    // 6. 计算结果
    std::chrono::duration<double> elapsed = end_time - start_time;
    double seconds = elapsed.count();
    
    double total_mb = (double)(BLOCK_COUNT * BLOCK_SIZE) / (1024 * 1024);
    double iops = BLOCK_COUNT / seconds;
    double throughput_mb = total_mb / seconds;

    // 7. 输出结果
    std::cout << "耗时    : " << seconds << " 秒" << std::endl;
    std::cout << "IOPS    : " << std::fixed << std::setprecision(2) << iops << std::endl;
    std::cout << "吞吐量  : " << throughput_mb << " MB/s" << std::endl;
    std::cout << "------------------------------------------------" << std::endl;
}