I did a review of the codebase.

Http2 is a multiplexed protocol with independent streams. The Go implementation 
uses a common reader thread/routine to read all of the connection content, and 
then demuxes the streams and passes the data via pipes to the stream readers. 
This multithreaded nature requires the use of locks to coordinate. By managing 
the window size, the connection reader should never block writing to a steam 
buffer - but a stream reader may stall waiting for data to arrive - get 
descheduled - only to be quickly rescheduled when reader places more data in 
the buffer - which is inefficient.

Out of the box on my machine, http1 is about 37 Gbps, and http2 is about 7 Gbps 
on my system.

Some things that jump out:

1. The chunk size is too small. Using 1MB pushed http1 from 37 Gbs to 50 Gbps, 
and http2 to 8 Gbps.

2. The default buffer in io.Copy() is too small. Use io.CopyBuffer() with a 
larger buffer - I changed to 4MB. This pushed http1 to 55 Gbs, and http2 to 
8.2. Not a big difference but needed for later.

3. The http2 receiver frame size of 16k is way too small. There is overhead on 
every frame - the most costly is updating the window.

I made some local mods to the net library, increasing the frame size to 256k, 
and the http2 performance went from 8Gbps to 38Gbps.

4. I haven’t tracked it down yet, but I don’t think the window size update code 
is not working as intended - it seems to be sending window updates (which are 
expensive due to locks) far too frequently. I think this is the area that could 
use the most improvement - using some heuristics there is the possibility to 
detect the sender rate, and adjust the refresh rate (using high/low water 
marks).

5. The implementation might need improvements using lock-free structures, 
atomic counters, and busy-waits in order to achieve maximum performance.

So 38Gbps for http2 vs 55 Gbps for http1. Better but still not great. Still, 
with some minor changes, the net package could allow setting of a large frame 
size on a per stream basis - which would enable much higher throughput. The 
gRPC library allows this.

> On Nov 8, 2021, at 10:58 AM, Kirth Gersen <kirthal...@gmail.com> wrote:
> 
> http/2 implementation seems ~5x slower in bytes per seconds (when transfer is 
> cpu capped).
> 
> POC: https://github.com/nspeed-app/http2issue 
> <https://github.com/nspeed-app/http2issue>
> 
> I submitted an issue about this 3 months ago in the Go Github ( 
> https://github.com/golang/go/issues/47840 
> <https://github.com/golang/go/issues/47840> ) but first commenter 
> misunderstood it and it got buried (they're probably just swamped with too 
> many open issues (5k+...)).
> 
> Everything using Golang net/http is impacted, the Caddy web server for 
> instance.
> 
> I know it probably doesn't matter for most use cases because it's only 
> noticeable with high throughput transfers (>1 Gbps). 
> Most http benchmarks focus on "requests per second" and not "bits per 
> seconds" but this performance matters too sometimes.
> 
> If anyone with expertise in profiling Go code and good knowledge of the 
> net/http lib internal could take a look. It would be nice to optimize it or 
> at least have an explanation.
> 
> thx (sorry if wrong  group to post this).
> 
> -- 
> You received this message because you are subscribed to the Google Groups 
> "golang-nuts" group.
> To unsubscribe from this group and stop receiving emails from it, send an 
> email to golang-nuts+unsubscr...@googlegroups.com 
> <mailto:golang-nuts+unsubscr...@googlegroups.com>.
> To view this discussion on the web visit 
> https://groups.google.com/d/msgid/golang-nuts/89926c2f-ec73-43ad-be49-a8bc76a18345n%40googlegroups.com
>  
> <https://groups.google.com/d/msgid/golang-nuts/89926c2f-ec73-43ad-be49-a8bc76a18345n%40googlegroups.com?utm_medium=email&utm_source=footer>.

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/AB3F7933-45CC-4C83-8B7B-D1DF6D609546%40ix.netcom.com.

Reply via email to