Home Forums Support Throughput and performance

Viewing 7 posts - 1 through 7 (of 7 total)
  • Author
    Posts
  • #3643
    Anonymous
    Inactive

    Hi, 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!

    #3645
    Anonymous
    Inactive

    I 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.

    #3650
    Anonymous
    Inactive

    Interesting, 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,
    Marc

    #3651
    Anonymous
    Inactive

    Hi 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.

    #3652
    Anonymous
    Inactive

    Correction: i7-4702MQ

    #3708
    Anonymous
    Inactive

    Hi 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?

    #3716
    Anonymous
    Inactive

    I have added this to our roadmap.

    Regards,
    Marc

Viewing 7 posts - 1 through 7 (of 7 total)
  • You must be logged in to reply to this topic.