From 61dfc95ec8be030468da5513d2b278e4536f5cea Mon Sep 17 00:00:00 2001 From: John Wellbelove Date: Tue, 4 Jun 2019 12:35:10 +0100 Subject: [PATCH 1/2] Optimised some binary operations. --- include/etl/binary.h | 94 ++++++++++++++++++++------------------------ 1 file changed, 42 insertions(+), 52 deletions(-) diff --git a/include/etl/binary.h b/include/etl/binary.h index b920d739..d701f37f 100644 --- a/include/etl/binary.h +++ b/include/etl/binary.h @@ -768,12 +768,10 @@ namespace etl inline uint_least8_t count_bits(uint8_t value) { uint32_t count; - static const int S[] = { 1, 2, 4 }; - static const uint8_t B[] = { 0x55, 0x33, 0x0F }; - count = value - ((value >> 1) & B[0]); - count = ((count >> S[1]) & B[1]) + (count & B[1]); - count = ((count >> S[2]) + count) & B[2]; + count = value - ((value >> 1) & 0x55); + count = ((count >> 2) & 0x33) + (count & 0x33); + count = ((count >> 4) + count) & 0x0F; return uint_least8_t(count); } @@ -792,13 +790,11 @@ namespace etl inline uint_least8_t count_bits(uint16_t value) { uint32_t count; - static const int S[] = { 1, 2, 4, 8 }; - static const uint16_t B[] = { 0x5555, 0x3333, 0x0F0F, 0x00FF }; - count = value - ((value >> 1) & B[0]); - count = ((count >> S[1]) & B[1]) + (count & B[1]); - count = ((count >> S[2]) + count) & B[2]; - count = ((count >> S[3]) + count) & B[3]; + count = value - ((value >> 1) & 0x5555); + count = ((count >> 2) & 0x3333) + (count & 0x3333); + count = ((count >> 4) + count) & 0x0F0F; + count = ((count >> 8) + count) & 0x00FF; return count; } @@ -816,9 +812,11 @@ namespace etl { uint32_t count; - value = value - ((value >> 1) & 0x55555555); - value = (value & 0x33333333) + ((value >> 2) & 0x33333333); - count = (((value + (value >> 4)) & 0xF0F0F0F) * 0x1010101) >> 24; + count = value - ((value >> 1) & 0x55555555); + count = ((count >> 2) & 0x33333333) + (count & 0x33333333); + count = ((count >> 4) + count) & 0x0F0F0F0F; + count = ((count >> 8) + count) & 0x00FF00FF; + count = ((count >> 16) + count) & 0x0000FF; return uint_least8_t(count); } @@ -835,15 +833,13 @@ namespace etl inline uint_least8_t count_bits(uint64_t value) { uint64_t count; - static const int S[] = { 1, 2, 4, 8, 16, 32 }; - static const uint64_t B[] = { 0x5555555555555555, 0x3333333333333333, 0x0F0F0F0F0F0F0F0F, 0x00FF00FF00FF00FF, 0x0000FFFF0000FFFF, 0x00000000FFFFFFFF }; - count = value - ((value >> 1) & B[0]); - count = ((count >> S[1]) & B[1]) + (count & B[1]); - count = ((count >> S[2]) + count) & B[2]; - count = ((count >> S[3]) + count) & B[3]; - count = ((count >> S[4]) + count) & B[4]; - count = ((count >> S[5]) + count) & B[5]; + count = value - ((value >> 1) & 0x5555555555555555); + count = ((count >> 2) & 0x3333333333333333) + (count & 0x3333333333333333); + count = ((count >> 4) + count) & 0x0F0F0F0F0F0F0F0F; + count = ((count >> 8) + count) & 0x00FF00FF00FF00FF; + count = ((count >> 16) + count) & 0x0000FFFF0000FFFF; + count = ((count >> 32) + count) & 0x00000000FFFFFFFF; return uint_least8_t(count); } @@ -1130,18 +1126,16 @@ namespace etl //***************************************************************************** inline uint16_t binary_interleave(uint8_t first, uint8_t second) { - static const uint16_t mask[] = { 0x5555, 0x3333, 0x0F0F }; - uint16_t f = first; uint16_t s = second; - f = (f | (f << 4)) & mask[2]; - f = (f | (f << 2)) & mask[1]; - f = (f | (f << 1)) & mask[0]; + f = (f | (f << 4)) & 0x0F0F; + f = (f | (f << 2)) & 0x3333; + f = (f | (f << 1)) & 0x5555; - s = (s | (s << 4)) & mask[2]; - s = (s | (s << 2)) & mask[1]; - s = (s | (s << 1)) & mask[0]; + s = (s | (s << 4)) & 0x0F0F; + s = (s | (s << 2)) & 0x3333; + s = (s | (s << 1)) & 0x5555; return (f | (s << 1)); } @@ -1158,20 +1152,18 @@ namespace etl //***************************************************************************** inline uint32_t binary_interleave(uint16_t first, uint16_t second) { - static const uint32_t mask[] = { 0x55555555, 0x33333333, 0x0F0F0F0F, 0x00FF00FF }; - uint32_t f = first; uint32_t s = second; - f = (f | (f << 8)) & mask[3]; - f = (f | (f << 4)) & mask[2]; - f = (f | (f << 2)) & mask[1]; - f = (f | (f << 1)) & mask[0]; + f = (f | (f << 8)) & 0x00FF00FF; + f = (f | (f << 4)) & 0x0F0F0F0F; + f = (f | (f << 2)) & 0x33333333; + f = (f | (f << 1)) & 0x55555555; - s = (s | (s << 8)) & mask[3]; - s = (s | (s << 4)) & mask[2]; - s = (s | (s << 2)) & mask[1]; - s = (s | (s << 1)) & mask[0]; + s = (s | (s << 8)) & 0x00FF00FF; + s = (s | (s << 4)) & 0x0F0F0F0F; + s = (s | (s << 2)) & 0x33333333; + s = (s | (s << 1)) & 0x55555555; return (f | (s << 1)); } @@ -1187,22 +1179,20 @@ namespace etl //***************************************************************************** inline uint64_t binary_interleave(uint32_t first, uint32_t second) { - static const uint64_t mask[] = { 0x5555555555555555, 0x3333333333333333, 0x0F0F0F0F0F0F0F0F, 0x00FF00FF00FF00FF, 0x0000FFFF0000FFFF }; - uint64_t f = first; uint64_t s = second; - f = (f | (f << 16)) & mask[4]; - f = (f | (f << 8)) & mask[3]; - f = (f | (f << 4)) & mask[2]; - f = (f | (f << 2)) & mask[1]; - f = (f | (f << 1)) & mask[0]; + f = (f | (f << 16)) & 0x0000FFFF0000FFFF; + f = (f | (f << 8)) & 0x00FF00FF00FF00FF; + f = (f | (f << 4)) & 0x0F0F0F0F0F0F0F0F; + f = (f | (f << 2)) & 0x3333333333333333; + f = (f | (f << 1)) & 0x5555555555555555; - s = (s | (s << 16)) & mask[4]; - s = (s | (s << 8)) & mask[3]; - s = (s | (s << 4)) & mask[2]; - s = (s | (s << 2)) & mask[1]; - s = (s | (s << 1)) & mask[0]; + s = (s | (s << 16)) & 0x0000FFFF0000FFFF; + s = (s | (s << 8)) & 0x00FF00FF00FF00FF; + s = (s | (s << 4)) & 0x0F0F0F0F0F0F0F0F; + s = (s | (s << 2)) & 0x3333333333333333; + s = (s | (s << 1)) & 0x5555555555555555; return (f | (s << 1)); } From 7515a60b6974738f5ea69a1f731ce8e6c9a7d46e Mon Sep 17 00:00:00 2001 From: John Wellbelove Date: Tue, 4 Jun 2019 20:41:36 +0100 Subject: [PATCH 2/2] Updated version number --- include/etl/version.h | 2 +- support/Release notes.txt | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/include/etl/version.h b/include/etl/version.h index 0f698a90..56975fa2 100644 --- a/include/etl/version.h +++ b/include/etl/version.h @@ -39,7 +39,7 @@ SOFTWARE. #define ETL_VERSION_MAJOR 14 #define ETL_VERSION_MINOR 26 -#define ETL_VERSION_PATCH 2 +#define ETL_VERSION_PATCH 3 #define ETL_VERSION ETL_STRINGIFY(ETL_VERSION_MAJOR) ETL_STRINGIFY(ETL_VERSION_MINOR) ETL_STRINGIFY(ETL_VERSION_PATCH) #define ETL_VERSION_W ETL_WIDE_STRING(ETL_CONCAT(ETL_CONCAT(ETL_VERSION_MAJOR, ETL_VERSION_MINOR), ETL_VERSION_PATCH)) diff --git a/support/Release notes.txt b/support/Release notes.txt index 5d163a6e..01871568 100644 --- a/support/Release notes.txt +++ b/support/Release notes.txt @@ -1,3 +1,7 @@ +=============================================================================== +14.26.3 +A few small optimisations to binary.h + =============================================================================== 14.26.2 Added #include to files using 'placement new'.