18 ms·
How fast are Linux pipes anyway?
- spacechild1 4y agoMaybe a stupid question, but why aren't pipes simply implemented as a contiguous buffer in a shared memory segment + a futex?
- jagrsw 4y agoSomething maybe a bit related. I just had 25Gb/s internet installed (https://www.init7.net/en/internet/fiber7/ https://www.init7.net/en/internet/fiber7/), and at those speeds Chrome and Firefox (which is Chrome-based) pretty much die when using speedtest.net at around 10-12Gbps. The symptoms are that the whole tab freezes, and the shown speed drops from those 10-12Gbps to <1Gbps and the page starts updating itself only every second or so. IIRC Chrome-based browsers use some form of IPC with a separate networking process, which actually handles networking, I wonder if this might be the case that the local speed limit for socketpair/pipe under Linux was reached and that's why I'm seeing this.
- implying 4y agoFirefox is not based on the chromium codebase, it is older.
- formerly_proven 4y agoWell if we're talking ancestors that's technically true, but not by that much - Firefox comes from Netscape, Chrome/Safari/... come from KHTML.
- elpescado 4y agoAFAIR, KHTML was/is not related to Netscape/Gecko in any way.
- wodenokoto 4y ago> ... on August 16, 1999 that [Lars Knoll] had checked in what amounted to a complete rewrite of the KHTML library—changing KHTML to use the standard W3C DOM as its internal document representation. https://en.wikipedia.org/wiki/KHTML#Re-write_and_improvement https://en.wikipedia.org/wiki/KHTML#Re-write_and_improvement > In March 1998, Netscape released most of the code base for its popular Netscape Communicator suite under an open source license. The name of the application developed from this would be Mozilla, coordinated by the newly created Mozilla Organization https://en.wikipedia.org/wiki/Mozilla_Application_Suite#History_and_development https://en.wikipedia.org/wiki/Mozilla_Application_Suite#Hist... Netscape Communicator (or Netscape 4) was released in 1997, so If we are tracing lineage, I'd say Firefox has a 2 year head start.
- def- 4y agoFirefox is only Chrome-based on iOS.
- rwaksmunski 4y agoYou mean WebKit.
- karamanolev 4y agoIt's Safari-based, which is Webkit-based. Chrome is also Safari-based on iOS, because all the browsers must be. There's no actual Chrome (as in Blink, the browser engine) on iOS, at least in Play Store.
- Izkata 4y ago> It's Safari-based, which is Webkit-based. Firefox only uses Webkit on iOS, due to Apple requirements. It uses Gecko everywhere else. And I don't think it's ever been Safari-based anywhere.
- karamanolev 4y agoReplying to > Firefox is only Chrome-based on iOS. So I'm talking only about iOS. When I said it's Safari-based, I meant Webkit based, but I thought Firefox/Chrome actually pull parts of Safari on iOS. Quick research says that's wrong and they just use Webkit. Not an iOS dev, so someone can point out better sources for the 100% correct terminology.
- jve 4y agoDo you actually mean Gbit/s? 25Gb/s would translate to 200Gbit/s ...
- Denvercoder9 4y agoThe small "b" is customarily used to refer to bits, with the large "B" used to refer to bytes. So 25 Gb/s would be 25 Gbit/s, while 25 GB/s would be 200 Gbit/s.
- karamanolev 4y agoGb != GB. Per Wikipedia, which aligns with my understanding, "The gigabit has the unit symbol Gbit or Gb." 25GB/s would translate to 200Gbit/s and also 200Gb/s.
- reitanqild 4y ago> and at those speeds Chrome and Firefox (which is Chrome-based) AFAIK, Firefox is not Chrome-based anywhere. On iOS it uses whatever iOS provides for webview - as does Chrome on iOS. Firefox and Safari is now the only supported mainstream browsers that has their own rendering engines. Firefox is the only that has their own rendering engine and is cross platform. It is also open source.
- yosamino 4y ago> AFAIK, Firefox is not Chrome-based anywhere. Not technically "Chrome-based", but Firefox draws graphics using Chrome's Skia graphics engine. Firefox is not completely independent from Chrome.
- SahAssar 4y agoSkia started in 2004 independently of google and was then acquired by google. Calling it "Chrome's Skia graphics engine" makes it sound like it was built for chrome.
- deleted 4y ago[deleted]
- deleted 4y ago[deleted]
- bawolff 4y agoI feel like counting every library is silly. In any case, i thought chrome used libnss which is a mozilla library, so you could say the reverse as well.
- SahAssar 4y ago> Firefox is the only that has their own rendering engine and is cross platform. Interestingly safaris rendering engine is open source and cross platform, but the browser is not. Lots of linux-focused browsers (konquerer, gnome web, surf) and most embedded browsers (nintendo ds & switch, playstation) use webkit. Also some user interfaces (like WebOS, which is running all of LG's TVs and smart refrigerators) use webkit as their renderer.
- sph 4y agoThis makes me wonder... does anyone offer an iperf-based speedtest service on the Internet?
- scoopr 4y agoWell there are some public iperf servers listed here: https://iperf.fr/iperf-servers.php https://iperf.fr/iperf-servers.php
- r3dey3 4y agohttps://github.com/R0GGER/public-iperf3-servers https://github.com/R0GGER/public-iperf3-servers is also a good list - a couple more US servers in various datacenters
- jagrsw 4y agoHa.. my ISP does :) I can hit those 25Gb/s when connecting directly (bypassing the router as it barely handles those 25Gb/s). With it in the way I get ~15-20Gb/s $ iperf3 -l 1M --window 64M -P10 -c speedtest.init7.net .. [SUM] 0.00-1.00 sec 1.87 GBytes 16.0 Gbits/sec 181406 $ iperf3 -R -l 1M --window 64M -P10 -c speedtest.init7.net .. [SUM] 0.00-1.00 sec 2.29 GBytes 19.6 Gbits/sec
- deleted 4y ago[deleted]
- jcims 4y agoSpeedtest does have a CLI as well, might be interesting to compare them.
- jagrsw 4y agoYup, the CLI version works well - https://www.speedtest.net/result/c/e9104814-294f-4927-af9f-d466ac5f3da7 https://www.speedtest.net/result/c/e9104814-294f-4927-af9f-d...
- zrail 4y agoThing to note: the open source version on GitHub, installable by homebrew and native package managers, is not the same version as Ookla distributes from their website and is not accurate at all.
- bayindirh 4y agoChrome fires many processes and creates an IPC based comm-network between them to isolate stuff. It's somewhat abusing your OS to get what its want in terms of isolation and whatnot. (Which is similar to how K8S abuses ip-tables and makes it useless for other ends, and makes you install a dedicated firewall in front of your ingress path, but let's not digress). On the other hand, Firefox is neither chromium based, nor is a cousin of it. It's a completely different codebase, inherited from Netscape days and evolved up to this point. As another test point, Firefox doesn't even blink at a symmetric gigabit connection going at full speed (my network is capped by my NIC, the pipe is way fatter).
- jagrsw 4y ago> As another test point, Firefox doesn't even blink at a symmetric gigabit connection going at full speed (my network is capped by my NIC, the pipe is way fatter). FWIW Firefox under Linux (Firefox Browser 100.0.2 (64-bit)) behaves pretty much the same as Chrome. The speed raises quickly to 5-8Gb/s, then the UI starts choking, and the shown speed drops to 500Mb/s. It could be that there's some scheduling limit or other bottleneck hit in the OS itself, assuming these are different codebases (are they?).
- bayindirh 4y agoI'd love to test and debug the path where it dies, but none of the systems we have firefox have pipes that fat (again NIC limited). However, you can test the limits of Linux by installing CLI version of Speedtest and hitting a nearby server. The bottleneck maybe in the browser itself, or in your graphics stack, too. Linux can do pretty amazing things in the network department, otherwise 100Gbps Infiniband cards wouldn't be possible at Linux servers, yet we have them on our systems. And yes, Chrome and Firefox are way different browsers. I can confidently say this, because I'm using Firefox since it's called Netscape 6.0 (and Mozilla in Knoppix).
- bawolff 4y ago> I can confidently say this, because I'm using Firefox since it's called Netscape 6.0 (and Mozilla in Knoppix). Mozilla suite/seamonkey isn't usually considered the same as firefox, although obviously related.
- merightnow 4y agoUnrelated question, what hardware do you use to setup your network for 25Gb/s? I've been looking at init7 for a while, but gave up and stayed with Salt after trying to find the right hardware for the job.
- jagrsw 4y agoNIC: Intel E810-XXVDA2 Optics: To ISP: Flexoptics (https://www.flexoptix.net/de/p-b1625g-10-ad.html?co10426=97205 https://www.flexoptix.net/de/p-b1625g-10-ad.html?co10426=972...), Router-PC: https://mikrotik.com/product/S-3553LC20D https://mikrotik.com/product/S-3553LC20D Router: Mikrotik CCR-2004 - https://mikrotik.com/product/ccr2004_1g_12s_2xs https://mikrotik.com/product/ccr2004_1g_12s_2xs - warning: it's good to up to ~20Gb/s one way. It can handle ~25Gb/s down, but only ~18Gb/s up, and with IPv6 the max seems to be ~10Gb/s any direction. If Mikrotik is something you're comfortable using you can also take a look at https://mikrotik.com/product/ccr2216_1g_12xs_2xq https://mikrotik.com/product/ccr2216_1g_12xs_2xq - it's more expensive (~2500EUR), but should handle 25Gb/s easily.
- zrail 4y agoIIRC most Mikrotik products lack hardware IPv6 offload which is probably why you're seeing lower speeds.
- BenjiWiebe 4y agoIn that case 10Gb/s sounds actually pretty good, if that's without hardware offload.
- pca006132 4y agoIs it only affecting the browser or the entire system? It might be possible that the CPU is busy handling interrupts from the ethernet controller, although in general these controllers should use DMA and should not send interrupts frequently.
- jagrsw 4y agoOnly browser(s), the OS is capable of 25Gb/s - checked with iperf and also speedtest-cli - https://www.speedtest.net/result/c/e9104814-294f-4927-af9f-d466ac5f3da7 https://www.speedtest.net/result/c/e9104814-294f-4927-af9f-d...
- deleted 4y ago[deleted]
- Spooky23 4y agoI ran into this with a VDI environment in a data center. We had initially delivered 10Gb Ethernet to the VMs, because why not. Turned out windows 7 or the NICs needed a lot of tuning to work well. There was alot of freezing and other fail.
- deleted 4y ago[deleted]
- jcranberry 4y agoSounds like a hard drive cache filling up.
- megous 4y agoOne would assume speed testing website would use `Cache-Control: no-store`... But alas, they do not, lol. They just use no-cache on the query which will not prevent the browser from storing the data. https://megous.com/dl/tmp/8112dd9346dd66e8.png https://megous.com/dl/tmp/8112dd9346dd66e8.png
- anotherhue 4y agopv is written in perl so isn't the snappiest, I'm surprised to see it score so highly. I wonder what the initial speed would have been if it just wrote to /dev/null
- rostayob 4y agoIt's not written in perl, it's written in C, and it uses splice() (one of the syscalls discussed in the post).
- karamanolev 4y agoDefinitely C, per what appears to be the official repo (linking the splice syscall) - https://github.com/icetee/pv/blob/master/src/pv/transfer.c#L239 https://github.com/icetee/pv/blob/master/src/pv/transfer.c#L...
- anotherhue 4y agoI was totally wrong. Thank you for showing me the facts.
- merpkz 4y agoConfused with parallel, maybe?
- herodoturtle 4y agoThis was a long but highly insightful read! (And as an aside, the combination of that font with the hand-drawn diagrams is really cool)
- zabumafew 4y agoWould definitely be curious to know the font name
- herodoturtle 4y agoIt's the IBM Plex font, and they're using a combination of IBM Plex Mono, IBM Plex Serif, and IBM Plex Sans. Here is the source: https://www.ibm.com/plex/ https://www.ibm.com/plex/ Hope that helps!
- gigatexal 4y agoNow this is the kind of content I come to HN for. Absolutely fascinating read.
- stackbutterflow 4y agoThis site is pleasing to the eye.
- apostate 4y agoIt looks like it is using the "Tufte" style, named after Edward Tufte, who is very famous for his writing on data visualization. More examples: https://rstudio.github.io/tufte/ https://rstudio.github.io/tufte/
- deleted 4y ago[deleted]
- arkitaip 4y agoThe visual design is amazing.
- mg 4y agoFor some reason, this raised my curiosity how fast different languages write individual characters to a pipe: PHP comes in at about 900KiB/s: php -r 'while (1) echo 1;' | pv > /dev/null Python is about 50% faster at about 1.5MiB/s: python3 -c 'while (1): print (1, end="")' | pv > /dev/null Javascript is slowest at around 200KiB/s: node -e 'while (1) process.stdout.write("1");' | pv > /dev/null What's also interesting is that node crashes after about a minute: FATAL ERROR: Ineffective mark-compacts near heap limit Allocation failed - JavaScript heap out of memory All results from within a Debian 10 docker container with the default repo versions of PHP, Python and Node. Update: Checking with strace shows that Python caches the output: strace python3 -c 'while (1): print (1, end="")' | pv > /dev/null Outputs a series of: write(1, "11111111111111111111111111111111"..., 8193) = 8193 PHP and JS do not. So the Python equivalent would be: python3 -c 'while (1): print (1, end="", flush=True)' | pv > /dev/null Which makes it compareable to the speed of JS. Interesting, that PHP is over 4x faster than the Python and JS.
- megous 4y ago"Javascript" is slowest probably because node pushes the writes to a thread instead of printing directly from the main process like PHP. Python cheats, and it's still slow as heck even while cheating (buffers the output at 8192 chunks instead of issuing 1 byte writes). write(1, "1", 1) loop in C pushes 6.38MiB/s on my PC. :)
- cout 4y agoWhy is it cheating to use a buffer? This is the behavior you would get in C if you used the C standard library (putc/fputc) instead of a system call (write).
- megous 4y agoBecause it doesn't answer the question "how fast individual languages write individual characters to a pipe" if in fact some languages do not. It's not language "cheating" of course. It's just OP "measuring the wrong thing".
- sandGorgon 4y agoAndroid's flavor of Linux uses "binder" instead of pipes because of its security model. IMHO filesystem-based IPC mechanisms (notably pipes), can't be used because of a lack of a world-writable directory - i may be wrong here. Binder comes from Palm actually (OpenBinder)
- marcodiego 4y agoHistory of binder is more involved and has its seeds on BeOS IIRC.
- megous 4y ago"lack of a world-writable directory" What's that? A lot of programs store sockets in /run which is typically implemented by `tmpfs`.
- Matthias247 4y agoPipes don’t necessarily mean one has to use FS permissions. Eg a server could hand out anonymous pipes to authorized clients via fd passing on Unix domain sockets. The server can then implement an arbitrary permission check before doing this.
- sylware 4y agoyep, you want perf? Don't mutex then yield, do spin and check your cpu heat sink. :)
- v3gas 4y agoLove the subtle stonks background in the first image.
- deleted 4y ago[deleted]
- effnorwood 4y ago
- deleted 4y ago[deleted]
- ianai 4y agoI usually just use cat /dev/urandom > /dev/null to generate load. Not sure how this compares to their code. Edit: it’s actually “yes” that I’ve used before for generating load. I remember reading somewhere “yes” was optimized differently than the original Unix command as part of the unix certification lawsuit(s). Long night.
- yakubin 4y agoOn 5.10.0-14-amd64 "pv < /dev/urandom >/dev/null" reports 72.2MiB/s. "pv < /dev/zero >/dev/null" reports 16.5GiB/s. AMD Ryzen 7 2700X with 16GB of DDR4 3000MHz memory. "tr '\0' 1 </dev/zero | pv >/dev/null" reports 1.38GiB/s. "yes | pv >/dev/null" reports 7.26GiB/s. So "/dev/urandom" may not be the best source when testing performance.
- sumtechguy 4y agoThink they were generating load? Going through the urandom device not bad as it has to do a bit of work to get that rand number? Just for throughput though zero is prob better.
- yakubin 4y agoI don't understand. If you're testing how fast pipes are, then I'd expect you to measure throughput or latency. Why would you measure how fast something unrelated to pipes is? If you want to measure this other thing on the other hand, why would you bother with pipes, which add noise to the measurement? UPDATE: If you mean that you want to test how fast pipes are when there is other load in the system, then I'd suggest just running a lot of stuff in the background. But I wouldn't put the process dedicated for doing something else into the pipeline you're measuring. As a matter of fact, the numbers I gave were taken with plenty of heavy processes running in the background, such as Firefox, Thunderbird, a VM with another instance of Firefox, OpenVPN, etc. etc. :)
- khorne 4y agoBecause they mentioned generating load, not testing pipe performance.
- mastax 4y agoI'm glad huge pages make a big difference because I just spent several hours setting them up. Also everyone says to disable transparent_hugepage, so I set it to `madvise`, but I'm skeptical that any programs outside databases will actually use them.
- deagle50 4y agoJVM can. I have JetBrains set up to use them.
- lazide 4y agoThe majority of this overhead (and the slow transfers) naively seem to be in the scripts/systems using the pipes. I was worried when I saw zfs send/receive used pipes for instance because of performance worries - but using it in reality I had no problems pushing 800MB/s+. It seemed limited by iop/s on my local disk arrays, not any limits in pipe performance.
- Matthias247 4y agoRight. I’m actually surprised the test with 256kB transfers gives reasonable results, and would rather have tested with > 1GB instead. For such a small transfer it seemed likely that the overhead of spawning the process and loading libraries by far dominates the amount of actual work. I’m also surprised this didn’t show up in profiles. But if obviously depends on where the measurement start and end points are
- azornathogron 4y agoPerhaps I've misunderstood what you're referring to, but the test in the article is measuring speed transferring 10 GiB. 256 KiB is just the buffer size.
- Matthias247 4y agoThe first C program in the blog post allocates a 256kB buffer and writes that one exactly once to stdout. I don't see another loop which writes it multiple times.
- azornathogron 4y agoThere's an outer while(true){} loop - the write side just writes continuously. More generally though, sidenote 5 says that the code in the article itself is incomplete and the real test code is available in the github repo: https://github.com/bitonic/pipes-speed-test https://github.com/bitonic/pipes-speed-test
- alex_hirner 4y agoDoes an API similar to vmsplice exist for Windows?
- Klasiaster 4y agoNetmap offers zero-copy pipes (included in FreeBSD, on Linux it's a third party module): https://www.freebsd.org/cgi/man.cgi?query=netmap&sektion=4 https://www.freebsd.org/cgi/man.cgi?query=netmap&sektion=4
- BeeOnRope 4y agoThis is a well-written article with excellent explanations and I thoroughly enjoyed it. However, none of the variants using vmsplice (i.e., all but the slowest) are safe. When you gift [1] pages to the kernel there is no reliable general purpose way to know when the pages are safe to reuse again. This post (and the earlier FizzBuzz variant) try to get around this by assuming the pages are available again after "pipe size" bytes have been written after the gift, _but this is not true in general_. For example, the read side may also use splice-like calls to move the pages to another pipe or IO queue in zero-copy way so the lifetime of the page can extend beyond the original pipe. This will show up as race conditions and spontaneously changing data where a downstream consumer sees the page suddenly change as it it overwritten by the original process. The author of these splice methods, Jens Axboe, had proposed a mechanism which enabled you to determine when it was safe to reuse the page, but as far as I know nothing was ever merged. So the scenarios where you can use this are limited to those where you control both ends of the pipe and can be sure of the exact page lifetime. --- [1] Specifically, using SPLICE_F_GIFT.
- rostayob 4y ago(I am the author of the post) I haven't digested this comment fully yet, but just to be clear, I am _not_ using SPLICE_F_GIFT (and I don't think the fizzbuzz program is either). However I think what you're saying makes sense in general, SPLICE_F_GIFT or not. Are you sure this unsafety depends on SPLICE_F_GIFT? Also, do you have a reference to the discussions regarding this (presumably on LKML)?
- BeeOnRope 4y agoYeah my mention of gift was a red herring: I had assumed gift was being used but the same general problem (the "page garbage collection issue") crops up regardless. If you don't use gift, you never know when the pages are free to use again, so in principle you need to keep writing to new buffers indefinitely. One "solution" to this problem is to gift the pages, in which case the kernel does the GC for you, but you need to churn through new pages constantly because you've gifted the old ones. Gift is especially useful when the page gifted can be used directly in the page cache (i.e., writing a file, not a pipe). Without gift some consumption patterns may be safe but I think they are exactly those which involve a copy (not using gift means that a copy will occur for additional read-side scenarios). Ultimately the problem is that if some downstream process is able to get a zero-copy view of a page from an upstream writer, how can this be safe to concurrently modification? The pipe size trick is one way it could work, but it doesn't pan out because the pages may live beyond the immediately pipe (this is actually alluded in the FizzBuzz article where they mentioned things blew up if more than one pipe was involved).
- nice2meetu 4y agoI once had to change my mental model for how fast some of these things were. I was using `seq` as an input for something else, and my thinking was along the lines that it is a small generator program running hot in the cpu and would be super quick. Specifically because it would only be writing things out to memory for the next program to consume, not reading anything in. But that was way off and `seq` turned out to be ridiculously slow. I dug down a little and made a faster version of `seq`, that kind of got me what I wanted. But then noticed at the end that the point was moot anyway, because just piping it to the next program over the command line was going to be the slow point, so it didn't matter anyway. https://github.com/tverniquet/hseq https://github.com/tverniquet/hseq
- freedomben 4y agoI had a somewhat similar discovery once using GNU parallel. I was trying to generate as much web traffic as possible from a single machine to load test a service I was building, and I assumed that the network I/o would be the bottleneck by a long shot, not the overhead of spawning many processes. I was disappointed by the amount of traffic generated, so I rewrote it in Ruby using the parallel gem with threads (instead of processes), and got orders of magnitude more performance.
- strictfp 4y agoNode is great for this usecase
- bfors 4y agoLove the subtle "stonks" overlay on the first chart
- spacedcowboy 4y agoRan the basic initial implementation on my Mac Studio and was pleasantly surprised to see @elysium pipetest % pipetest | pv > /dev/null 102GiB 0:00:13 [8.00GiB/s] @elysium ~ % pv < /dev/zero > /dev/null 143GiB 0:00:04 [36.4GiB/s] Not a valid comparison between the two machines because I don't know what the original machine is, but MacOS rarely comes out shining in this sort of comparison, and the simplistic approach here giving 8 GB/s rather than the author's 3.5 GB/s was better than I'd expected, even given the machine I'm using.
- mhh__ 4y agoGiven the machine as in a brand new Mac?
- spacedcowboy 4y agogiven that the machine is the most performant Mac that Apple make.
- Cloudef 4y agoI've dumped pixels and pcm audio through a pipe, it certainly was fast enough for that https://git.cloudef.pw/glcapture.git/tree/glcapture.c https://git.cloudef.pw/glcapture.git/tree/glcapture.c (I suggest gamescope + pipewire to do this instead nowadays however)
- Maursault 4y agoLinux pipes? Oh yes, Linux pipes were invented by Douglas McIlroy while working for Bell Labs on Research UNIX and first described in the man pages of Version 3 Unix, Feb. 1974, just a couple months after Linus Torvald's 4th birthday. Where and how and when will the unjust and blatent plagiarism of Linux cease? The software was made free by BSD, so feel free to use it, roll it all into GNU/Linux, have at it, but please stop incorrectly describing these things as Linux things. Because the only software that I am certain actually belongs to Linux is systemd. So let's start calling that "Linux systemd," and stop calling anything else Linux anything.
- NobodyNada 4y ago> In this post, we will explore how Unix pipes are implemented in Linux Seems to me like this post is pretty specifically about Unix pipes on Linux (i.e. Linux pipes), as opposed to Unix pipes in general. The article also talks about “Linux paging”, again clearly referring to the implementation and usage of virtual memory on Linux, rather than…whatever ancient architecture first invented the page table.
- Maursault 4y agoThis would be valid, but only if the implementation of pipes in Linux is different than other pipelines, regardless of differences in memory paging, which the article, as detailed and in depth as it is, never makes clear. So I'm not sure it is not analogous to, "today, we're going to talk about Linux electricity, specifically the way electricity is utilized in Linux."
- hampereddustbin 4y agoWhen you have multiple ways to interpret what someone says, it's generally a good idea to assume best intentions. In this case Linux pipes would then refer to pipes in Linux, rather than implied ownership or origin. This avoids a lot of unnecessary squabbling
- Maursault 4y agoSo pipes in Linux are significantly different than other pipelines? Was the wheel really reinvented when Linux was developed from Minux, such that the Minix pipeline implementation was abandoned? RLY??! I doubt it.
- mrtweetyhack 4y ago