1

I am trying to benchmark my hard disk and find the throughput in Mb/s and latency in milliseconds. This is my code.

public class OneMB implements Timer {
public static void main(String a[]) throws IOException {
    OneMB oneMB = new OneMB();
    oneMB.process();

}
public void process() throws IOException{
    RandomAccessFile randomAccessFile=null;
    try{            
        File file=new File("oneMByte.txt");
        byte[] b=new byte[1024];
        randomAccessFile=new RandomAccessFile(file, "rw");
        randomAccessFile.setLength(1024*1024*10);
        long endLatency=0;
        int i=0;
        long startWrite = this.getTimer();
        randomAccessFile.writeBoolean(true);
        endLatency=this.getTimer();                 
        for (i = 0; i < 1024*10*1024-1; i++) {
            randomAccessFile.writeBoolean(true); //Writes a boolean to the file as a one-byte value.
        }
        long endWrite = this.getTimer();
        randomAccessFile.seek(0);
        randomAccessFile.readFully(b);
        long endRead=this.getTimer();
        double timeTaken=(endRead-startWrite)/1000000000.0;
        double data=10.0;
        double throughput=data/timeTaken;
        double latency=(endLatency-startWrite)/1000000.0;//time for the reception of 1 byte
        System.out.println(timeTaken);
        System.out.println(data);
        System.out.println("Throughput="+throughput+" Mb/s");
        System.out.println("Latency="+latency+" ms");
        randomAccessFile.close();
    }
    catch (Exception e) {
        e.printStackTrace();
        randomAccessFile.close();
    }
}

@Override
public long getTimer() {
    // TODO Auto-generated method stub
    return System.nanoTime();
}
}

I get the output as

56.065550577
10.0
Throughput=0.17836264688538242 Mb/s
Latency=0.057668 ms

I have a reasonably fast computer with 1TB harddisk @ 5400 Rpm, Intel i7 with quad core @2.1Ghz, 8GB ddr 3 Ram. Could someone tell me if the throughput would be that low or am I using a wrong approach?

Gilles 'SO- stop being evil'
  • 104,111
  • 38
  • 209
  • 254
Prasanna
  • 2,593
  • 7
  • 39
  • 53
  • The way you are testing is wrong. There are examples of how to do this sort of stuff properly all over the internet. Or try http://stackoverflow.com/questions/504103/how-do-i-write-a-correct-micro-benchmark-in-java – Apprentice Queue Jan 27 '13 at 17:23

3 Answers3

2

The number appears to be about right to me. You are making a very large number of system calls. 178K system calls/s is about right for a 2.1 GB i7. On a 3.5 GHz I7 you can get about 300K system calls per second.

The very first time you run a method it has to be loaded and this slows it down. Even though it is not compiled to native code in this phase, some work has to be done and a latency of 57 micro-seconds seems reasonable for a first call.

Peter Lawrey
  • 525,659
  • 79
  • 751
  • 1,130
  • For the same processor as I mentioned above, I get processor speed in the range of 13 Giga Flops. Is this reasonable? Do we have any tool that measures processor speed in GFLOPS so that I could compare my results? – Prasanna Jan 28 '13 at 12:31
  • 1
    13 giga flops is reason for the right test. Don't forget that such benchmarks are a manufacturers guarantee never to exceed this value. The value you get in a real program might be 1% or less. – Peter Lawrey Jan 28 '13 at 21:38
  • I noticed something with this code. When I increase the data chunk size, say from 1Mb to 1GB, through put appears to increase by nearly 1000 MBps. I am making a mistake right? It has to be the same irrespective of the chunk size right? – Prasanna Jan 31 '13 at 04:57
  • The length of the test can matter. It can take a while for the JVM and OS to optimise for your application. This can take seconds and your 10 MB it is very short (tens of milli-seconds) so you might see an improvement if you run the test for a couple of seconds. I would be surpise but interested if you can now do one millon system calls per second. – Peter Lawrey Jan 31 '13 at 07:48
1

I'm sure there are lots of disk benchmarks out there... Google gives a lot of links. Look at sites geared to benchmarking, they probably publish their tools to make results repeatable. Use them, so you can compare to results obtained elsewhere. Unless you are interested in benchmarking some very specific special case, that is. And in that case you'd better measure the perfomance for your case including the whole stack: Program, compiler, operating system and hardware.

vonbrand
  • 11,412
  • 8
  • 32
  • 52
0

Seems reasonable to me as long as you're using the same code on all the HDs or platforms you're testing. I do think that for larger sequential write test you might want to try writing several bytes as a time instead of a flag, makes it clearer to interpret how much data is being written.

Here's a utility I wrote in java to benchmark disk IO: https://sourceforge.net/projects/jdiskmark/ It would be nice if I could add latency check like your code does but it does an okay job with bandwidth. You can check out the code on gitlab.

simgineer
  • 1,754
  • 2
  • 22
  • 49