Measure read() and write() time with no system caching

Hi all,

This post is an extension to my earlier query regarding read() and write() time.
To avoid confusions, I am posting a new topic in a different context.
Please note: Before reading this thread, if you want to refer my earlier queries and replies, please refer
openqnx.com/phpbbforum/viewt … 10&t=13551

I am still trying to get a solution for getting the actual read(), write() speed without involving system cache to the maximum.
Problem is getting worse when I do a read() after a write() and a simple read() alone to the disk.
read() after a write() is very faster than read() alone.

I have tried one more approach. I have given cache=0M argument to devb-eide driver at bootup.
Then speed of read() after write() for MB sized blocks is almost comparable to read() alone speed.
But for smaller KB sized blocks, speed variation still exists.
But I am not sure of the root cause of this speed variation at smaller data sizes.
Also I am not sure what this “cache=” argument means for devb-eide? Is it disk cache or system cache?
Is it a good way to disable cache to 0M?

On just skimming through QNX help files, I again noticed another set of functions like msync(), mmap_device_memory,
cache_init(), CACHE_FLUSH() and CACHE_INVAL().
Could any one please comment on whether I can use any combinations of these routines to measure the actual speed of my read(),
write() APIs?
Note: For the time-being, we can ignore the usecase of disabling disk cache. Just consider disabling the system cache.
I would like to experiment on how disabling system caching will affect the usecase…

Please also share if you have any other ideas on this problem…
I am very much stuck in this issue… :frowning:

Thanks,
Lullaby

Lullaby,

If you are just trying to test the ‘raw’ speed of read and write commands you have to get the cache out of the way. By cache I mean the O/S cache (decb-eide) and the physical disk cache (typically 32 or 64 Megs).

So doing a write followed by a read of the SAME DATA is going to read from cache. Either the O/S cache or the physical disk cache.

Just how accurate a number do you require? Are you looking for a time in seconds? tenths of seconds, milliseconds, nano-seconds?

Testing read time should be relatively straight forward. Just have a reasonable size file on the hard drive. Then use your program to read it into memory and time how long that takes. If you run your program repeatedly it should produce smaller numbers the second (and beyond) time since it will be reading cached data (O/S or physical disk). So between runs of your test program you’ll need to have another program read a different much larger file (I’d suggest 64 megs to invalidate the physical disk cache). That way you’ll get the cache out of the equation.

For doing writes I suggest writing a file LARGER than 64 Megs (thus invalidating caches). Then time how long that takes.

Tim

thank you for your reply, tim.
our application needs read/write speed in MB/sec. currently we are using clockcycles() before and after the read/write api to get the expired cycles and hence time. then calculate speed of read/write using this time. that is all okay.
but could you explain me if the functions msync(), cache_init(), Cache_flush() etc can be used? how?

lullaby

If you set cache= below a minimum, the driver will use the minimum. The driver cannot function with 0 cache. This cache is a memory area that holds disk sectors.

As explained by someone else previously, the cache_…() routines refer to the memory cache.
msync() has also works on the memory cache. mmap_device_memory() is used to allocate memory for a hardward device, typically for use with a DMA channel. The reason this is needed is that regular memory is virtual. The physical memory behind it may not be contiguous, but for a DMA transfer, you need contiguous memory.

Tim’s suggestions will give you reasonable answers to your questions.

Thank you all for your replies.
But I guess, your suggested methods don’t work for me.
The requirement of my application is:-
Application will read/write/read after write a user defined data buffer of size in KB or MB
continuously to the hard-disk from start sector to end sector. Each time, an operation is
performed, it will keep track of the time using ClockCycles() and also calculate the speed
of each sector read/write operation.
So I couldn’t customize my operations so as to induce cache misses and get the correct disk
performance. :frowning:

I understood from your replies that even if we give cache=0M argument to devb-eide driver, it won’t work with 0 cache, instead it works with a minimum cache. So I assume the speed variations in lower sized datasizes is due to the effect of minimum cache. So that method also won’t work the way I expect.

My question is:

  1. Can I specify a “write-through” (cached data is immediately written to memory) mechanism through any of the available options in QNX? Is that msync() API mean? I am very much confused with this system cache, disk cache, memory cache etc… :frowning:

Thanks,
Lullaby

What I’m hearing is that you expect the speed calculation to reflect the actual time it takes
to get the data to disk. Is that right?

Well then you either need to get another OS, write your own custom file I/O or relax your requirement.

OK now I understand your application a bit better. But I have another question for you.

Are you trying to test whether the logic of your code works? Or are you trying to guarantee that the read/write and read times you measure and report to the user are always equal. If your answer is the second one it’s going to be almost impossible to get that with real hardware due to the cache on the physical disk, platter speed (data on another platter takes more time to retrieve) etc unless you are using an SSD drive. Even then devb-eide has it’s own cache that will sometimes already have the data in it speeding up retrieval time.

On the other hand for testing the logic of your program you could use a RAM drive. That gets rid of the physical hard drive component to allow you to test just the O/S part of things speed wise.

// Create an and mount 50 Meg RAM drive
devb-ram ram capacity=100000 &
mount -t qnx4 /dev/hd1t77 /fs/ram

// List the contents of the RAM drive
ls /fs/ram

At this point you can read/write to the RAM drive as if it’s a normal hard drive. Just make sure to prefix all your paths with /fs/ram/PATH/FILE or else it will be written to your regular hard drive.

Note: devb-ram is now the ‘disk driver’ instead of devb-eide. I don’t know if devb-ram has any caching. There are no options for it so I suspect there is no caching at all since it’s literally memory being used.

Tim

P.S. I can’t remember whether you talked about this in another thread or not. But are you running a multi or single core build of QNX? If you are running a multi-core build then timing things with ClockCycles() is a bit trickier than with a single core build.