As another data point, I decided to test a few implementations of http2 
downloads on OSX.

Using a Go server with default frame size (16k):

Go client:  900 MB/s
Java client: 1300 MB/s
curl: 1500 MB/s

Using a Java server with default frame size (16k):

Go client: 670 MB/s
Java client: 720 MB/s
curl: 800 M/s

Using Go server using 256k client max frame size:

Go client: 2350 MB/s
Java client: 2800 MB/s
h2load: 4300 MB/s

Using Java server using 256k client max frame size:

Go client: 2900 MB/s
Java client: 2800 MB/s
h2load: 3750 MB/s

For h2load, I needed to create a PR to allow the frame size to be set, see 
https://github.com/nghttp2/nghttp2/pull/1640


> On Nov 10, 2021, at 7:04 PM, robert engels <reng...@ix.netcom.com> wrote:
> 
> No worries. I updated the issue and the CL. I will comment in the CL with a 
> few more details.
> 
>> On Nov 10, 2021, at 2:30 PM, Andrey T. <xnow4fippy...@sneakemail.com 
>> <mailto:xnow4fippy...@sneakemail.com>> wrote:
>> 
>> Thank you Robert, 
>> I somehow missed the reference to the ticket in the first message, sorry 
>> about that.
>> 
>> As for the CL - I think adding link to the github issue, and add a bit of 
>> explanation in a commit message would help.
>> I added link to your CL to the github issue's discussion, hopefully it will 
>> bring more attention to it. 
>> 
>> A.
>> 
>> On Wednesday, November 10, 2021 at 1:22:42 PM UTC-7 ren...@ix.netcom.com 
>> <http://ix.netcom.com/> wrote:
>> As reported in the OP, the issue was filed long ago 
>> https://github.com/golang/go/issues/47840 
>> <https://github.com/golang/go/issues/47840>
>> 
>> My CL https://go-review.googlesource.com/c/net/+/362834 
>> <https://go-review.googlesource.com/c/net/+/362834> is a viable fix (and 
>> should of been supported originally).
>> 
>> 
>>> On Nov 10, 2021, at 12:59 PM, Andrey T. <xnow4f...@sneakemail.com 
>>> <applewebdata://11DC8BA4-6589-42F5-BBFD-BE3933D9DE20>> wrote:
>>> 
>> 
>>> Fellas, 
>>> I would say the 5x throughput difference is a serious problem.Would you be 
>>> kind and open an issue on github about it? 
>>> Also, the PR that you have might benefit from explanation about what you 
>>> are trying to solve (and probably link to an issue on github), so it would 
>>> get more attention. 
>>> 
>>> Thanks!
>>> 
>>> Andrey
>>> 
>>> 
>>> On Tuesday, November 9, 2021 at 4:50:34 PM UTC-7 ren...@ix.netcom.com 
>>> <http://ix.netcom.com/> wrote:
>>> Well, I figured out a way to do it simply. The CL is here 
>>> https://go-review.googlesource.com/c/net/+/362834 
>>> <https://go-review.googlesource.com/c/net/+/362834>
>>> 
>>> The frame size will be used for all connections using that transport, so it 
>>> is probably better to create a transport specifically for the 
>>> high-throughput transfers.
>>> 
>>> You can also create perform single shot requests like:
>>> 
>>> if useH2C {
>>>    rt = &http2.Transport{
>>>       AllowHTTP: true,
>>>       DialTLS: func(network, addr string, cfg *tls.Config) (net.Conn, 
>>> error) {
>>>          return dialer.Dial(network, addr)
>>>       },
>>>       MaxFrameSize: 1024*256,
>>>    }
>>> }
>>> 
>>> var body io.ReadCloser = http.NoBody
>>> 
>>> req, err := http.NewRequestWithContext(ctx, "GET", url, body)
>>> if err != nil {
>>>    return err
>>> }
>>> 
>>> resp, err := rt.RoundTrip(req)
>>> 
>>> 
>>>> On Nov 9, 2021, at 3:31 PM, Robert Engels <ren...@ix.netcom.com <>> wrote:
>>>> 
>>>> To be clear, I have no plans to submit a Cl to improve this at this time. 
>>>> 
>>>> It would require some api changes to implement properly. 
>>>> 
>>>>> On Nov 9, 2021, at 12:19 PM, Kirth Gersen <kirth...@gmail.com <>> wrote:
>>>>> 
>>>>> Great !
>>>>> 
>>>>> > I made some local mods to the net library, increasing the frame size to 
>>>>> > 256k, and the http2 performance went from 8Gbps to 38Gbps.
>>>>> That is already enormous for us. thx for finding this.
>>>>> 
>>>>> 4 -> Indeed  a lot of WINDOW_UPDATE messages are visible when using 
>>>>> GODEBUG=http2debug=1 
>>>>> 
>>>>> 
>>>>> On Tuesday, November 9, 2021 at 6:28:16 PM UTC+1 ren...@ix.netcom.com 
>>>>> <http://ix.netcom.com/> wrote:
>>>>> 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 <kirth...@ <>gmail.com 
>>>>>> <http://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...@ <>googlegroups.com 
>>>>>> <http://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...@googlegroups.com <>.
>>>>> To view this discussion on the web visit 
>>>>> https://groups.google.com/d/msgid/golang-nuts/7332f727-6716-4c4d-85c5-a86cacd0c89fn%40googlegroups.com
>>>>>  
>>>>> <https://groups.google.com/d/msgid/golang-nuts/7332f727-6716-4c4d-85c5-a86cacd0c89fn%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...@googlegroups.com 
>>> <applewebdata://11DC8BA4-6589-42F5-BBFD-BE3933D9DE20>.
>> 
>>> To view this discussion on the web visit 
>>> https://groups.google.com/d/msgid/golang-nuts/1bfe6aec-abd2-4f63-bf77-bbfa6fd213ban%40googlegroups.com
>>>  
>>> <https://groups.google.com/d/msgid/golang-nuts/1bfe6aec-abd2-4f63-bf77-bbfa6fd213ban%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 
>> <mailto:golang-nuts+unsubscr...@googlegroups.com>.
>> To view this discussion on the web visit 
>> https://groups.google.com/d/msgid/golang-nuts/1b63863b-45af-45d0-a885-8716acc65ac7n%40googlegroups.com
>>  
>> <https://groups.google.com/d/msgid/golang-nuts/1b63863b-45af-45d0-a885-8716acc65ac7n%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/4558357B-4022-46DC-8AE6-EBEDDC441B6D%40ix.netcom.com.

Reply via email to