Go Down

Topic: YunServer transfer rate very slow (Read 9921 times) previous topic - next topic

priority

Tried this on 2 different Yuns and both exhibited the same behavior.  One Yun was freshly config'ed out of the box with a newly formatted 2gb sd card with the proper directories setup.

When I load the TemperatureWebPanel example sketch as-is, everything compiles and uploads properly.  When I go to arduino.local/sd/TemperatureWebPanel in both firefox and chrome, everything appears be working.   I see the webpage update every couple of seconds. 

However, if I look under the hood at the resulting get from $('#content').load('/arduino/temperature')  with firebug or chrome developer tools, it is taking 2 to 4 seconds for the 32U4 to respond to the get request.  Since the transfer of info from the 32U4 under 200 bytes, and the request is 13 bytes,  the effective transfer rate is very, very, very, very slow.

Any ideas on why it takes so long for the 32u4 and AR9331 to exchange a few bytes?

scrot

Understand that the processor running Linino is very, very, slow.  Raspberry Pi suffers from the same problem.  Secondly the code implementing the Bridge, and the YunServer is written to expose a wide variety of functionality first, performance second.

My inspection of the BridgeServer code revealed one socket per transmission as opposed to more efficiently keeping a socket open. 

That all said, the Arduino team did a terrific job delivering this functionality.  Since it is open source it is up to us to improve it.  I'm currently working on taking the bridge out of the picture entirely and using a direct serial connection between the a sketch and a Python program running on Linino.  I hope that this approach will be much faster, but it will be more complex to set up a solution.

priority

I have continued to work on this since my earlier posting.  My problem is not so much related to the AR9331's performance as it is to the bridge code; I have a "farm" of RPi's running various tasks (webservers and data collection); the AR9331 is a bit slower, but still good from my perspective.  The Yun is actually turning out respectable performance for a handful of tests of serving webpages (an example: html+jQuery is showing ~2mpbs for 150k page) when it does not have to talk to the 32U4.

As a point of comparison for what should be possible for relatively small data packets, a project I have running has a 328 connected via SPI to a ENC28J60 ethernet controller transfers ~500 bytes in ~70ms.

So, it should be possible to get a 200 byte packet transferred in the tens of millisec range on the Yun. 

In short, there is a lot of performance left on the table; it is a very safe bet your Python code will be able to get somewhere close to 100X improvement over the current bridge code.

priority

Still working to understand the extremely slow transfer rates with YunServer/YunClient.

To help narrow down the source of the latency, I measured the time in milliseconds that it takes on the Arduino to respond to a HTTP request from the AR9331.  The average time was about 1200msec.  Since this is an HTTP transaction, it is not possible to conclusively say which side is causing the latency.  However, it is important to note the browser sees an additional > 1 sec delay before it gets the data.

As a point of comparison, I modified the TemperatureWebPanel program to use the mailbox bridge functionality.  Time to put two key/value pairs was around 20msec as measured on the Arduino.  Much better!

Interestingly, if you view the key/value pairs in a browser at arduino.local/data/get, the /data/get operation takes about 500 msec (measured by Firebug and Chrome Developer Tools).   Since the arduino is not involved in displaying the key/value values in the browser, the relatively slow webpage response has to be on the AR9331 with the mailbox bridge code and/or webserver being the likely culprit(s). 


federicofissore

Hi priority and thank you for your analysis.
The speed problem you see on the temperature web panel is not related to the speed of the communication channel between the sketch and the ar9331, but rather on what that sketch is doing
TemperatureWebPanel, after having received a request, is calling a linux program (date) and then is packing the response. This going back and forth has a cost and starting another process has an additional cost.

If you just want to test the communication speed, you should write a sketch that exposes an API (let's call it "test") that sends back a known number of characters (a for loop of 10240 iterations that prints "a", for example) and stress that API with "ab" (http://httpd.apache.org/docs/2.2/programs/ab.html). Call that "test" API some hundreds of thounsands time and read ab output.
It should report a much higher speed

Just to drop details in the forum, every http request causes uhttpd (the webserver) to fork, just like apache does. Your API will be handled by a lua script, so you'll also see a dedicated lua process. This means 2 new processes for each API call. This is not very memory efficient but it's an easy way to free memory at the end of the request.

Historical note: the first release of the web part of the yun used python to do everything, both the web server and the linux part of the bridge. It was a residend process and it was much much faster but used 8MB of ram, no matter if you were using it or not, so we replaced it.

Go Up