2015-04-04 32 views
0

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

//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); 

我尝试使用的fopenFWRITE功能太多,我得到了类似的结果。

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

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

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

+0

您的操作系统正在实施磁盘缓存; I/O实际上并不是来自磁盘本身。 – 2015-04-04 13:19:33

回答

3

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

这个问题是非常特定于平台的。你需要以某种方式愚弄缓存。

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

在Windows上,根据this resource,传递给CreateFile函数的附加标志FILE_FLAG_NO_BUFFERING应该足以禁用此文件的缓冲。

引用:

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

+0

谢谢。我试过了FILE_FLAG_NO_BUFFERING标志。现在我的写入速度约为3 MB /秒。 – Andrew 2015-04-04 14:14:52

0

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

0

我想我已经想通了。

无缓冲的文件写入速度取决于函数写入的数据大小。我的实验显示数据量越大,写入速度越快。对于大量数据(> 1MB),它甚至优于缓冲写入,我可以通过写入大于2GB的数据进行测量。

总之,可以通过精确测量在硬盘驱动器的写入速度:

  • 使用CreateFile打开文件和设置FILE_FLAG_NO_BUFFERING标志。
  • 一次写入大量数据,使用WriteFile