All of lore.kernel.org
 help / color / mirror / Atom feed
From: Peter Lieven <pl@kamp.de>
To: qemu-devel@nongnu.org
Cc: kwolf@redhat.com, pbonzini@redhat.com, Peter Lieven <pl@kamp.de>
Subject: [Qemu-devel] [PATCHv3 2/9] cutils: add a function to find non-zero content in a buffer
Date: Thu, 21 Mar 2013 16:57:30 +0100	[thread overview]
Message-ID: <1363881457-14814-3-git-send-email-pl@kamp.de> (raw)
In-Reply-To: <1363881457-14814-1-git-send-email-pl@kamp.de>

this adds buffer_find_nonzero_offset() which is a SSE2/Altives
optimized function that searches for non-zero content in a
buffer.

due to the optimizations used in the function there are restrictions
on buffer address and search length. the function
can_use_buffer_find_nonzero_content() can be used to check if
the function can be used safely.

Signed-off-by: Peter Lieven <pl@kamp.de>
---
 include/qemu-common.h |    3 +++
 util/cutils.c         |   50 +++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 53 insertions(+)

diff --git a/include/qemu-common.h b/include/qemu-common.h
index e76ade3..ebbaf71 100644
--- a/include/qemu-common.h
+++ b/include/qemu-common.h
@@ -362,6 +362,9 @@ size_t qemu_iovec_from_buf(QEMUIOVector *qiov, size_t offset,
 size_t qemu_iovec_memset(QEMUIOVector *qiov, size_t offset,
                          int fillc, size_t bytes);
 
+#define BUFFER_FIND_NONZERO_OFFSET_UNROLL_FACTOR 8
+inline bool can_use_buffer_find_nonzero_offset(const void *buf, size_t len);
+inline size_t buffer_find_nonzero_offset(const void *buf, size_t len);
 bool buffer_is_zero(const void *buf, size_t len);
 
 void qemu_progress_init(int enabled, float min_skip);
diff --git a/util/cutils.c b/util/cutils.c
index 1439da4..6d079ac 100644
--- a/util/cutils.c
+++ b/util/cutils.c
@@ -143,6 +143,56 @@ int qemu_fdatasync(int fd)
 }
 
 /*
+ * Searches for an area with non-zero content in a buffer
+ *
+ * Attention! The len must be a multiple of 8 * sizeof(VECTYPE) 
+ * and addr must be a multiple of sizeof(VECTYPE) due to 
+ * restriction of optimizations in this function.
+ * 
+ * can_use_buffer_find_nonzero_offset() can be used to check
+ * these requirements.
+ * 
+ * The return value is the offset of the non-zero area rounded
+ * down to 8 * sizeof(VECTYPE). If the buffer is all zero 
+ * the return value is equal to len.
+ */
+
+inline size_t buffer_find_nonzero_offset(const void *buf, size_t len)
+{
+    VECTYPE *p = (VECTYPE *)buf;
+    VECTYPE zero = ZERO_SPLAT;
+    size_t i;
+    
+    if (*((const long *) buf)) {
+        return 0;
+    }
+
+    for (i = 0; i < len / sizeof(VECTYPE); 
+            i += BUFFER_FIND_NONZERO_OFFSET_UNROLL_FACTOR) {
+        VECTYPE tmp0 = p[i + 0] | p[i + 1];
+        VECTYPE tmp1 = p[i + 2] | p[i + 3];
+        VECTYPE tmp2 = p[i + 4] | p[i + 5];
+        VECTYPE tmp3 = p[i + 6] | p[i + 7];
+        VECTYPE tmp01 = tmp0 | tmp1;
+        VECTYPE tmp23 = tmp2 | tmp3;
+        if (!ALL_EQ(tmp01 | tmp23, zero)) {
+            break;
+        }
+    }
+    return i * sizeof(VECTYPE);
+}
+
+inline bool can_use_buffer_find_nonzero_offset(const void *buf, size_t len)
+{
+    if (len % (BUFFER_FIND_NONZERO_OFFSET_UNROLL_FACTOR 
+                * sizeof(VECTYPE)) == 0 
+            && ((uintptr_t) buf) % sizeof(VECTYPE) == 0) {
+        return true;
+    }
+    return false;
+}
+
+/*
  * Checks if a buffer is all zeroes
  *
  * Attention! The len must be a multiple of 4 * sizeof(long) due to
-- 
1.7.9.5

  parent reply	other threads:[~2013-03-21 15:58 UTC|newest]

Thread overview: 22+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2013-03-21 15:57 [Qemu-devel] [PATCHv3 0/9] buffer_is_zero / migration optimizations Peter Lieven
2013-03-21 15:57 ` [Qemu-devel] [PATCHv3 1/9] move vector definitions to qemu-common.h Peter Lieven
2013-03-21 17:29   ` Eric Blake
2013-03-21 15:57 ` Peter Lieven [this message]
2013-03-21 18:12   ` [Qemu-devel] [PATCHv3 2/9] cutils: add a function to find non-zero content in a buffer Eric Blake
2013-03-21 19:11     ` Peter Lieven
2013-03-21 15:57 ` [Qemu-devel] [PATCHv3 3/9] buffer_is_zero: use vector optimizations if possible Peter Lieven
2013-03-21 18:16   ` Eric Blake
2013-03-21 15:57 ` [Qemu-devel] [PATCHv3 4/9] bitops: use vector algorithm to optimize find_next_bit() Peter Lieven
2013-03-21 19:18   ` Eric Blake
2013-03-21 15:57 ` [Qemu-devel] [PATCHv3 5/9] migration: search for zero instead of dup pages Peter Lieven
2013-03-21 19:24   ` Eric Blake
2013-03-21 15:57 ` [Qemu-devel] [PATCHv3 6/9] migration: add an indicator for bulk state of ram migration Peter Lieven
2013-03-21 19:27   ` Eric Blake
2013-03-21 15:57 ` [Qemu-devel] [PATCHv3 7/9] migration: do not sent zero pages in bulk stage Peter Lieven
2013-03-21 19:26   ` Eric Blake
2013-03-21 19:44     ` Peter Lieven
2013-03-21 15:57 ` [Qemu-devel] [PATCHv3 8/9] migration: do not search dirty " Peter Lieven
2013-03-21 19:27   ` Eric Blake
2013-03-21 19:57     ` Peter Lieven
2013-03-21 15:57 ` [Qemu-devel] [PATCHv3 9/9] migration: use XBZRLE only after " Peter Lieven
2013-03-21 19:31   ` Eric Blake

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=1363881457-14814-3-git-send-email-pl@kamp.de \
    --to=pl@kamp.de \
    --cc=kwolf@redhat.com \
    --cc=pbonzini@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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.