Skip to content

Implement "arithmetic" lane wise shift right. #90

@thecppzoo

Description

@thecppzoo

Currently we support the shifting of lanes both left and right, with the "logical" semantics.
For example, shiftRightLanes:

zoo/inc/zoo/swar/SWAR.h

Lines 144 to 171 in 4a13f5c

constexpr SWAR shiftLanesLeft(int laneCount) const noexcept {
return SWAR(value() << (NBits * laneCount));
}
constexpr SWAR shiftLanesRight(int laneCount) const noexcept {
return SWAR(value() >> (NBits * laneCount));
}
/// \brief as the name suggests
/// \param protectiveMask should clear the bits that would cross the lane.
/// The bits that will be cleared are directly related to the count of
/// shifts, it is natural to maintain the protective mask by the caller,
/// otherwise, the mask would have to be computed in all invocations.
/// We are not sure the optimizer would maintain this mask somewhere, if it
/// were to recalculate it, it would be disastrous for performance
/// \note the \c static_cast are necessary because of narrowing conversions
#define SHIFT_INTRALANE_OP_X_LIST X(Left, <<) X(Right, >>)
#define X(name, op) \
constexpr SWAR \
shiftIntraLane##name(int bitCount, SWAR protectiveMask) const noexcept { \
T shiftC = static_cast<T>(bitCount); \
auto V = (*this & protectiveMask).value(); \
auto rv = static_cast<T>(V op shiftC); \
return SWAR{rv}; \
}
SHIFT_INTRALANE_OP_X_LIST
#undef X
#undef SHIFT_INTRALANE_OP_X_LIST

There are many arithmetic operations that would like to have "arithmetic" shift right, shift right can be used as cheap division by two, then there are very clear use cases that we can anticipate enough for implementing this operation.

Metadata

Metadata

Assignees

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions