Andras
Andras

Reputation: 13

HDD benchmark in C++ - measured transfer speed is too fast

I am m trying to develop a mini benchmarking system in C++ and I have trouble measuring the HDD read and write speed. More exactly, the transfer speed measured by me is huge: 400-600 MB/s for read and above 1000 MB/s for write. I have a 5400 RPM hard disk drive (not SSD), the real read/write speed (according to a benchmarking program) is roughly about 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);

I tried using fopen and fwrite functions too and I got similar results.

I ran my app on another computer. The write speed was about right, the read speed was still huge.

The most interesting thing is that the application actually creates a 1GB file in about 2 seconds which corresponds to a 500 MB/s write speed.

Does anybody have any idea what am I doing wrong?

Upvotes: 0

Views: 3927

Answers (3)

Andras
Andras

Reputation: 13

I think I have figured it out.

Unbuffered file writing speed depends on the size of data the WriteFile function is writing. My experiments show that the bigger the data size, the higher the writing speed. For large amounts of data (>1MB) it even outperforms buffered writing, which I was able to measure by writing data larger than 2GB.

To summarize, one can measure the hard drive writing speed accurately by:

  • Opening the file using CreateFile and setting the FILE_FLAG_NO_BUFFERING flag.
  • Writing a lot of data at a time, using WriteFile.

Upvotes: 0

Mateusz Grzejek
Mateusz Grzejek

Reputation: 12068

Technically, you are doing nothing wrong. The problem is, that every OS uses caching for all I/O operations. The HDD itself also caches some data, so it can perform them efficiently.

This question is very platform-specific. You would need to fool caching somehow.

Perhaps, you should look at this library: Bonnie++. You may find it useful. It was written for Unix systems, but source code could reveal some useful techniques.

On Windows, based on this resource, additional flag FILE_FLAG_NO_BUFFERING passed to CreateFile function should be enough to disable buffering for this file.

Quote:

In these situations, caching can be turned off. This is done at the time the file is opened by passing FILE_FLAG_NO_BUFFERING as a value for the dwFlagsAndAttributes parameter of CreateFile. When caching is disabled, all read and write operations directly access the physical disk. However, the file metadata may still be cached. To flush the metadata to disk, use the FlushFileBuffers function.

Upvotes: 4

riodoro1
riodoro1

Reputation: 1256

You are measuring the performance of cache. Try storing a lot more data than that, once the cache fills the data should be written straight to the disk.

Upvotes: 0

Related Questions