C ++中的硬盘基准测试 - 测量传输速度太快

时间:2015-04-04 13:17:42

标签: c++ performance

我正在尝试用C ++开发一个迷你基准测试系统,我无法测量硬盘的读写速度。更确切地说,我测量的传输速度很大:读取时为400-600 MB / s,写入时为1000 MB / s以上。我有一个5400转的硬盘驱动器(不是SSD),真正的读/写速度(根据基准测试程序)大约是60 MB / s。

//blockSize is 4096
//my data buffer
char* mydata = (char*)malloc(1*blockSize);

//initialized with random data
srand(time(NULL));
for(int i=0;i<blockSize;i++){
    mydata[i] = rand()%256;
}

double startt, endt, difft;
int times = 10*25000;
int i=0,j=0;
DWORD written;
HANDLE f, g;
DWORD read;

f=CreateFileA(
    "newfolder/myfile.txt",
    GENERIC_WRITE,
    0,
    NULL,
    CREATE_ALWAYS,
    FILE_ATTRIBUTE_NORMAL,
    NULL
    );

if(f==INVALID_HANDLE_VALUE){
    std::cout<<"Error openning for write.";
    return -1;
}

startt = clock();
for(i=0;i<times;i++){
    WriteFile(
    f,
    mydata,
    blockSize,
    &written,
    NULL
    );
}
endt = clock();

difft = 1.0*(endt-startt)/(1.0*CLOCKS_PER_SEC);
std::cout<<"\nWrite time: "<<difft;
std::cout<<"\nWrite speed: "<<1.0*times*blockSize/difft/1024/1024<<" MB/s";

CloseHandle(f);
//------------------------------------------------------------------------------------------------

g=CreateFile("newfolder/myfile.txt",
                GENERIC_READ,
                0,
                NULL,
                OPEN_ALWAYS,
                FILE_ATTRIBUTE_NORMAL,
                NULL
                );
if(g==INVALID_HANDLE_VALUE){
    std::cout<<"Error opening for read.";
    return -1;
}

startt = clock();

for(i=0;i<times;i++){
    ReadFile(
    g,
    mydata,
    blockSize,
    &read,
    NULL
    );
}
endt = clock();
difft = 1.0*(endt-startt)/(1.0*CLOCKS_PER_SEC);
std::cout<<"\nRead time:"<<difft;
std::cout<<"\nRead speed: "<<1.0*times*blockSize/difft/1024/1024<<" MB/s";

CloseHandle(g);

我也尝试使用 fopen fwrite 函数,我得到了类似的结果。

我在另一台计算机上运行我的应用程序。写入速度差不多,读取速度仍然很大。

最有趣的是,应用程序实际上在大约2秒内创建了1GB文件,相当于500 MB / s的写入速度。

有人知道我做错了什么吗?

3 个答案:

答案 0 :(得分:4)

技术上,你没有做错任何事。问题是,每个操作系统都使用缓存来进行所有I / O操作。 HDD本身也会缓存一些数据,因此它可以有效地执行它们。

这个问题非常具体。你需要以某种方式愚弄缓存。

也许,你应该看看这个库:Bonnie++。你可能会发现它很有用。它是为Unix系统编写的,但源代码可以揭示一些有用的技术。

在Windows上,基于this resource,传递给FILE_FLAG_NO_BUFFERING函数的其他标记CreateFile应该足以禁用此文件的缓冲。

引用:

  

在这些情况下,可以关闭缓存。这是在文件打开时通过传递FILE_FLAG_NO_BUFFERING作为CreateFile的dwFlagsAndAttributes参数的值来完成的。禁用高速缓存时,所有读写操作都直接访问物理磁盘。但是,仍可以缓存文件元数据。要将元数据刷新到磁盘,请使用FlushFileBuffers函数。

答案 1 :(得分:0)

您正在测量缓存的性能。 尝试存储比这更多的数据,一旦缓存填满数据应该直接写入磁盘。

答案 2 :(得分:0)

我想我已经明白了。

无缓冲的文件写入速度取决于WriteFile函数正在写入的数据大小。我的实验表明,数据量越大,写入速度越高。对于大量数据(> 1MB),它甚至优于缓冲写入,我可以通过写入大于2GB的数据来测量。

总而言之,可以通过以下方式准确测量硬盘写入速度:

  • 使用CreateFile打开文件并设置FILE_FLAG_NO_BUFFERING标记。
  • 使用WriteFile一次编写大量数据。