- This topic has 6 replies, 2 voices, and was last updated 9 years, 6 months ago by
Anonymous.
-
AuthorPosts
-
January 28, 2015 at 14:18 #3643
Anonymous
InactiveHi, I develop an application where a central server is connected to many clients (mobile devices via Wifi).
The central server on his part routes the received messages to a further application that usually resides on the same PC, so it’s localhost communication.
Basically it works, but I worry that the throughput of networkcomms is not sufficient.
Even with two test clients, that each send approxmimately 50 small messages per second, the central server has a total CPU load up to 50% for a single CPU core (Intel i7-4702MQ).One hotspot for CPU usage seems to be the StreamTools.Write method.
I don’t fully understand why it’s realized this way, but it seems to introduce a considerable amout of overhead.
I tried different settings of SendBufferSizeBytes and Initial/Max-ReceiveBufferSizeBytes, but without any satisfactory results.
Is there a way to reduce CPU load?Apart from that it’s really a great library!
January 29, 2015 at 01:00 #3645Anonymous
InactiveI replaced the StreamTool.Write implementation with a simple synchronous version:
public static double Write(Stream inputStream, long inputStart, long inputLength, Stream destinationStream, int writeBufferSize, double timeoutMSPerKBWrite, int minTimeoutMS) { if (inputStream == null) throw new ArgumentNullException("source"); if (destinationStream == null) throw new ArgumentNullException("destination"); //Make sure we start in the right place inputStream.Seek(inputStart, SeekOrigin.Begin); int bytesRemaining = (int)inputLength; int bufSize = Math.Min((int)inputLength, writeBufferSize); byte[] buf = new byte[bufSize]; while (bytesRemaining > 0) { int count; if (bytesRemaining < buf.Length) count = (int)bytesRemaining; else count = buf.Length; inputStream.Read(buf, 0, count); destinationStream.Write(buf, 0, count); bytesRemaining -= count; } return 0; }
Now the performance is fine!
First I thought the allocation of the various buffers and objects in your implmenentation is the reason, but now I suppose it’s due to the overhead of thread/context switching from the asynchronous stream begin/end methods.
Tested it with a slightly modified version of your ExamplesConsole AdvandedSend example which runs now five times faster.
Send calls per second increased from 5000 to 25000 on localhost and CPU load dropped to one third.January 30, 2015 at 10:47 #3650Anonymous
InactiveInteresting, thanks for the update. The reason we use an async write is that we noticed on some platforms, I think it was mono and android, streams would sometimes freeze and the write would crash the application.
I would not have expected to see such a significant performance difference. Could you give us some more information about the platform you are running this on?
Kind regards,
MarcJanuary 30, 2015 at 15:45 #3651Anonymous
InactiveHi Marc, I’m running it on a Windows 8.1 Pro Notebook with a i7-5702MQ CPU (2,2 GHz). The effect is the same at least for .Net Framework 3.5 and 4.0.
January 30, 2015 at 15:47 #3652Anonymous
InactiveCorrection: i7-4702MQ
February 17, 2015 at 22:42 #3708Anonymous
InactiveHi Marc, can you reproduce this observations and is there a chance that a faster StreamTool.Write implementation finds it’s way into a coming release?
February 18, 2015 at 21:28 #3716Anonymous
InactiveI have added this to our roadmap.
Regards,
Marc -
AuthorPosts
- You must be logged in to reply to this topic.