Slight delay when writing to file


12 posts
by satz » Sun Nov 04, 2012 10:28 am
Hey everyone..

I am trying to write counter output to a file when ir sensor detects
obstacle..

So, when i run the code and try to place object in front of the sensor, sometimes it hangs.. so i tried 100 iteration to write to file and noticed it do stuck at least 2 to 3 times in every 100 iteration..

Any idea hw to solve or better method ?

Code: Select all
 
void detected(int count)
{
   fp = fopen("raw", "w");
   char buffer[6] ;
   snprintf(buffer, sizeof(buffer), "%d",count);

   size_t len = 0;
   len=strlen(buffer);
   fwrite(buffer, len, 1, fp);
   fclose(fp);
}

void test()
{

   for (int i=0;i<100;i++)
   {
      detected (i);
   }

}

Posts: 15
Joined: Wed Oct 24, 2012 12:05 pm
by BlackJack » Sun Nov 04, 2012 5:57 pm
@satz: I guess you get the delay when the data is finally written from the in-memory cache to the SD card. Which is quite slow. Solution: don't write to the SD card. :-) If it has to be a file and if it does not have to be permanent in case of power loss then write the file into a RAM file system.

BTW: You might want to look up what the return value of `snprintf()` means. :-)
Code: Select all
while not self.asleep():
    sheep += 1
Posts: 288
Joined: Sat Aug 04, 2012 8:28 am
by AndyD » Sun Nov 04, 2012 10:30 pm
@satz, why are you writing to an array and then writing to the file? Your code could be simplified to the following.
Code: Select all
void detected(int count)
{
    fp = fopen("raw", "w");
   
    if (fp)
    {
        fprintf(fp, "%d",count);
        close(fp);
    }
}


When you say hang do you mean a delay? File I/O can be delayed for all sorts of reasons.

Are you using this file to communicate with other processes? If you are you may want to consider a different form of communication between the processes. I found this link with a quick search http://beej.us/guide/bgipc/ and it covers all the IPC mechanisms I can think of, off the top of my head.

Hope this helps.
Posts: 909
Joined: Sat Jan 21, 2012 8:13 am
Location: Melbourne, Australia
by satz » Mon Nov 05, 2012 1:41 pm
hi, thx for the replies..

i actually separated the code to 2 for some other purpose..
yeah, i need to write to file ..

or is there some other method to link the output to php (web server) ?
time for each write (~300ms)..

thx..
Posts: 15
Joined: Wed Oct 24, 2012 12:05 pm
by tedhale » Mon Nov 05, 2012 1:49 pm
fflush(fp);
- Ted B. Hale
http://raspberrypihobbyist.blogspot.com
User avatar
Posts: 111
Joined: Thu Sep 20, 2012 4:52 pm
Location: Williamsburg, VA, USA
by BlackJack » Mon Nov 05, 2012 3:34 pm
@tedhale: Why? The file is closed right after the write, so there is no point in an explicit `flush()` which is implicit in the closing of the file.
Code: Select all
while not self.asleep():
    sheep += 1
Posts: 288
Joined: Sat Aug 04, 2012 8:28 am
by satz » Tue Nov 06, 2012 2:07 am
Hi, i tried both with and without fflush(fp);

It has no difference, when i loop to write to a file 100 times, it still stuck
or has certain delay 2 to 3 times..

Any other idea ?

Thx
Posts: 15
Joined: Wed Oct 24, 2012 12:05 pm
by AndyD » Tue Nov 06, 2012 7:55 am
As @BlackJack said previously there is no need to fflush() as fclose() will flush and close the stream.

I still think that you need to reconsider your design to get over the issue. There are millions of programs out there using fopen(), fwrite() and fclose(), these are pretty fundamental.

You could try putting some timing in your code to see which is the call that is causing the delay.

You could always try using unbuffered I/O using the open(), write() and close() functions. (These function are in section 2 of the Un*x manuals so you need to type man 2 open to get the correct man page). I suspect you will get the same performance, but it is worth a try.

I have just tried your original code (once it was corrected to compile) on my Pi (latest wheezy) and can't see any delay. Is it possible that the delay is in another part of the code?
Posts: 909
Joined: Sat Jan 21, 2012 8:13 am
Location: Melbourne, Australia
by AndyD » Tue Nov 06, 2012 8:32 am
Just tried the code with some timing. Running 100 times average time 2419 microseconds, minimum time 1888 usecs, max time 2951 usec.

I think to get further you will need to consider:-

What distribution are you using?
Are you using a relatively fast SD card? The Pi I tested on is using an 8Gb Sandisk Ultra.
What else do you have running that could be tying up the disk I/O?
Are you running out of memory so that memory is being swapped to disk?

I should have read your last post more carefully. Looks like you have a write time of 300mS. That is certainly longer than my test that was 2-3mS. I can't remember the command off the top of my head, but there was one to test I/O speed that I saw in the forums that people were using to test SD card speed.
Posts: 909
Joined: Sat Jan 21, 2012 8:13 am
Location: Melbourne, Australia
by satz » Tue Nov 06, 2012 11:34 am
thx alot for the reply.. well, i am using class 6 card, 16GB kingston..

i am using whezzy.. i have mysql, apache n php (LAMP) running in
background.. could that cause the delay ?

i mean, i need to write to file every 300ms..
even by using system("echo o> raw); looping 1000 times stuck twice..
delayed for say about 500ms.. den it goes fast again..

now i am trying to implement open, close.. reading about it now.. :)
Posts: 15
Joined: Wed Oct 24, 2012 12:05 pm
by AndyD » Tue Nov 06, 2012 10:10 pm
Hi @satz,
I wouldn't bother with the unbuffered I/O as I am pretty sure this isn't going to solve you problem. If echo'ing to a file is showing the same behavior then I suspect that your system is just busy. I don't have much experience configuring mysql or apache, but if it was me I would start looking at trying to get them to use less cpu and memory resources. Before doing that I would try to work out which resource is causing the bottleneck.You can use the top command to view cpu and memory usage, but there are a number of other commands that will let you monitor resources (vmstat etc).

It could also be that your process is being switched out, so another process can run. The Pi has only one core and as Linux is multitasking. So, from time to time your process will be stop executing so that other processes can be run. Take a look at you load average (use uptime as a quick report).
Posts: 909
Joined: Sat Jan 21, 2012 8:13 am
Location: Melbourne, Australia
by satz » Thu Nov 08, 2012 4:00 pm
thx alot everyone.. found out that mysql is the cause of all this !!
made fresh instal n its good now..!
Posts: 15
Joined: Wed Oct 24, 2012 12:05 pm