mirror of
http://git.haproxy.org/git/haproxy.git/
synced 2025-01-12 16:59:48 +00:00
MEDIUM: mux-h1: avoid a double copy on the Tx path whenever possible
In order to properly deal with unaligned contents, the output data are currently copied into a temporary buffer, to be copied into the mux's output buffer at the end. The new buffer API allows several buffers to share the same data area, so we're using this here to make the temporary buffer point to the same area as the output buffer when that one is empty. This is enough to avoid the copy at the end, only pointers and lengths have to be adjusted. In addition the output buffer's head is advanced by the HTX header size so that the remaining copy is aligned. By doing this we improve the large object performance by an extra 10%, which is 64% above the 1.9-dev9 state. It's worth noting that there are no more calls to __memcpy_sse2_unaligned() now. Since this code deals with various block types, it appears difficult to adjust it to be smart enough to even avoid the first copy. However a distinct approach could consist in trying to detect a single blocked HTX and jump to dedicated code in this case.
This commit is contained in:
parent
78f548f49e
commit
c5efa33021
17
src/mux_h1.c
17
src/mux_h1.c
@ -1326,6 +1326,15 @@ static size_t h1_process_output(struct h1c *h1c, struct buffer *buf, size_t coun
|
||||
|
||||
|
||||
tmp = get_trash_chunk();
|
||||
|
||||
/* pre-align the output buffer like the HTX in case it's empty. In this
|
||||
* case since it's aligned we don't need to use the temporary trash.
|
||||
*/
|
||||
if (!b_data(&h1c->obuf)) {
|
||||
h1c->obuf.head = sizeof(struct htx);
|
||||
tmp->area = h1c->obuf.area + h1c->obuf.head;
|
||||
}
|
||||
|
||||
tmp->size = b_room(&h1c->obuf);
|
||||
|
||||
blk = htx_get_head_blk(chn_htx);
|
||||
@ -1472,7 +1481,13 @@ static size_t h1_process_output(struct h1c *h1c, struct buffer *buf, size_t coun
|
||||
}
|
||||
|
||||
copy:
|
||||
b_putblk(&h1c->obuf, tmp->area, tmp->data);
|
||||
/* when the output buffer is empty, tmp shares the same area so that we
|
||||
* only have to update pointers and lengths.
|
||||
*/
|
||||
if (tmp->area == h1c->obuf.area)
|
||||
h1c->obuf.data = tmp->data;
|
||||
else
|
||||
b_putblk(&h1c->obuf, tmp->area, tmp->data);
|
||||
|
||||
if (!buf_room_for_htx_data(&h1c->obuf))
|
||||
h1c->flags |= H1C_F_OUT_FULL;
|
||||
|
Loading…
Reference in New Issue
Block a user