Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Very slow second write to a socket #31842

Open
mateuszbaran opened this issue Apr 26, 2019 · 3 comments
Open

Very slow second write to a socket #31842

mateuszbaran opened this issue Apr 26, 2019 · 3 comments
Labels
io Involving the I/O subsystem: libuv, read, write, etc. performance Must go faster sockets

Comments

@mateuszbaran
Copy link
Contributor

I am experiencing very poor performance in a client-server application that communicates over loopback when I split a single write on the server into two separate writes to a socket. I have the following code:

using Sockets

function u_server(host::IPAddr, port::Int)
    task = @async begin
        server = listen(host, port)
        while true
            sock = accept(server)
            @async begin
                while !eof(sock)
                    line = read(sock, 1)
                    t0 = time()
                    write(sock, [0x00, 0x00])
                    flush(sock)
                    t1 = time()
                    println("time: ", t1-t0)
                end
            end
        end
    end
    return task
end

function u_client(host, port::Integer)
    conn = connect(host, port)
    write(conn, 0x20)
    flush(conn)
    response_len = read(conn, 2)

    time()
    write(conn, 0x20)
    flush(conn)
    t0 = time()
    response_len = read(conn, 2)
    t1 = time()

    println("Total time (s): ", t1-t0)
    close(conn)
end

I run server by calling u_server(IPv4("127.0.0.1"), 2041) and, in a separate Julia REPL process, I run a client u_client(IPv4("127.0.0.1"), 2041). The code above has good performance, the time it takes the client to receive both bytes is on the order of 0.1ms. However, if I send the bytes separately (for example by replacing write(sock, [0x00, 0x00]) with write(sock, 0x00, 0x00)) the time measured by the client jumps to over 40ms and is consistent across multiple runs.

Version info:

Julia Version 1.1.0
Commit 80516ca202 (2019-01-21 21:24 UTC)
Platform Info:
  OS: Linux (x86_64-pc-linux-gnu)
  CPU: Intel(R) Core(TM) i7-4800MQ CPU @ 2.70GHz
  WORD_SIZE: 64
  LIBM: libopenlibm
  LLVM: libLLVM-6.0.1 (ORCJIT, haswell)
@JeffBezanson
Copy link
Member

This reminds me of #45 (fixed by #6302). The disable_nagle function ended up in Distributed, but it looks like it should be moved to Sockets and documented.

@JeffBezanson JeffBezanson added io Involving the I/O subsystem: libuv, read, write, etc. performance Must go faster labels Apr 26, 2019
@mateuszbaran
Copy link
Contributor Author

Thanks, that seems to be it. I can make a PR. By the way, do you think Nagle's algorithm should be enabled or disabled by default?

@jpsamaroo
Copy link
Member

Nagle's algorithm is important for ensuring good performance when doing large numbers of small writes/reads to/from a TCP socket. The fact that it's on by default for TCP sockets in most (all?) Linux distributions is, to me, a signal that it's a sensible choice to leave it on by default in applications. The assumption made seems to be that high bandwidth usecases far outweight low latency usecases.

mateuszbaran added a commit to mateuszbaran/julia that referenced this issue May 4, 2019
mateuszbaran added a commit to mateuszbaran/julia that referenced this issue May 5, 2019
mateuszbaran added a commit to mateuszbaran/julia that referenced this issue May 24, 2019
…1842 )

disable_nagle was split into nagle (which enables or disables Nagle's 
algorithm) and quickack (which enables or disables TCP_QUICKACK on Linux 
systems).
JeffBezanson pushed a commit that referenced this issue Jun 6, 2019
…31924)

disable_nagle was split into nagle (which enables or disables Nagle's 
algorithm) and quickack (which enables or disables TCP_QUICKACK on Linux 
systems).
freemin7 added a commit to freemin7/julia that referenced this issue Dec 17, 2023
Improve Nagle DocString. See also JuliaLang#31842
aviatesk pushed a commit that referenced this issue Dec 20, 2023
Improve Nagle DocString. See also
#31842

---------

Co-authored-by: Elliot Saba <staticfloat@gmail.com>
Keno pushed a commit that referenced this issue Jun 5, 2024
…31924)

disable_nagle was split into nagle (which enables or disables Nagle's 
algorithm) and quickack (which enables or disables TCP_QUICKACK on Linux 
systems).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
io Involving the I/O subsystem: libuv, read, write, etc. performance Must go faster sockets
Projects
None yet
Development

No branches or pull requests

4 participants