qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
From: Peter Lieven <pl@kamp.de>
To: Gerd Hoffmann <kraxel@redhat.com>, qemu-devel@nongnu.org
Subject: Re: [Qemu-devel] [PATCH 19/19] buffer: allow a buffer to shrink gracefully
Date: Tue, 3 Nov 2015 08:10:29 +0100	[thread overview]
Message-ID: <56385DE5.2000806@kamp.de> (raw)
In-Reply-To: <1446203414-4013-20-git-send-email-kraxel@redhat.com>

Am 30.10.2015 um 12:10 schrieb Gerd Hoffmann:
> From: Peter Lieven <pl@kamp.de>
>
> the idea behind this patch is to allow the buffer to shrink, but
> make this a seldom operation. The buffers average size is measured
> exponentionally smoothed with am alpha of 1/128.
>
> Signed-off-by: Peter Lieven <pl@kamp.de>
> Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
> ---
>   include/qemu/buffer.h |  1 +
>   util/buffer.c         | 34 ++++++++++++++++++++++++++++------
>   2 files changed, 29 insertions(+), 6 deletions(-)
>
> diff --git a/include/qemu/buffer.h b/include/qemu/buffer.h
> index 0a69b3a..dead9b7 100644
> --- a/include/qemu/buffer.h
> +++ b/include/qemu/buffer.h
> @@ -37,6 +37,7 @@ struct Buffer {
>       char *name;
>       size_t capacity;
>       size_t offset;
> +    uint64_t avg_size;
>       uint8_t *buffer;
>   };
>   
> diff --git a/util/buffer.c b/util/buffer.c
> index fe5a44e..5461f86 100644
> --- a/util/buffer.c
> +++ b/util/buffer.c
> @@ -23,6 +23,7 @@
>   
>   #define BUFFER_MIN_INIT_SIZE     4096
>   #define BUFFER_MIN_SHRINK_SIZE  65536
> +#define BUFFER_AVG_SIZE_SHIFT       7
>   
>   static size_t buffer_req_size(Buffer *buffer, size_t len)
>   {
> @@ -37,6 +38,11 @@ static void buffer_adj_size(Buffer *buffer, size_t len)
>       buffer->buffer = g_realloc(buffer->buffer, buffer->capacity);
>       trace_buffer_resize(buffer->name ?: "unnamed",
>                           old, buffer->capacity);
> +
> +    /* make it even harder for the buffer to shrink, reset average size
> +     * to currenty capacity if it is larger than the average. */
> +    buffer->avg_size = MAX(buffer->avg_size,
> +                           buffer->capacity << BUFFER_AVG_SIZE_SHIFT);
>   }
>   
>   void buffer_init(Buffer *buffer, const char *name, ...)
> @@ -48,16 +54,30 @@ void buffer_init(Buffer *buffer, const char *name, ...)
>       va_end(ap);
>   }
>   
> +static uint64_t buffer_get_avg_size(Buffer *buffer)
> +{
> +    return buffer->avg_size >> BUFFER_AVG_SIZE_SHIFT;
> +}
> +
>   void buffer_shrink(Buffer *buffer)
>   {
> -    /*
> -     * Only shrink in case the used size is *much* smaller than the
> -     * capacity, to avoid bumping up & down the buffers all the time.
> +    size_t new;
> +
> +    /* Calculate the average size of the buffer as
> +     * avg_size = avg_size * ( 1 - a ) + required_size * a
> +     * where a is 1 / 2 ^ QIO_BUFFER_AVG_SIZE_SHIFT. */
> +    buffer->avg_size *= (1 << BUFFER_AVG_SIZE_SHIFT) - 1;
> +    buffer->avg_size >>= BUFFER_AVG_SIZE_SHIFT;
> +    buffer->avg_size += buffer_req_size(buffer, 0);
> +
> +    /* And then only shrink if the average size of the buffer is much
> +     * too big, to avoid bumping up & down the buffers all the time.
>        * realloc() isn't exactly cheap ...
>        */
> -    if (buffer->offset < (buffer->capacity >> 3) &&
> -        buffer->capacity > BUFFER_MIN_SHRINK_SIZE) {
> -        return;
> +    new = buffer_req_size(buffer, buffer_get_avg_size(buffer));
> +    if (new < buffer->capacity >> 3 &&
> +        new >= BUFFER_MIN_SHRINK_SIZE) {
> +        buffer_adj_size(buffer, buffer_get_avg_size(buffer));
>       }
>   
>       buffer_adj_size(buffer, 0);
> @@ -83,6 +103,7 @@ uint8_t *buffer_end(Buffer *buffer)
>   void buffer_reset(Buffer *buffer)
>   {
>       buffer->offset = 0;
> +    buffer_shrink(buffer);
>   }
>   
>   void buffer_free(Buffer *buffer)
> @@ -107,6 +128,7 @@ void buffer_advance(Buffer *buffer, size_t len)
>       memmove(buffer->buffer, buffer->buffer + len,
>               (buffer->offset - len));
>       buffer->offset -= len;
> +    buffer_shrink(buffer);
>   }
>   
>   void buffer_move_empty(Buffer *to, Buffer *from)

This isn't the last version of this patch. Please have a look at:

https://github.com/plieven/qemu/commit/e599748ab1ef381d4b1c88bf1ea1454dd89353fb

Peter

  parent reply	other threads:[~2015-11-03  7:10 UTC|newest]

Thread overview: 45+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-10-30 11:09 [Qemu-devel] [PATCH 00/19] buffer/vnc: improve vnc buffer hsndling Gerd Hoffmann
2015-10-30 11:09 ` [Qemu-devel] [PATCH 01/19] buffer: make the Buffer capacity increase in powers of two Gerd Hoffmann
2015-10-30 12:06   ` Daniel P. Berrange
2015-10-30 11:09 ` [Qemu-devel] [PATCH 02/19] buffer: add buffer_init Gerd Hoffmann
2015-10-30 12:07   ` Daniel P. Berrange
2015-10-30 11:09 ` [Qemu-devel] [PATCH 03/19] buffer: add buffer_move_empty Gerd Hoffmann
2015-10-30 12:11   ` Daniel P. Berrange
2015-10-30 12:34     ` Daniel P. Berrange
2015-10-30 11:09 ` [Qemu-devel] [PATCH 04/19] buffer: add buffer_move Gerd Hoffmann
2015-10-30 12:12   ` Daniel P. Berrange
2015-10-30 11:10 ` [Qemu-devel] [PATCH 05/19] buffer: add buffer_shrink Gerd Hoffmann
2015-10-30 12:13   ` Daniel P. Berrange
2015-10-30 11:10 ` [Qemu-devel] [PATCH 06/19] buffer: add tracing Gerd Hoffmann
2015-10-30 12:14   ` Daniel P. Berrange
2015-10-30 11:10 ` [Qemu-devel] [PATCH 07/19] vnc: attach names to buffers Gerd Hoffmann
2015-10-30 12:15   ` Daniel P. Berrange
2015-10-30 11:10 ` [Qemu-devel] [PATCH 08/19] vnc: kill jobs queue buffer Gerd Hoffmann
2015-10-30 12:16   ` Daniel P. Berrange
2015-10-30 11:10 ` [Qemu-devel] [PATCH 09/19] vnc-jobs: move buffer reset, use new buffer move Gerd Hoffmann
2015-10-30 12:17   ` Daniel P. Berrange
2015-10-30 11:10 ` [Qemu-devel] [PATCH 10/19] vnc: zap dead code Gerd Hoffmann
2015-10-30 12:18   ` Daniel P. Berrange
2015-10-30 11:10 ` [Qemu-devel] [PATCH 11/19] vnc: add vnc_width+vnc_height helpers Gerd Hoffmann
2015-10-30 12:19   ` Daniel P. Berrange
2015-10-30 11:10 ` [Qemu-devel] [PATCH 12/19] vnc: factor out vnc_update_server_surface Gerd Hoffmann
2015-10-30 12:22   ` Daniel P. Berrange
2015-10-30 11:10 ` [Qemu-devel] [PATCH 13/19] vnc: use vnc_{width, height} in vnc_set_area_dirty Gerd Hoffmann
2015-10-30 12:23   ` Daniel P. Berrange
2015-10-30 11:10 ` [Qemu-devel] [PATCH 14/19] vnc: only alloc server surface with clients connected Gerd Hoffmann
2015-10-30 12:24   ` Daniel P. Berrange
2015-10-30 11:10 ` [Qemu-devel] [PATCH 15/19] vnc: fix local state init Gerd Hoffmann
2015-10-30 12:26   ` Daniel P. Berrange
2015-10-30 11:10 ` [Qemu-devel] [PATCH 16/19] vnc: recycle empty vs->output buffer Gerd Hoffmann
2015-10-30 12:27   ` Daniel P. Berrange
2015-10-30 11:10 ` [Qemu-devel] [PATCH 17/19] buffer: factor out buffer_req_size Gerd Hoffmann
2015-10-30 12:28   ` Daniel P. Berrange
2015-10-30 11:10 ` [Qemu-devel] [PATCH 18/19] buffer: factor out buffer_adj_size Gerd Hoffmann
2015-10-30 12:29   ` Daniel P. Berrange
2015-10-30 11:10 ` [Qemu-devel] [PATCH 19/19] buffer: allow a buffer to shrink gracefully Gerd Hoffmann
2015-10-30 12:33   ` Daniel P. Berrange
2015-11-03  7:10   ` Peter Lieven [this message]
2015-10-30 12:36 ` [Qemu-devel] [PATCH 00/19] buffer/vnc: improve vnc buffer hsndling Daniel P. Berrange
2015-11-03  7:13 ` Peter Lieven
2015-11-03  8:23   ` Gerd Hoffmann
2015-11-03  9:01     ` Peter Lieven

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=56385DE5.2000806@kamp.de \
    --to=pl@kamp.de \
    --cc=kraxel@redhat.com \
    --cc=qemu-devel@nongnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).