From 9233661c6f40e76b3b178330c3e326518c7a11ce Mon Sep 17 00:00:00 2001 From: Ben Vanik Date: Tue, 23 Dec 2014 10:22:33 -0800 Subject: [PATCH] Skeleton for copy_and_swap. --- src/poly/memory.cc | 47 ++++++++++++++++++++++++++++++++++++++ src/poly/memory.h | 56 +++++++++++++++++++++++++++++++++++++++++----- 2 files changed, 97 insertions(+), 6 deletions(-) diff --git a/src/poly/memory.cc b/src/poly/memory.cc index 448899769..d4360abe7 100644 --- a/src/poly/memory.cc +++ b/src/poly/memory.cc @@ -29,4 +29,51 @@ size_t page_size() { return value; } +// TODO(benvanik): fancy AVX versions. +// http://gnuradio.org/redmine/projects/gnuradio/repository/revisions/cb32b70b79f430456208a2cd521d028e0ece5d5b/entry/volk/kernels/volk/volk_16u_byteswap.h +// http://gnuradio.org/redmine/projects/gnuradio/repository/revisions/f2bc76cc65ffba51a141950f98e75364e49df874/entry/volk/kernels/volk/volk_32u_byteswap.h +// http://gnuradio.org/redmine/projects/gnuradio/repository/revisions/2c4c371885c31222362f70a1cd714415d1398021/entry/volk/kernels/volk/volk_64u_byteswap.h + +void copy_and_swap_16_aligned(uint16_t* dest, const uint16_t* src, + size_t count) { + for (size_t i = 0; i < count; ++i) { + dest[i] = byte_swap(src[i]); + } +} + +void copy_and_swap_16_unaligned(uint16_t* dest, const uint16_t* src, + size_t count) { + for (size_t i = 0; i < count; ++i) { + dest[i] = byte_swap(src[i]); + } +} + +void copy_and_swap_32_aligned(uint32_t* dest, const uint32_t* src, + size_t count) { + for (size_t i = 0; i < count; ++i) { + dest[i] = byte_swap(src[i]); + } +} + +void copy_and_swap_32_unaligned(uint32_t* dest, const uint32_t* src, + size_t count) { + for (size_t i = 0; i < count; ++i) { + dest[i] = byte_swap(src[i]); + } +} + +void copy_and_swap_64_aligned(uint64_t* dest, const uint64_t* src, + size_t count) { + for (size_t i = 0; i < count; ++i) { + dest[i] = byte_swap(src[i]); + } +} + +void copy_and_swap_64_unaligned(uint64_t* dest, const uint64_t* src, + size_t count) { + for (size_t i = 0; i < count; ++i) { + dest[i] = byte_swap(src[i]); + } +} + } // namespace poly diff --git a/src/poly/memory.h b/src/poly/memory.h index a3488eaf4..e7443626a 100644 --- a/src/poly/memory.h +++ b/src/poly/memory.h @@ -29,6 +29,54 @@ size_t hash_combine(size_t seed, const T& v, const Ts&... vs) { size_t page_size(); +void copy_and_swap_16_aligned(uint16_t* dest, const uint16_t* src, + size_t count); +void copy_and_swap_16_unaligned(uint16_t* dest, const uint16_t* src, + size_t count); +void copy_and_swap_32_aligned(uint32_t* dest, const uint32_t* src, + size_t count); +void copy_and_swap_32_unaligned(uint32_t* dest, const uint32_t* src, + size_t count); +void copy_and_swap_64_aligned(uint64_t* dest, const uint64_t* src, + size_t count); +void copy_and_swap_64_unaligned(uint64_t* dest, const uint64_t* src, + size_t count); + +template +void copy_and_swap(T* dest, const T* src, size_t count) { + bool is_aligned = reinterpret_cast(dest) % 32 == 0 && + reinterpret_cast(src) % 32 == 0; + if (sizeof(T) == 1) { + std::memcpy(dest, src, count); + } else if (sizeof(T) == 2) { + auto ps = reinterpret_cast(src); + auto pd = reinterpret_cast(dest); + if (is_aligned) { + copy_and_swap_16_aligned(pd, ps, count); + } else { + copy_and_swap_16_unaligned(pd, ps, count); + } + } else if (sizeof(T) == 4) { + auto ps = reinterpret_cast(src); + auto pd = reinterpret_cast(dest); + if (is_aligned) { + copy_and_swap_32_aligned(pd, ps, count); + } else { + copy_and_swap_32_unaligned(pd, ps, count); + } + } else if (sizeof(T) == 8) { + auto ps = reinterpret_cast(src); + auto pd = reinterpret_cast(dest); + if (is_aligned) { + copy_and_swap_64_aligned(pd, ps, count); + } else { + copy_and_swap_64_unaligned(pd, ps, count); + } + } else { + assert_always("Invalid poly::copy_and_swap size"); + } +} + template T load(const void* mem); template <> @@ -259,12 +307,8 @@ template struct be { be() = default; be(const T& src) : value(poly::byte_swap(src)) {} - be(const be& other) { - value = other.value; - } - operator T() const { - return poly::byte_swap(value); - } + be(const be& other) { value = other.value; } + operator T() const { return poly::byte_swap(value); } T value; };