0

I'm trying to send images from C# running on win 11 to a python server running on WSL2.

I'm using ZeroMQ to send byte arrays, but as soon as the byte arrays cross a threshold (~8kb) the latency spikes from 0.3ms to 50ms. This 50ms latency remains until I get to ~74KB. Then it reduces back to about 0.3ms.

I have seen references to Nagle's algorithm (https://stackoverflow.com/a/75190133/1988046) but it seems that Nagle's is disabled by default in zeromq (http://wiki.zeromq.org/area:faq).

[Update] I ran it with a local install of python on the Win 11 side and did not see this problem at all, even though I was using exactly the same code file.

Can anyone suggest what I'm doing wrong?

C# Client

using System.Diagnostics;
using NetMQ;
using NetMQ.Sockets;

namespace ChatGptUdp;

internal class Program
{
    private static void Main(string[] args)
    {
        var socket = new RequestSocket();
        socket.Connect("tcp://localhost:5555");
        var data = new byte[100000];
        for (var i = 0; i < data.Length; i++) data[i] = (byte) i;

        for (var i = 1; i < 100; i++)
        {
            var targetLength = 1000 * i;
            var chunk = data.Take(targetLength).ToArray();
            var elapsed = new List<TimeSpan>();
            for (var j = 0; j < 100; j++)
            {
                var sw = Stopwatch.StartNew();
                socket.SendFrame(chunk);
                var response = socket.ReceiveFrameString();
                sw.Stop();
                elapsed.Add(sw.Elapsed);
            }
            // I skip the first 50 so that I ignore any startup delays. 
            // I don't think that will happen with this version of my algorithm, but just to be sure.
            Console.Out.WriteLine($"{targetLength}: {elapsed.Skip(50).Average(s => s.TotalMilliseconds)}");
        }
    }
}

Python Server

import zmq
import numpy as np
context = zmq.Context()
socket = context.socket(zmq.REP)
socket.bind('tcp://*:5555')
print("Server connected")
while True:
    msg = socket.recv()
    data = {
        'str': 'Hello there!'
    }
    socket.send_json(data)

Latency results

Size in bytes Time in ms
1000 0.3235700000000001
2000 0.28261
3000 0.28320400000000007
4000 0.280366
5000 0.35102799999999995
6000 0.2954839999999999
7000 0.30082
8000 0.27812799999999993
9000 50.00155000000001
10000 49.99915800000001
11000 50.00125
12000 50.008024
... ...
70000 50.004577999999995
71000 49.986256
72000 49.99861
73000 49.998368
74000 2.3343279999999997
75000 0.337194
76000 1.37548
77000 0.34829199999999993
78000 0.31957599999999997
79000 0.3393840000000001
80000 0.34001999999999993
5
  • Is that a one time measurement or is that consistently repeatable? Commented Mar 22, 2023 at 19:32
  • It's repeatable. And it's always at 8kb and 74kb Commented Mar 22, 2023 at 19:47
  • And sorry about the data at the end. It's a well formatted table in the preview. Not sure why it breaks in practice. Commented Mar 22, 2023 at 20:02
  • Does the behavior change if you go from big to small? Or start somewhere in the middle? Or even randomly chosen sizes? Commented Mar 22, 2023 at 21:44
  • Yes, exactly the same. Running in random order produced an identical distribution. Commented Mar 22, 2023 at 21:59

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.