qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Qemu-devel] [PATCH 26/27] block/parallels: optimize linear image ex


From: Denis V. Lunev
Subject: Re: [Qemu-devel] [PATCH 26/27] block/parallels: optimize linear image expansion
Date: Wed, 22 Apr 2015 18:41:29 +0300
User-agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.10; rv:31.0) Gecko/20100101 Thunderbird/31.6.0

On 22/04/15 17:25, Denis V. Lunev wrote:
On 22/04/15 17:18, Stefan Hajnoczi wrote:
On Wed, Mar 11, 2015 at 01:28:20PM +0300, Denis V. Lunev wrote:
Plain image expansion spends a lot of time to update image file size.
This seriously affects the performance. The following simple test
   qemu_img create -f parallels -o cluster_size=64k ./1.hds 64G
   qemu_io -n -c "write -P 0x11 0 1024M" ./1.hds
could be improved if the format driver will pre-allocate some space
in the image file with a reasonable chunk.

This patch preallocates 128 Mb using bdrv_write_zeroes, which should
normally use fallocate() call inside. Fallback to older truncate()
could be used as a fallback using image open options thanks to the
previous patch.

The benefit is around 15%.
qcow2 doesn't use bdrv_truncate() at all.  It simply writes past the end
of bs->file to grow the file.  Can you use this approach instead?
this is worse from performance point of view.

OK, there is no difference if big write will come from guest. In
this case single write will do the job just fine. Though if the
file will be extended by several different write the situation
will be different. Each write will update inode metadata.
Welcome journal write. This metadata update will cost us
even more in the case of network filesystem and much more
in the case of distributed filesystem (additional MDS write
transaction at least).

This is the main reason to follow this approach here.

#define _GNU_SOURCE

#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/types.h>
#include <malloc.h>
#include <string.h>

int main(int argc, char *argv[])
{
    int fd = open(argv[1], O_WRONLY | O_CREAT | O_DIRECT | O_TRUNC, 0644);
    void *buf;
    int i = 0;

    buf = memalign(4096, 65536);
    memset(buf, 0x11, 65536);

    for (i = 0; i < 1024 * 64; i++) {
        write(fd, buf, 65536);
    }

    close(fd);
    return 0;
}

# with O_TRUNC in the test
hades /vol $ time for i in `seq 1 10` ; do ./a.out aa ; done

real    3m4.031s
user    0m0.123s
sys    0m18.902s
hades /vol
hades /vol $
hades /vol $

# without O_TRUNC in the test (file exists)
hades /vol $ time for i in `seq 1 10` ; do ./a.out aa ; done

real    2m56.770s
user    0m0.133s
sys    0m10.756s
hades /vol $

The difference for this case (ext4) is 5%.

hades ~ $ uname -a
Linux hades 3.16.0-34-generic #47~14.04.1-Ubuntu SMP Fri Apr 10 17:49:16 UTC 2015 x86_64 x86_64 x86_64 GNU/Linux
hades ~ $



reply via email to

[Prev in Thread] Current Thread [Next in Thread]