-
Notifications
You must be signed in to change notification settings - Fork 12
Implement lane-wise modulo. #86
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from 33 commits
295d602
dbf8115
2327807
7c10d29
0b8b214
e3a802d
7ed6e88
03edd02
0648bb1
0d0a833
33183cd
a7d744d
06af01c
ffc1120
5b837e6
c97318f
3dd0296
da9ccb9
da64b7d
11ccd9e
aab033a
ba6a5ba
f3d9f42
783f189
f9e28b1
d636521
d880691
bbad583
f6a04f1
e39d298
0ca3600
f7ffe70
53e56f5
b62355a
bf93d56
79d3847
a585ad9
711bb08
f1452cb
f45632a
79148d3
08a73e1
0228573
0829a7e
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,75 @@ | ||
#pragma once | ||
#include "SWAR.h" | ||
#include <cstddef> | ||
#include <cstdint> | ||
|
||
namespace zoo::math { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You know, should you have used There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I wouldn't have let 'maths' slide. |
||
|
||
template <typename IntegerType = size_t> | ||
constexpr static | ||
std::enable_if_t<std::is_integral_v<IntegerType>, bool> | ||
is_power_of_two(IntegerType x) noexcept { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. habit, let's move to camelCase to be consistent. will start email thread about case to ask if you have strong preference to avoid polluting PR with unrelated discussion. |
||
return x > 0 && (x & (x - 1)) == 0; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Indentation. |
||
} | ||
|
||
template <typename IntegerType = size_t, IntegerType X> | ||
constexpr static | ||
std::enable_if_t<std::is_integral_v<IntegerType>, bool> | ||
is_power_of_two() noexcept { | ||
return is_power_of_two(X); | ||
} | ||
static_assert(is_power_of_two<int, 4>()); | ||
|
||
|
||
template <size_t N, typename IntegerType = size_t> | ||
constexpr static | ||
std::enable_if_t< | ||
std::is_integral_v<IntegerType> && | ||
is_power_of_two<size_t, N>(), size_t> | ||
modulo_power_of_two(IntegerType x) noexcept { | ||
return x & (N - 1); | ||
} | ||
|
||
static_assert(modulo_power_of_two<4>(0) == 0); | ||
static_assert(modulo_power_of_two<8>(9) == 1); | ||
static_assert(modulo_power_of_two<4096>(4097) == 1); | ||
|
||
} | ||
|
||
// SWAR power of two | ||
|
||
namespace zoo::swar { | ||
template <typename S> | ||
constexpr static auto subtract_one_unsafe(S x) noexcept { | ||
constexpr auto Ones = S::LeastSignificantBit; | ||
auto x_minus_1 = S{x.value() - Ones}; | ||
return x_minus_1; | ||
} | ||
// todo subtract K unsafe using BitmaskMaker | ||
// todo subtract K "saturated" using BitmaskMaker | ||
|
||
template <typename S> | ||
constexpr static auto is_power_of_two(S x) noexcept { | ||
constexpr auto NBits = S::NBits; | ||
using T = typename S::type; | ||
auto greater_than_0 = greaterEqual_MSB_off(x, S{0}); | ||
auto x_minus_1 = subtract_one_unsafe(x); | ||
auto zero = equals(S{x_minus_1.value() & x.value()}, S{0}); | ||
return greater_than_0 & zero; | ||
} | ||
|
||
template <size_t N, typename S> | ||
constexpr static | ||
std::enable_if_t<zoo::math::is_power_of_two<size_t, N>(), S> | ||
modulo_power_of_two(const S x) noexcept { | ||
constexpr auto NBits = S::NBits; | ||
using T = typename S::type; | ||
constexpr auto N_minus_1 = N - 1; | ||
constexpr auto N_in_lanes = zoo::meta::BitmaskMaker<T, N_minus_1, NBits>::value; | ||
T y = x.value() & N_in_lanes; | ||
return S{y}; | ||
} | ||
|
||
|
||
} // namespace zoo::swar | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
SWAR.h
includes this, or its equivalent,stdint.h
, I see no point in things likestd::uint64_t
instead of justuint64_t