Flash disk write speed problem

Code list:

uint64_t _cycle0; //initial clock cycle as the application start
uint64_t _cps = SYSPAGE_ENTRY(qtime)->cycles_per_sec; //cycles in one second
uint64_t _cpms = (uint64_t)(0.001*_cps);
inline double GetTime() { return (double)(ClockCycles()-_cycle0)/_cps; }

struct DLGHEADER
{
short header;
char type;
double time;
};

int main(int argc, char *argv[])
{
char szTime[256];
char szFileb[256];
time_t t = time(NULL);
tm *ptm = localtime(&t);
sprintf(szTime, “%02d%02d%02d%02d%02d”, ptm->tm_year-100, ptm->tm_mon+1, ptm->tm_mday, ptm->tm_hour, ptm->tm_min);
::sprintf(szFileb, “%sb.log”, szTime);

FILE *pfLog = ::fopen(szFileb, "wb");

DLGHEADER header = {0x5555, 'A', 1.0};
while(1)
{
	usleep(20000);
	cout<<::GetTime()<<endl;
	::fopen(szFileb, "a");
	for(int i=0; i<50; i++)
		fwrite(&header, sizeof(DLGHEADER), 1, pfLog);
	
	::fclose(pfLog);
	
}

return EXIT_SUCCESS;

}


I collected the output time of each write operation starting time, and found that the time for writing changes greatly(should be aroung 26-27ms, while quite a lot of points reach 60, or even 70ms), the interval of the timings is shown in the attached figure. Thanks for any suggestions.

Eric

Eric,

What’s the problem with this data?

Are you saying it’s taking too long to write in some cases or that the variations between write times is too great?

Flash Disks aren’t hard drives and so you should expect them to take quite a bit longer to write. Buying a better (faster) Flash Drive can really help decrease write times and may decreate the variations too since Flash Drives have custom algorithms to evenly wear the flash memory which may cause them to re-arrange data.

A couple of things here:

  1. Why are you opening/closing the file in the main loop? If you just left the file open you’d probably get much better performance as the seek time could be coming into play.

  2. The driver (devb-eide) generally buffers write commands unless you specifically set it up to write-immediately. Thus those 60-70 ms times could be writing out buffers of several prior write commands.

Tim

The former one, but this should lead to the great variations between write times.

Since in our applications, we need to make sure the logging data is saved in case of emergency.

Sorry, i am not quite clear about this. Could u explain more how the cases of 60-70ms write-time happen? and how can i make it write-immediately?

Thanks,
Eric

“Maybe” (Is just a guest), while the driver is buffering you get the “standard” or expected time (26-27 ms), but when the driver flush all data to the physical device, it consumes his 60-70 msecs (writing all the previouse buffered data).

Other thing important here is what else is running and at what priority (maybe graphic driver, Photon, etc, I don’t know). Try to run your program at a higher priority to discard preemption.

JM

Eric,

What kind of CF card are you using? You should get the best one money can buy if you need really fast writes.

Another thing to ensure is that whatever interrupt the IDE controller is on is not shared with another device and that the CF card is the only device on the IDE controller (ie no CD-Rom on it too). Otherwise another device could introduce delays.

The open/close is probably consuming a lot of those ms. The seek time alone could be killing your chances of writing in 20 ms since seek times are not guaranteed to be within a certain time period but rather an average seek time (prob 10 ms worth of seek time). Each time you open the file you have to jump to the end of it to write. By the time your log gets to several megabytes in size (assuming it can do so) your open time is going to get larger and larger.

You are probably going to have to use an open once, write many and close at exit time approach. There are tools to recover files under QNX and if you set devb-eide to write immediately you won’t lose any more data by doing an open once, write many, close at exit appraoch vs doing what you are doing now.

Drivers normally buffer data rather than writing to disk immediately. This gives better performance because it’s not always writing on each request but rather at defined intervals (say once every 1 second). So while it appears to your program you wrote to disk, the data may not get on the physical medium for another second or so. So those 20 ms times may be when the driver is buffering data and the 70 ms may when the driver is truly flushing the data to the physical medium along with all the data over the last second or so.

Take at look at the docs for io-blk.so in the helpviewer/QNX documentation. That explains the options you can set to force data to be written immediately. If you set commit=high all data is written immediately when it comes to the driver. But be aware, there is going to be a cost for this. The driver will likely consume more CPU time (thus denying your processes CPU time) and your average write time may go up because the driver won’t free up your writing process until the data is truly on the disk.

Out of curiousity, how fast must you log to disk (ie how often and at what kind of response time are you expecting to finish the write)? It may not be possible to achieve what you need using CF cards.

Tim

I don’t think seek times vary much for CF cards.

CF Card: We had very good experiences with SanDisk Extreme III. But the writing speed was much more bound to our other hardware setup, as ide-controller, pci-bus-controller, etc. etc. etc… But overall the SanDisk overruled all other disks in our setups. We will have some CPU-Card-Tests soon (May) again (CPCI - 3M - CPU Boards) with read/write tests on different CF / NICs / PCI-IO / …
Til now i can just recommend the given CF.

PS: We had quite some difference on CF-Tests, up to 10M/sec.

Thank you. I have confirmed that the previous mentioned solid state disk is fast enough in my application. I used another PC104 to test it and verified that.

Eric