• Named pipes vs. Unix sockets (was: Re: Are We Back to the "Wars" Now ?)

    From vallor@21:1/5 to vallor on Fri Nov 22 07:29:16 2024
    On 22 Nov 2024 07:02:47 GMT, vallor <vallor@cultnix.org> wrote in <lqaoknF8btnU2@mid.individual.net>:

    On Fri, 22 Nov 2024 06:37:06 -0000 (UTC), Lawrence D'Oliveiro <ldo@nz.invalid> wrote in <vhp8qi$12m83$2@dont-email.me>:

    On 22 Nov 2024 06:09:05 GMT, vallor wrote:

    Doesn't the named pipe connection work through the filesystem code?
    That
    could add overhead.

    No. The only thing that exists in the filesystem is the “special file” >> entry in the directory. Opening that triggers special-case processing
    in
    the kernel that creates the usual pipe buffering/synchronization
    structures (or links up with existing structures created by some prior
    opening of the same special file, perhaps by a different process), not
    dependent on any filesystem.

    I just tried creating a C program to do speed tests on data transfers
    through pipes and socket pairs between processes. I am currently
    setting
    the counter to 10 gigabytes, and transferring that amount of data
    (using
    whichever mechanism) only takes a couple of seconds on my system.

    So the idea that pipes are somehow not suited to large data transfers
    is
    patently nonsense.

    Can't use named pipes on just any filesystem -- won't work on NFS for
    example, unless I'm mistaken.

    Hard to believe NFS could stuff that up, but there you go ...

    Just tested NFS, and named pipes work there.

    $ time -p ( dd if=/dev/zero of=test count=$[1024*1024] ) & cat test > /
    dev/null
    [1] 38859
    1048576+0 records in
    1048576+0 records out
    536870912 bytes (537 MB, 512 MiB) copied, 0.918945 s, 584 MB/s
    real 0.92
    user 0.16
    sys 0.76

    NFS vers 4.1.

    $ nc -l -U -N /tmp/socket > /dev/null & time -p ( dd if=/dev/zero count=$[1024*1024*2] | nc -U -N /tmp/socket )
    [1] 40284
    2097152+0 records in
    2097152+0 records out
    1073741824 bytes (1.1 GB, 1.0 GiB) copied, 2.03617 s, 527 MB/s
    real 2.03
    user 0.47
    sys 3.60
    [1]+ Done nc -l -U -N /tmp/socket > /dev/null

    However, the speed appears to be limited by dd in my examples -- setting a block size to fill the pipe/packets seems to increase throughput:

    $ nc -l -U -N /tmp/socket > /dev/null & time -p ( dd if=/dev/zero count=$[1024*1024*4] bs=1024 | nc -U -N /tmp/socket > /dev/null )
    [1] 41764
    4194304+0 records in
    4194304+0 records out
    4294967296 bytes (4.3 GB, 4.0 GiB) copied, 4.02026 s, 1.1 GB/s
    real 4.02
    user 0.89
    sys 7.11

    $ time -p ( dd if=/dev/zero of=test count=$[1024*1024*4] bs=$[8*512]) &
    cat test > /dev/null
    [1] 41282
    4194304+0 records in
    4194304+0 records out
    17179869184 bytes (17 GB, 16 GiB) copied, 4.43357 s, 3.9 GB/s
    real 4.43
    user 0.54
    sys 3.88

    $ ulimit -p
    8
    (pipesize in 512-byte blocks)

    (Now I'm off to find out the MTU for Unix sockets...)

    --
    -v System76 Thelio Mega v1.1 x86_64 NVIDIA RTX 3090 Ti
    OS: Linux 6.12.0 Release: Mint 21.3 Mem: 258G
    ""This is a job for.. AACK! WAAUGHHH!! ...someone else." - Calvin"

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From vallor@21:1/5 to vallor on Fri Nov 22 08:38:20 2024
    On 22 Nov 2024 07:29:16 GMT, vallor <vallor@cultnix.org> wrote in <lqaq6cF8btnU3@mid.individual.net>:

    However, the speed appears to be limited by dd in my examples -- setting
    a block size to fill the pipe/packets seems to increase throughput:

    $ nc -l -U -N /tmp/socket > /dev/null & time -p ( dd if=/dev/zero count=$[1024*1024*4] bs=1024 | nc -U -N /tmp/socket > /dev/null )

    Realized the bottleneck would be the pipe between dd and nc, so wrote
    a program to connect to /tmp/socket and spew data at it -- it sends
    46950 212992-byte buffers (9999974400 bytes) in 2.41 seconds.
    (4149366971 bytes/second, or 4.1GB/s).

    (The default "MTU" for a Linux Unix socket connection
    is 212992 bytes. Default pipe size is 8*512 bytes.)

    --
    -v System76 Thelio Mega v1.1 x86_64 NVIDIA RTX 3090 Ti
    OS: Linux 6.12.0 Release: Mint 21.3 Mem: 258G
    "Profanity is the one language all programmers know best."

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Lawrence D'Oliveiro@21:1/5 to vallor on Fri Nov 22 09:37:59 2024
    On 22 Nov 2024 08:38:20 GMT, vallor wrote:

    ... or 4.1GB/s).

    That’s about what I was getting, for both a pipe (unnamed) and a
    socketpair.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Phillip Frabott@21:1/5 to vallor on Fri Nov 22 10:00:31 2024
    On 11/22/2024 03:38, vallor wrote:
    On 22 Nov 2024 07:29:16 GMT, vallor <vallor@cultnix.org> wrote in <lqaq6cF8btnU3@mid.individual.net>:

    However, the speed appears to be limited by dd in my examples -- setting
    a block size to fill the pipe/packets seems to increase throughput:

    $ nc -l -U -N /tmp/socket > /dev/null & time -p ( dd if=/dev/zero
    count=$[1024*1024*4] bs=1024 | nc -U -N /tmp/socket > /dev/null )

    Realized the bottleneck would be the pipe between dd and nc, so wrote
    a program to connect to /tmp/socket and spew data at it -- it sends
    46950 212992-byte buffers (9999974400 bytes) in 2.41 seconds.
    (4149366971 bytes/second, or 4.1GB/s).

    (The default "MTU" for a Linux Unix socket connection
    is 212992 bytes. Default pipe size is 8*512 bytes.)


    Yeah, this has been the experience of our testing as well. We can also
    bump the MTU up a bit to get sockets to do better and we've also
    modified some of the socket code to our environment so it's able to do
    around 12GB/s. We think we can tune it further to get about 15GB/s from sockets. At the moment we have to do 4.6GB per 0.5sec to keep up, and
    7GB per 0.5sec to stay ahead. We've done everything we can to squeeze
    out as much performance from pipes as we could but there just isn't much
    we can do anymore. But yeah, sockets are way more capable of large data
    intake vs pipes, and this shows as well in a lot of research that's been
    done. We've been testing sockets for about the last year and the results
    have shown we are keeping up better then we are with pipes right now.

    And for tribute to pipes, we've been using pipes in this project for the
    last 30 years. That's a pretty great track record for something to have
    been useful for such a long time and not be replaced with something else
    until now. Sadly sockets will likely bottom out in the next 10-15 years
    and we'll have to switch to something else. But for now, it's working.

    --
    Phillip Frabott
    ----------
    - Adam: Is a void really a void if it returns?
    - Jack: No, it's just nullspace at that point.
    ----------

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Lawrence D'Oliveiro@21:1/5 to Phillip Frabott on Fri Nov 22 20:52:17 2024
    On Fri, 22 Nov 2024 10:00:31 -0500, Phillip Frabott wrote:

    At the moment we have to do 4.6GB per 0.5sec to keep up, and
    7GB per 0.5sec to stay ahead. We've done everything we can to squeeze
    out as much performance from pipes as we could but there just isn't much
    we can do anymore.

    Sounds like a job for a shared memory section.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Phillip Frabott@21:1/5 to Lawrence D'Oliveiro on Fri Nov 22 17:06:06 2024
    On 11/22/2024 15:52, Lawrence D'Oliveiro wrote:
    On Fri, 22 Nov 2024 10:00:31 -0500, Phillip Frabott wrote:

    At the moment we have to do 4.6GB per 0.5sec to keep up, and
    7GB per 0.5sec to stay ahead. We've done everything we can to squeeze
    out as much performance from pipes as we could but there just isn't much
    we can do anymore.

    Sounds like a job for a shared memory section.

    That only works if the entire dataset originates on, and results within,
    the same system. Unfortunately this is not the case so it wouldn't be
    possible. This is an intermediate system between the intake and final processing systems which are further down the line.

    Unless you can recommend a way to do shared memory across different
    machines without extra hardware. Currently we ingest data from a
    (external) /dev (unbuffered data stream) into a process on the machine
    that buffers the data (currently though an unnamed pipe, which as I said
    before is in the process of being replaced with UNIX socket) then that
    data pipes to another process (again, being replaced with UNIX socket
    soon) which converts the data stream from the buffer to block data and
    then categorizes those blocks based on data types and depending on those
    data types sends it to one of 4 /dev devices that leave the machine. The bottleneck is not between the first and second process (buffer process
    and stream to block data processor) it's between the intake /dev to the intermediate and the intermediate to the 4 outbound /devs. These /dev
    are not networks so there is no TCP data. They are hard lined between
    the /dev machine and the intermediate computer and the intermediate
    computer to the 4 other /dev machines. So how would I share memory
    between /dev machines from the 80s-90s and the intermediate computer
    without using any network or TCP/UDP capabilities?

    (If it was not apparent. these are manufacturing machines.)

    --
    Phillip Frabott
    ----------
    - Adam: Is a void really a void if it returns?
    - Jack: No, it's just nullspace at that point.
    ----------

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Lawrence D'Oliveiro@21:1/5 to Phillip Frabott on Sat Nov 23 00:42:21 2024
    On Fri, 22 Nov 2024 17:06:06 -0500, Phillip Frabott wrote:

    Unless you can recommend a way to do shared memory across different
    machines without extra hardware.

    Ah, I thought you were running all these processes on the same machine,
    since pipes don’t work any other way.

    What about those high-speed interconnects like the ones they use in supercomputers? 40Gb Ethernet (not sure if 100Gb is working yet)? How fast
    does SCSI go? Some fibre-based interconnect?

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Geoff Clare@21:1/5 to Rich on Tue Nov 26 14:21:21 2024
    Rich wrote:

    The only 'filesystem' access for named pipes is during the
    open() call to look up the name from the filesystem. Once you get the
    file descriptor back, it is the exact same in-memory FIFO queue as an anonymous pipe created via pipe() (at least on Linux).

    POSIX requires that pipes and FIFOs behave identically once you have a
    file descriptor. This is how it defines the term "pipe":

    An object identical to a FIFO which has no links in the file hierarchy.

    --
    Geoff Clare <netnews@gclare.org.uk>

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Richard L. Hamilton@21:1/5 to Phillip Frabott on Tue Dec 3 05:23:15 2024
    In article <vhq6ag$176f0$1@dont-email.me>,
    Phillip Frabott <nntp@fulltermprivacy.com> writes:
    On 11/22/2024 03:38, vallor wrote:
    On 22 Nov 2024 07:29:16 GMT, vallor <vallor@cultnix.org> wrote in
    <lqaq6cF8btnU3@mid.individual.net>:

    However, the speed appears to be limited by dd in my examples -- setting >>> a block size to fill the pipe/packets seems to increase throughput:

    $ nc -l -U -N /tmp/socket > /dev/null & time -p ( dd if=/dev/zero
    count=$[1024*1024*4] bs=1024 | nc -U -N /tmp/socket > /dev/null )

    Realized the bottleneck would be the pipe between dd and nc, so wrote
    a program to connect to /tmp/socket and spew data at it -- it sends
    46950 212992-byte buffers (9999974400 bytes) in 2.41 seconds.
    (4149366971 bytes/second, or 4.1GB/s).

    (The default "MTU" for a Linux Unix socket connection
    is 212992 bytes. Default pipe size is 8*512 bytes.)


    Yeah, this has been the experience of our testing as well. We can also
    bump the MTU up a bit to get sockets to do better and we've also
    modified some of the socket code to our environment so it's able to do
    around 12GB/s. We think we can tune it further to get about 15GB/s from sockets. At the moment we have to do 4.6GB per 0.5sec to keep up, and
    7GB per 0.5sec to stay ahead. We've done everything we can to squeeze
    out as much performance from pipes as we could but there just isn't much
    we can do anymore. But yeah, sockets are way more capable of large data intake vs pipes, and this shows as well in a lot of research that's been done. We've been testing sockets for about the last year and the results
    have shown we are keeping up better then we are with pipes right now.

    And for tribute to pipes, we've been using pipes in this project for the
    last 30 years. That's a pretty great track record for something to have
    been useful for such a long time and not be replaced with something else until now. Sadly sockets will likely bottom out in the next 10-15 years
    and we'll have to switch to something else. But for now, it's working.



    Shared memory and a semaphore to coordinate access? Should be crazy fast
    given a large enough hunk of shared memory. More changes on both ends, of course; whereas on Solaris, I swapped (unnamed) pipes (STREAMS based, there) with socketpair() using an LD_PRELOADable wrapper, so no changes on either end. Just to see if I could; I didn't run any timing tests.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Lawrence D'Oliveiro@21:1/5 to Richard L. Hamilton on Tue Dec 3 06:20:01 2024
    On Tue, 03 Dec 2024 05:23:15 GMT, Richard L. Hamilton wrote:

    ... whereas on Solaris, I swapped (unnamed) pipes (STREAMS based,
    there) with socketpair() using an LD_PRELOADable wrapper, so no changes
    on either end.

    STREAMS made that easy to do, didn’t it. Yet the whole idea was never that popular; both Steve Jobs and Linus Torvalds were less than enthusiastic
    about it. Were there performance downsides?

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Richard L. Hamilton@21:1/5 to Lawrence D'Oliveiro on Sat Dec 14 07:58:09 2024
    In article <vim7ug$3t1l3$3@dont-email.me>,
    Lawrence D'Oliveiro <ldo@nz.invalid> writes:
    On Tue, 03 Dec 2024 05:23:15 GMT, Richard L. Hamilton wrote:

    ... whereas on Solaris, I swapped (unnamed) pipes (STREAMS based,
    there) with socketpair() using an LD_PRELOADable wrapper, so no changes
    on either end.

    STREAMS made that easy to do, didn’t it. Yet the whole idea was never that popular; both Steve Jobs and Linus Torvalds were less than enthusiastic
    about it. Were there performance downsides?

    What I did didn't depend on STREAMS, only that the pipe implementation
    was bidirectional like a socketpair() is, so that the behavior is
    similar enough for most purposes. So I didn't write a STREAMS module.
    The difference between pipe() and socketpair() does change some of the
    tricky things that can be done; for instance, both STREAMS pipes and socketpair() could allow passing a file descriptor, but how that's
    done is quite different.

    Solaris still uses STREAMS, but to get TCP/IP up to full speed, the
    connection between the two isn't STREAMS any more (so you can't put
    a STREAMS module between them) but some faster approach at
    handing off packets. Somewhere in there is also a fast packet classifier,
    to decide what listeners get what packets as quickly as possible.

    Not sure how they did SCTP, haven't looked at that code.

    So yes, the full generality of STREAMS can have performance limitations.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)