0

I wrote a program that are reading/writing data (open one infile and one outfile, read part of infile, then process, then write to outfile, and that cycle repeats), with I/O value about 200M/s in total. However, most of the running time, they are in status D, which means waiting for I/O (As shown in the figure)1. I used dd check write speed in my system, that is about 1.8G/s.

enter image description here

Are my programs inefficient? Or my harddisk have problems? How can I deal with it?

E. Yin
  • 23
  • 4
  • 3
    Until you've run a proper test of read and write performance for your disks you have no basis for making any inferences about the performance of your disks. By 'proper test' I mean executing one of the well established, and easily found on the Internet, benchmarks available for the purpose. I certainly wouldn't draw the conclusion that your program is inefficient -- it may simply not do enough i/o to hit your disk's (theoretical) maximum transfer rate(s). Or the mixture of reads and writes might prevent getting anywhere near the maximum transfer rate. – High Performance Mark Aug 02 '16 at 09:05
  • You need a way to get metrics on what it is doing, and what it is not doing. That is either debug lines in the code, or something like Intel inspector, etc. So you could have I/O timers, and compute timers... If you're writing or reading small blocks then it it could be getting enough processes going to slow things up. It is not uncommon to do all the I/O from a single thread and then spread out the work across the nodes. You may need to do a smaller problem with 1 or 2 threads to work it out. I suspect a race condition... Or a file not closing/flushing properly. – Holmz Aug 03 '16 at 08:24

1 Answers1

0

If using ifort, you must explicitly use buffered I/O. Flag with -assume buffered_io when compiling or set buffered='yes' in the openstatement.

If you are using gfortran this is the default, so then there must be some other problem.

Edit

I can add that depending on how you read and write the data, most time can be spent parsing it, i.e. decoding ascii characters 123 etc and changing the basis from 10 to 2 until it is machine readable data; then doing the opposite when writing. This is the case if you construct your code like this:

real :: vector1(10)

do
  read(5,*) vector1 !line has 10 values
  write(6,*) vector1
enddo

If you instead do the following, it will be much faster:

character(1000) :: line1 ! use enough characters so the whole line fits

do
  read(5,'(A)') line1 
  write(6,'(A)') line1
enddo

Now you are just pumping ascii through the program without even knowing if its digits or maybe "ääåö(=)&/&%/(¤%/&Rhgksbks---31". With these modifications I think you should reach the max of your disk speed.

Notice also that there is a write cache in most drives, which is faster than the disk read/write speeds, meaning that you might first be throttled by the read speed, and after filling up the write cache, be throttled by the write speed, which is usually lower than the read speed.

Jonatan Öström
  • 2,428
  • 1
  • 16
  • 27