From: Loic Dachary <loic@dachary.org>
To: Janne Grunau <j@jannau.net>, ceph-devel@vger.kernel.org
Subject: Re: [PATCH 1/3] buffer: add an aligned buffer with less alignment than a page
Date: Mon, 15 Sep 2014 18:46:44 +0200 [thread overview]
Message-ID: <541717F4.4050509@dachary.org> (raw)
In-Reply-To: <1410796508-28711-1-git-send-email-j@jannau.net>
[-- Attachment #1: Type: text/plain, Size: 8674 bytes --]
Look great !
Running on git builder under the branch wip-9408-buffer-alignment at http://ceph.com/gitbuilder.cgi
On 15/09/2014 17:55, Janne Grunau wrote:
> SIMD optimized erasure code computation needs aligned memory. Buffers
> aligned to a page boundary are wasted on it though. The buffers used
> for the erasure code computation are typical smaller than a page.
>
> Currently an alignement of 16 bytes is enough for the used
> SIMD instruction sets (SSE4 and NEON).
>
> Signed-off-by: Janne Grunau <j@jannau.net>
> ---
> configure.ac | 9 +++++
> src/common/buffer.cc | 100 +++++++++++++++++++++++++++++++++++++++++++++++++++
> src/include/buffer.h | 10 ++++++
> 3 files changed, 119 insertions(+)
>
> diff --git a/configure.ac b/configure.ac
> index cccf2d9..1bb27c4 100644
> --- a/configure.ac
> +++ b/configure.ac
> @@ -793,6 +793,15 @@ AC_MSG_RESULT([no])
> ])
>
> #
> +# Check for functions to provide aligned memory
> +#
> +AC_CHECK_HEADERS([malloc.h])
> +AC_CHECK_FUNCS([posix_memalign _aligned_malloc memalign aligned_malloc],
> + [found_memalign=yes; break])
> +
> +AS_IF([test "x$found_memalign" != "xyes"], [AC_MSG_WARN([No function for aligned memory allocation found])])
> +
> +#
> # Check for pthread spinlock (depends on ACX_PTHREAD)
> #
> saved_LIBS="$LIBS"
> diff --git a/src/common/buffer.cc b/src/common/buffer.cc
> index b141759..acc221f 100644
> --- a/src/common/buffer.cc
> +++ b/src/common/buffer.cc
> @@ -30,6 +30,10 @@
> #include <sys/uio.h>
> #include <limits.h>
>
> +#ifdef HAVE_MALLOC_H
> +#include <malloc.h>
> +#endif
> +
> namespace ceph {
>
> #ifdef BUFFER_DEBUG
> @@ -155,9 +159,15 @@ static simple_spinlock_t buffer_debug_lock = SIMPLE_SPINLOCK_INITIALIZER;
> virtual int zero_copy_to_fd(int fd, loff_t *offset) {
> return -ENOTSUP;
> }
> + virtual bool is_aligned() {
> + return ((long)data & ~CEPH_ALIGN_MASK) == 0;
> + }
> virtual bool is_page_aligned() {
> return ((long)data & ~CEPH_PAGE_MASK) == 0;
> }
> + bool is_n_align_sized() {
> + return (len & ~CEPH_ALIGN_MASK) == 0;
> + }
> bool is_n_page_sized() {
> return (len & ~CEPH_PAGE_MASK) == 0;
> }
> @@ -209,6 +219,41 @@ static simple_spinlock_t buffer_debug_lock = SIMPLE_SPINLOCK_INITIALIZER;
> }
> };
>
> + class buffer::raw_aligned : public buffer::raw {
> + public:
> + raw_aligned(unsigned l) : raw(l) {
> + if (len) {
> +#if HAVE_POSIX_MEMALIGN
> + if (posix_memalign((void **) &data, CEPH_ALIGN, len))
> + data = 0;
> +#elif HAVE__ALIGNED_MALLOC
> + data = _aligned_malloc(len, CEPH_ALIGN);
> +#elif HAVE_MEMALIGN
> + data = memalign(CEPH_ALIGN, len);
> +#elif HAVE_ALIGNED_MALLOC
> + data = aligned_malloc((len + CEPH_ALIGN - 1) & ~CEPH_ALIGN_MASK,
> + CEPH_ALIGN);
> +#else
> + data = malloc(len);
> +#endif
> + if (!data)
> + throw bad_alloc();
> + } else {
> + data = 0;
> + }
> + inc_total_alloc(len);
> + bdout << "raw_aligned " << this << " alloc " << (void *)data << " " << l << " " << buffer::get_total_alloc() << bendl;
> + }
> + ~raw_aligned() {
> + free(data);
> + dec_total_alloc(len);
> + bdout << "raw_aligned " << this << " free " << (void *)data << " " << buffer::get_total_alloc() << bendl;
> + }
> + raw* clone_empty() {
> + return new raw_aligned(len);
> + }
> + };
> +
> #ifndef __CYGWIN__
> class buffer::raw_mmap_pages : public buffer::raw {
> public:
> @@ -334,6 +379,10 @@ static simple_spinlock_t buffer_debug_lock = SIMPLE_SPINLOCK_INITIALIZER;
> return true;
> }
>
> + bool is_aligned() {
> + return false;
> + }
> +
> bool is_page_aligned() {
> return false;
> }
> @@ -520,6 +569,9 @@ static simple_spinlock_t buffer_debug_lock = SIMPLE_SPINLOCK_INITIALIZER;
> buffer::raw* buffer::create_static(unsigned len, char *buf) {
> return new raw_static(buf, len);
> }
> + buffer::raw* buffer::create_aligned(unsigned len) {
> + return new raw_aligned(len);
> + }
> buffer::raw* buffer::create_page_aligned(unsigned len) {
> #ifndef __CYGWIN__
> //return new raw_mmap_pages(len);
> @@ -1013,6 +1065,16 @@ static simple_spinlock_t buffer_debug_lock = SIMPLE_SPINLOCK_INITIALIZER;
> return true;
> }
>
> + bool buffer::list::is_aligned() const
> + {
> + for (std::list<ptr>::const_iterator it = _buffers.begin();
> + it != _buffers.end();
> + ++it)
> + if (!it->is_aligned())
> + return false;
> + return true;
> + }
> +
> bool buffer::list::is_page_aligned() const
> {
> for (std::list<ptr>::const_iterator it = _buffers.begin();
> @@ -1101,6 +1163,44 @@ static simple_spinlock_t buffer_debug_lock = SIMPLE_SPINLOCK_INITIALIZER;
> _buffers.push_back(nb);
> }
>
> +void buffer::list::rebuild_aligned()
> +{
> + std::list<ptr>::iterator p = _buffers.begin();
> + while (p != _buffers.end()) {
> + // keep anything that's already page sized+aligned
> + if (p->is_aligned() && p->is_n_align_sized()) {
> + /*cout << " segment " << (void*)p->c_str()
> + << " offset " << ((unsigned long)p->c_str() & ~CEPH_ALIGN_MASK)
> + << " length " << p->length()
> + << " " << (p->length() & ~CEPH_ALIGN_MASK) << " ok" << std::endl;
> + */
> + ++p;
> + continue;
> + }
> +
> + // consolidate unaligned items, until we get something that is sized+aligned
> + list unaligned;
> + unsigned offset = 0;
> + do {
> + /*cout << " segment " << (void*)p->c_str()
> + << " offset " << ((unsigned long)p->c_str() & ~CEPH_ALIGN_MASK)
> + << " length " << p->length() << " " << (p->length() & ~CEPH_ALIGN_MASK)
> + << " overall offset " << offset << " " << (offset & ~CEPH_ALIGN_MASK)
> + << " not ok" << std::endl;
> + */
> + offset += p->length();
> + unaligned.push_back(*p);
> + _buffers.erase(p++);
> + } while (p != _buffers.end() &&
> + (!p->is_aligned() ||
> + !p->is_n_align_sized() ||
> + (offset & ~CEPH_ALIGN_MASK)));
> + ptr nb(buffer::create_aligned(unaligned._len));
> + unaligned.rebuild(nb);
> + _buffers.insert(p, unaligned._buffers.front());
> + }
> +}
> +
> void buffer::list::rebuild_page_aligned()
> {
> std::list<ptr>::iterator p = _buffers.begin();
> diff --git a/src/include/buffer.h b/src/include/buffer.h
> index e5c1b50..ea362e7 100644
> --- a/src/include/buffer.h
> +++ b/src/include/buffer.h
> @@ -56,6 +56,9 @@
> # include <assert.h>
> #endif
>
> +#define CEPH_ALIGN 16
> +#define CEPH_ALIGN_MASK (~(CEPH_ALIGN - 1LLU))
> +
> namespace ceph {
>
> class buffer {
> @@ -124,6 +127,7 @@ private:
> */
> class raw;
> class raw_malloc;
> + class raw_aligned;
> class raw_static;
> class raw_mmap_pages;
> class raw_posix_aligned;
> @@ -144,6 +148,7 @@ public:
> static raw* create_malloc(unsigned len);
> static raw* claim_malloc(unsigned len, char *buf);
> static raw* create_static(unsigned len, char *buf);
> + static raw* create_aligned(unsigned len);
> static raw* create_page_aligned(unsigned len);
> static raw* create_zero_copy(unsigned len, int fd, int64_t *offset);
>
> @@ -177,7 +182,9 @@ public:
> bool at_buffer_head() const { return _off == 0; }
> bool at_buffer_tail() const;
>
> + bool is_aligned() const { return ((long)c_str() & ~CEPH_ALIGN_MASK) == 0; }
> bool is_page_aligned() const { return ((long)c_str() & ~CEPH_PAGE_MASK) == 0; }
> + bool is_n_align_sized() const { return (length() & ~CEPH_ALIGN_MASK) == 0; }
> bool is_n_page_sized() const { return (length() & ~CEPH_PAGE_MASK) == 0; }
>
> // accessors
> @@ -344,7 +351,9 @@ public:
> bool contents_equal(buffer::list& other);
>
> bool can_zero_copy() const;
> + bool is_aligned() const;
> bool is_page_aligned() const;
> + bool is_n_align_sized() const;
> bool is_n_page_sized() const;
>
> bool is_zero() const;
> @@ -382,6 +391,7 @@ public:
> bool is_contiguous();
> void rebuild();
> void rebuild(ptr& nb);
> + void rebuild_aligned();
> void rebuild_page_aligned();
>
> // sort-of-like-assignment-op
>
--
Loïc Dachary, Artisan Logiciel Libre
[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 263 bytes --]
next prev parent reply other threads:[~2014-09-15 16:46 UTC|newest]
Thread overview: 41+ messages / expand[flat|nested] mbox.gz Atom feed top
2014-09-15 15:55 [PATCH 1/3] buffer: add an aligned buffer with less alignment than a page Janne Grunau
2014-09-15 15:55 ` [PATCH 2/3] ec: make use of added aligned buffers Janne Grunau
2014-09-15 17:20 ` Loic Dachary
2014-09-15 23:56 ` Ma, Jianpeng
2014-09-16 0:02 ` Sage Weil
2014-09-16 0:08 ` Ma, Jianpeng
2014-09-16 6:47 ` Loic Dachary
2014-09-16 6:59 ` Ma, Jianpeng
2014-09-16 7:55 ` Loic Dachary
2014-09-16 8:23 ` Ma, Jianpeng
2014-09-15 15:55 ` [PATCH 3/3] ceph_erasure_code_benchmark: align the encoding input Janne Grunau
2014-09-15 16:46 ` Loic Dachary [this message]
2014-09-18 10:33 ` v2 aligned buffer changes for erasure codes Janne Grunau
2014-09-18 10:33 ` [PATCH v2 1/3] buffer: add an aligned buffer with less alignment than a page Janne Grunau
2014-09-18 10:33 ` [PATCH v2 2/3] ec: use 32-byte aligned buffers Janne Grunau
2014-09-19 9:47 ` Loic Dachary
2014-09-18 10:33 ` [PATCH v2 3/3] ceph_erasure_code_benchmark: align the encoding input Janne Grunau
2014-09-18 12:18 ` v2 aligned buffer changes for erasure codes Andreas Joachim Peters
2014-09-18 12:34 ` Andreas Joachim Peters
2014-09-18 12:53 ` Janne Grunau
2014-09-19 9:18 ` Loic Dachary
2014-09-18 12:40 ` Janne Grunau
2014-09-18 13:01 ` Andreas Joachim Peters
2014-09-18 13:23 ` Janne Grunau
2014-09-18 14:47 ` Andreas Joachim Peters
2014-09-29 12:34 ` [PATCH v3 0/4] buffer alignment for erasure code SIMD Janne Grunau
2014-09-29 12:34 ` [PATCH v3 1/4] buffer: add an aligned buffer with less alignment than a page Janne Grunau
2014-09-29 13:12 ` Loic Dachary
2014-10-02 12:09 ` Janne Grunau
2014-09-29 13:27 ` Loic Dachary
2014-10-02 12:12 ` Janne Grunau
2014-10-02 14:17 ` Loic Dachary
2014-09-29 12:34 ` [PATCH v3 2/4] erasure code: use a function for the chunk mapping index Janne Grunau
2014-09-29 12:34 ` [PATCH v3 3/4] erasure code: use 32-byte aligned buffers Janne Grunau
2014-09-29 12:34 ` [PATCH v3 4/4] ceph_erasure_code_benchmark: use 32-byte aligned input Janne Grunau
2014-09-29 13:15 ` [PATCH v3 0/4] buffer alignment for erasure code SIMD Loic Dachary
2014-09-29 15:18 ` Milosz Tanski
2014-09-29 15:24 ` C++11 Sage Weil
2014-09-29 15:44 ` C++11 Milosz Tanski
2014-09-29 17:56 ` C++11 Wido den Hollander
2014-10-02 12:15 ` [PATCH v3 0/4] buffer alignment for erasure code SIMD Janne Grunau
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=541717F4.4050509@dachary.org \
--to=loic@dachary.org \
--cc=ceph-devel@vger.kernel.org \
--cc=j@jannau.net \
/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