嘿,亲!知识可是无价之宝呢,但咱这精心整理的资料也耗费了不少心血呀。小小地破费一下,绝对物超所值哦!如有下载和支付问题,请联系我们QQ(微信同号):78630559
本次赞助数额为: 2 元微信扫码支付:2 元
请留下您的邮箱,我们将在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;
}