]> git.ipfire.org Git - thirdparty/haproxy.git/commit
OPTIM: mux-h2: call h2_send() directly from h2_snd_buf()
authorWilly Tarreau <w@1wt.eu>
Sat, 4 Nov 2023 07:34:23 +0000 (08:34 +0100)
committerWilly Tarreau <w@1wt.eu>
Sat, 4 Nov 2023 07:34:23 +0000 (08:34 +0100)
commite16762f8a886361b0657ecf6dac038e316b5ab73
tree5fc938ac6a7d202f4b9adcb02594a0ef810499b2
parent0fa5adee3bb17814b80ddfb5e07f5e219efcfebd
OPTIM: mux-h2: call h2_send() directly from h2_snd_buf()

This allows to eliminate full buffers very quickly and to recycle them
much faster, resulting in higher transfer rates and lower memory usage
at the same time. We just wake the tasklet up if it succeeded so that
h2_process() and friends are called to finalize what needs to.

For regular buffer sizes, the performance level becomes quite close to
the one obtained with the zero-copy mechanism (zero-copy remains much
faster with non-default buffer sizes). The memory savings are huge with
default buffer size: at 64c * 100 streams on a single thread, we used
to forward 4.4 Gbps of traffic using 10400 buffers. After the change,
the performance reaches 5.9 Gbps with only 22-24 buffers, since they
are quickly recycled. That's asaving of 160 MB of RAM.

A concern was an increase in the number of syscalls but this is not
the case, the numbers remained exactly the same before and after.

Some experimentations were made to try to cork data and not send
incomplete buffers, and that always voided these changes. One
explanation might be that keeping a first buffer with only headers
frames is sufficient to prevent a zero-copy of the data coming in
a next snd_buf() call. This still needs to be studied anyway.
src/mux_h2.c