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

fix(SendMessage): use SendStream::set_writable_event_low_watermark #1838

Merged
merged 22 commits into from
May 7, 2024

Conversation

mxinden
Copy link
Collaborator

@mxinden mxinden commented Apr 17, 2024

Previously SendMessage::send_data could stall, if less than the minimum message size is available to be sent. See
#1819 for details.

This commit implements solution (3) proposed in
#1819.

This commit introduces SendStream::set_writable_event_low_watermark which is then used in SendMessage::send_data to signal to SendStream the minimum required send space (low watermark) for the next send. Once reached, SendStream emits a SendStreamWritable event, eventually triggering another SendMessage::send_data.

Alternative to #1835. Compared to #1835, this fix does not utilize the SendMessage buffer, thus does not introduce an indirection to the send path. In addition, under the assumption that available send space is increased in larger batches, this fix does not send tiny data frames (2 byte header, 1 byte goodput). Downside, compared to #1835, is that it requires both changes in neqo-transport and neqo-http3.

Fixes #1819.

Secondarily, this fixes #1821 as well.


Thank you Martin and Lars for the input on #1819 out-of-band.

Previously `SendMessage::send_data` could stall, if less than the minimum
message size is available to be sent. See
mozilla#1819 for details.

This commit implements solution (3) proposed in
mozilla#1819.

This commit introduces `SendStream::set_writable_event_low_watermark` which is
then used in `SendMessage::send_data` to signal to `SendStream` the minimum
required send space (low watermark) for the next send. Once reached,
`SendStream` emits a `SendStreamWritable` eventually triggering another
`SendMessage::send_data`.

Alternative to mozilla#1835. Compared to
mozilla#1835, this fix does not utilize the
`SendMessage` buffer, thus does not introduce an indirection to the send path.
In addition, under the assumption that available send space is increased in
larger batches, this fix does not send tiny data frames (2 byte header, 1 byte
goodput). Downside, compared to mozilla#1835, is
that it requires both changes in `neqo-transport` and `neqo-http3`.

Secondarily, this fixes mozilla#1821 as well.
Copy link

github-actions bot commented Apr 19, 2024

Benchmark results

Performance differences relative to ed19eb2.

  • drain a timer quickly time: [310.25 ns 318.38 ns 325.73 ns]
    change: [-2.1870% +0.0832% +2.3375%] (p = 0.94 > 0.05)
    No change in performance detected.

  • coalesce_acked_from_zero 1+1 entries
    time: [196.52 ns 197.00 ns 197.48 ns]
    change: [-1.4157% -1.0415% -0.6943%] (p = 0.00 < 0.05)
    Change within noise threshold.

  • coalesce_acked_from_zero 3+1 entries
    time: [238.43 ns 239.09 ns 239.82 ns]
    change: [-0.9587% -0.2838% +0.9034%] (p = 0.64 > 0.05)
    No change in performance detected.

  • coalesce_acked_from_zero 10+1 entries
    time: [238.19 ns 239.06 ns 240.09 ns]
    change: [-1.3212% -0.6122% +0.1552%] (p = 0.12 > 0.05)
    No change in performance detected.

  • coalesce_acked_from_zero 1000+1 entries
    time: [218.59 ns 218.87 ns 219.30 ns]
    change: [+0.3808% +0.8805% +1.3393%] (p = 0.00 < 0.05)
    Change within noise threshold.

  • RxStreamOrderer::inbound_frame()
    time: [119.32 ms 119.39 ms 119.47 ms]
    change: [+0.1823% +0.2668% +0.3583%] (p = 0.00 < 0.05)
    Change within noise threshold.

  • transfer/Run multiple transfers with varying seeds
    time: [118.69 ms 118.95 ms 119.21 ms]
    thrpt: [33.555 MiB/s 33.627 MiB/s 33.702 MiB/s]
    change:
    time: [-1.4636% -1.1383% -0.8246%] (p = 0.00 < 0.05)
    thrpt: [+0.8314% +1.1514% +1.4854%]
    Change within noise threshold.

  • transfer/Run multiple transfers with the same seed
    time: [118.79 ms 119.01 ms 119.23 ms]
    thrpt: [33.548 MiB/s 33.610 MiB/s 33.672 MiB/s]
    change:
    time: [-1.6752% -1.4107% -1.1425%] (p = 0.00 < 0.05)
    thrpt: [+1.1557% +1.4309% +1.7038%]
    Change within noise threshold.

  • 1-conn/1-100mb-resp (aka. Download)/client
    time: [1.1134 s 1.1194 s 1.1261 s]
    thrpt: [88.802 MiB/s 89.331 MiB/s 89.814 MiB/s]
    change:
    time: [+1.4059% +2.1857% +2.9635%] (p = 0.00 < 0.05)
    thrpt: [-2.8782% -2.1389% -1.3864%]
    💔 Performance has regressed.

  • 1-conn/10_000-parallel-1b-resp (aka. RPS)/client
    time: [428.00 ms 430.25 ms 432.54 ms]
    thrpt: [23.120 Kelem/s 23.242 Kelem/s 23.364 Kelem/s]
    change:
    time: [-0.0254% +0.6971% +1.4164%] (p = 0.06 > 0.05)
    thrpt: [-1.3966% -0.6923% +0.0254%]
    No change in performance detected.

  • 1-conn/1-1b-resp (aka. HPS)/client
    time: [49.442 ms 49.645 ms 49.847 ms]
    thrpt: [20.061 elem/s 20.143 elem/s 20.226 elem/s]
    change:
    time: [-2.1138% -1.3873% -0.7582%] (p = 0.00 < 0.05)
    thrpt: [+0.7640% +1.4068% +2.1594%]
    Change within noise threshold.

Client/server transfer results

Transfer of 134217728 bytes over loopback.

Client Server CC Pacing Mean [ms] Min [ms] Max [ms] Relative
msquic msquic 629.0 ± 245.1 395.9 1045.8 1.00
neqo msquic reno on 1133.8 ± 325.1 781.8 1693.4 1.00
neqo msquic reno 957.4 ± 182.2 751.8 1211.5 1.00
neqo msquic cubic on 951.2 ± 228.0 742.5 1378.1 1.00
neqo msquic cubic 959.8 ± 229.5 766.8 1377.8 1.00
msquic neqo reno on 4374.4 ± 258.4 4085.0 4908.0 1.00
msquic neqo reno 4373.9 ± 260.0 4062.7 4881.5 1.00
msquic neqo cubic on 4451.5 ± 188.4 4166.9 4723.9 1.00
msquic neqo cubic 4435.4 ± 344.9 4080.9 5110.2 1.00
neqo neqo reno on 3618.4 ± 397.0 2891.4 4215.0 1.00
neqo neqo reno 3654.1 ± 347.6 3251.7 4334.8 1.00
neqo neqo cubic on 4191.1 ± 586.5 2988.7 4870.0 1.00
neqo neqo cubic 4184.3 ± 230.8 3891.8 4602.3 1.00

⬇️ Download logs

neqo-http3/src/server_events.rs Show resolved Hide resolved
neqo-transport/src/send_stream.rs Outdated Show resolved Hide resolved
neqo-transport/src/send_stream.rs Outdated Show resolved Hide resolved
neqo-transport/src/send_stream.rs Outdated Show resolved Hide resolved
Copy link

codecov bot commented Apr 22, 2024

Codecov Report

All modified and coverable lines are covered by tests ✅

Project coverage is 93.26%. Comparing base (17c45d8) to head (2bc3e78).
Report is 5 commits behind head on main.

Additional details and impacted files
@@            Coverage Diff             @@
##             main    #1838      +/-   ##
==========================================
- Coverage   93.27%   93.26%   -0.02%     
==========================================
  Files         110      110              
  Lines       35793    35864      +71     
==========================================
+ Hits        33387    33448      +61     
- Misses       2406     2416      +10     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

Copy link
Collaborator

@larseggert larseggert left a comment

Choose a reason for hiding this comment

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

LGTM but I would like @KershawChang or @martinthomson to also take a look.

Should we see a performance increase in the benchmarks?

neqo-http3/src/send_message.rs Outdated Show resolved Hide resolved
Copy link

github-actions bot commented Apr 23, 2024

Failed Interop Tests

QUIC Interop Runner, client vs. server

All results

Succeeded Interop Tests

QUIC Interop Runner, client vs. server

Unsupported Interop Tests

QUIC Interop Runner, client vs. server

Copy link
Collaborator

@KershawChang KershawChang left a comment

Choose a reason for hiding this comment

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

Overall looks good, but it'd be good to see @martinthomson 's comment on this.

neqo-transport/src/send_stream.rs Outdated Show resolved Hide resolved
@larseggert
Copy link
Collaborator

Overall looks good, but it'd be good to see @martinthomson 's comment on this.

Which of his comments? (I can't seem to find one on this PR.)

@KershawChang
Copy link
Collaborator

Overall looks good, but it'd be good to see @martinthomson 's comment on this.

Which of his comments? (I can't seem to find one on this PR.)

Sorry for any confusion. I assumed that Martin would add his review comments to this change. I'd like him to have a look as well.

@mxinden
Copy link
Collaborator Author

mxinden commented Apr 23, 2024

Should we see a performance increase in the benchmarks?

Intuitively yes, especially since it fixes #1821 along the way, i.e. neqo-transport no longer emits a DataWritable event each time it receives an ACK.

Running the 1-conn/1-100mb-resp (aka. Download) benchmark locally results in ~275 DataWritable events with this patch and ~5_000 DataWritable events without this patch. In other words this patch significantly reduces wake-ups due to new (and mostly duplicate) events and thus significantly reduces subsequent unnecessary calls to SendMessage::send_data.

That said, as you say, the benchmarks show a regression:

  • 1-conn/1-100mb-resp (aka. Download)/client
    time: [1.1417 s 1.1482 s 1.1547 s]
    thrpt: [86.601 MiB/s 87.094 MiB/s 87.586 MiB/s]
    change:
    time: [+4.5106% +5.2617% +6.0179%] (p = 0.00 < 0.05)
    thrpt: [-5.6763% -4.9987% -4.3159%]
    💔 Performance has regressed.

I don't have a good understanding why yet. Also I don't know how representative this benchmark currently is with neqo_transport::Server::timers back in place (#1801).

@mxinden
Copy link
Collaborator Author

mxinden commented Apr 24, 2024

  • 1-conn/1-100mb-resp (aka. Download)/client
    time: [1.1039 s 1.1187 s 1.1413 s]
    thrpt: [87.618 MiB/s 89.387 MiB/s 90.586 MiB/s]
    change:
    time: [-2.7683% -0.3963% +2.0928%] (p = 0.78 > 0.05)
    thrpt: [-2.0499% +0.3979% +2.8471%]
    No change in performance detected.

Consecutive run no longer shows a regression. Not a performance proof for this patch, but rather another datapoint that the benchmark is unreliable.

@larseggert
Copy link
Collaborator

Holding off until @martinthomson has reviewed.

Copy link
Member

@martinthomson martinthomson left a comment

Choose a reason for hiding this comment

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

I think that I found a problem with the code that will necessitate some changes.

neqo-http3/src/send_message.rs Outdated Show resolved Hide resolved
neqo-http3/src/send_message.rs Outdated Show resolved Hide resolved
neqo-http3/tests/httpconn.rs Outdated Show resolved Hide resolved
neqo-http3/tests/httpconn.rs Outdated Show resolved Hide resolved
neqo-transport/src/send_stream.rs Outdated Show resolved Hide resolved
neqo-transport/src/send_stream.rs Outdated Show resolved Hide resolved
neqo-transport/src/send_stream.rs Outdated Show resolved Hide resolved
neqo-transport/src/send_stream.rs Outdated Show resolved Hide resolved
neqo-transport/src/send_stream.rs Show resolved Hide resolved
@mxinden
Copy link
Collaborator Author

mxinden commented May 2, 2024

All review comments addressed. I still need to look into the current test failures.

@martinthomson
Copy link
Member

Ping me when you sort out the test failures. The code looks fine, but you might have changed test conditions.

@mxinden
Copy link
Collaborator Author

mxinden commented May 3, 2024

@martinthomson test failure was due to a simple double borrow attempt. See 8d66880. Ready to merge now.

@martinthomson martinthomson enabled auto-merge May 5, 2024 23:52
@mxinden
Copy link
Collaborator Author

mxinden commented May 6, 2024

image

@martinthomson in case your intention was to merge here: I think you will have to resolve your previous request for change.

@larseggert larseggert requested a review from martinthomson May 6, 2024 13:53
@martinthomson martinthomson added this pull request to the merge queue May 7, 2024
Merged via the queue into mozilla:main with commit bb88aab May 7, 2024
47 checks passed
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.

http3::SendMessage::send_data can stall
4 participants