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

[mplex] Add benchmark, tweak default split_send_size. #1834

Merged
merged 5 commits into from
Nov 16, 2020

Conversation

romanb
Copy link
Contributor

@romanb romanb commented Nov 12, 2020

This PR supersedes #802. It includes a benchmark that sends and receives 1MiB of data via TCP and memory transports with varying choices for the split_send_size. Always using the plaintext protocol for "authentication". Typical results from my side look as follows:

tcp/256                 time:   [1.3490 ms 1.3550 ms 1.3619 ms]  
tcp/512                 time:   [1.0430 ms 1.0493 ms 1.0563 ms]                     
tcp/1024                time:   [788.28 us 792.05 us 795.92 us]                     
tcp/8192                time:   [609.95 us 614.46 us 619.14 us]                     
tcp/16384               time:   [586.30 us 592.73 us 600.07 us]                      
tcp/65536               time:   [571.13 us 575.46 us 580.18 us]                      
tcp/262144              time:   [587.14 us 593.29 us 599.73 us]                       
tcp/1048576             time:   [2.1731 ms 2.2119 ms 2.2529 ms]                         

memory/256              time:   [1.2023 ms 1.2125 ms 1.2231 ms]                        
memory/512              time:   [723.83 us 730.71 us 738.00 us]                       
memory/1024             time:   [466.72 us 471.63 us 477.29 us]                        
memory/8192             time:   [289.08 us 293.97 us 299.65 us]                        
memory/16384            time:   [270.09 us 274.39 us 278.91 us]                         
memory/65536            time:   [248.38 us 254.62 us 261.55 us]                         
memory/262144           time:   [273.51 us 281.88 us 290.79 us]    

Based on such numbers, and probably not surprisingly, 8KiB seems to be a good default, as it also is the buffer size of the underlying Framed codec. Hence this PR changes the default from 1KiB to 8KiB.

With both TCP and memory transports. As a result, change the
default `split_send_size` to 8KiB.
Copy link
Member

@mxinden mxinden left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am in favor of the data driven approach.

split_send_size limits the maximum amount of data a substream can send in one go. Do I understand correctly that the underlying motivation for this mechanism is to control the amount of latency a substream can induce on another substream, by enforcing interleaving at a certain packet size?

muxers/mplex/benches/split_send_size.rs Show resolved Hide resolved
@romanb
Copy link
Contributor Author

romanb commented Nov 15, 2020

Do I understand correctly that the underlying motivation for this mechanism is to control the amount of latency a substream can induce on another substream, by enforcing interleaving at a certain packet size?

As far as I'm concerned, the motivation is not primarily better interleaving of substream write operations, though that may be a side-effect. My reasoning here is two-fold:

  1. We want to scope a single substream write to writing of a single Mplex frame. A single frame cannot be arbitrarily large, the maximum is 1MiB per the spec. We don't want to return errors when a write operation tries to write more than that but rather write as much as we can, so the given data to write needs to be cut somewhere.
  2. We could always cut at 1MiB, i.e. trying to always produce maximally sized frames (to compare, I think yamux does so w.r.t. the remaining window size, which is up to 256KiB by default). However, it does not seem to be beneficial to take 1MiB-sized "bites" from the input if it then immediately needs to be broken down into smaller chunks which themselves need to be potentially buffered again in intermediate layers, which I think is what happens in the underlying Framed (8KiB default buffer size that grows / allocates as necessary) and further down the TCP stack. I couldn't get too much out of the flamegraphs I shortly looked at, but I think this is at least part of the reason why the benchmark deteriorates again with larger Mplex frame sizes towards 1MiB.

Copy link
Member

@mxinden mxinden left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for drawing the bigger picture. This looks good to me.

@romanb romanb merged commit 41d3f72 into libp2p:master Nov 16, 2020
@romanb romanb deleted the mplex-bench branch November 16, 2020 16:41
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants