Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
70 changes: 34 additions & 36 deletions include/bitlib/bit-algorithms/count.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ count(

if (first.position() != 0) {
word_type first_value = lsr(*first.base(), first.position());
result = _popcnt(first_value);
result = std::popcount(static_cast<std::make_unsigned_t<word_type>>(first_value));
++it;
}
// The SIMD implementation here is actually slower than the standard
Expand All @@ -67,46 +67,44 @@ count(
//{
//// Align to boundary
//for (; it != last.base() && !is_aligned(&(*it), 64); ++it) {
//result += _popcnt(*it);
//}

//// SIMD
//hn::ScalableTag<word_type> d;
//for (; std::distance(it, last.base()) >= hn::Lanes(d); it += hn::Lanes(d))
//{
//const auto popcntV = hn::PopulationCount(hn::Load(d, &*it));
//result += hn::ReduceSum(d, popcntV);
//}

//// Remaining
//for (; it != last.base(); ++it) {
//result += _popcnt(*it);
//}
//} else
//#endif
{
// std:: version
//result += std::transform_reduce(
//it,
//last.base(),
//0,
//std::plus{},
//[](word_type word) {return _popcnt(word); }
//);

// libpopcnt
result += popcnt(&*it, (digits / 8) * std::distance(it, last.base()));
}
//result += std::popcount(*it);
//}

//// SIMD
//hn::ScalableTag<word_type> d;
//for (; std::distance(it, last.base()) >= hn::Lanes(d); it += hn::Lanes(d))
//{
//const auto popcntV = hn::PopulationCount(hn::Load(d, &*it));
//result += hn::ReduceSum(d, popcntV);
//}

//// Remaining
//for (; it != last.base(); ++it) {
//result += std::popcount(*it);
//}
//} else
//#endif
{
// std:: version
//result += std::transform_reduce(
//it,
//last.base(),
//0,
//std::plus{},
//[](word_type word) {return std::popcount(word); }
//);

// libpopcnt
result += popcnt(&*it, (digits / 8) * std::distance(it, last.base()));
}
if (last.position() != 0) {
word_type last_value = *last.base() << (digits - last.position());
result += _popcnt(last_value);
result += std::popcount(static_cast<std::make_unsigned_t<word_type>>(last_value));
}
// Computation when bits belong to the same underlying word
} else {
result = _popcnt(
_bextr<word_type>(*first.base(), first.position(), last.position()
- first.position())
);
result = std::popcount(static_cast<std::make_unsigned_t<word_type>>(
_bextr<word_type>(*first.base(), first.position(), last.position() - first.position())));
}

// Negates when the number of zero bits is requested
Expand Down
30 changes: 16 additions & 14 deletions include/bitlib/bit-algorithms/find.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@

// ============================== PREAMBLE ================================== //
// C++ standard library
#include <bit>
#include <iterator>
// Project sources
#include "bitlib/bit-iterator/bit.hpp"
Expand Down Expand Up @@ -37,6 +38,7 @@ constexpr bit_iterator<RandomAccessIt> find(
) {

using word_type = typename bit_iterator<RandomAccessIt>::word_type;
using uword_type = std::make_unsigned_t<word_type>;
using size_type = typename bit_iterator<RandomAccessIt>::size_type;
const std::size_t digits = binary_digits<word_type>::value;

Expand All @@ -48,8 +50,8 @@ constexpr bit_iterator<RandomAccessIt> find(
if (!is_first_aligned) {
word_type shifted_first = lsr(*first.base(), first.position());
size_type num_trailing_complementary_bits = (bv == bit0)
? _tzcnt(static_cast<word_type>(~shifted_first))
: _tzcnt(static_cast<word_type>(shifted_first));
? std::countr_zero(static_cast<uword_type>(~shifted_first))
: std::countr_zero(static_cast<uword_type>(shifted_first));
if (std::next(first.base(), is_last_aligned) == last.base()) {
return first + std::min(num_trailing_complementary_bits, static_cast<size_type>(distance(first, last)));
} else if (num_trailing_complementary_bits + first.position() < digits) {
Expand All @@ -72,8 +74,8 @@ constexpr bit_iterator<RandomAccessIt> find(
}

size_type num_trailing_complementary_bits = (bv == bit0)
? _tzcnt(static_cast<word_type>(~*it))
: _tzcnt(static_cast<word_type>(*it));
? std::countr_zero(static_cast<uword_type>(~*it))
: std::countr_zero(static_cast<uword_type>(*it));
return bit_iterator(it, (size_type) num_trailing_complementary_bits);
}

Expand All @@ -92,8 +94,8 @@ constexpr bit_iterator<RandomAccessIt> find(
{
it += hn::FindKnownFirstTrue(d, found);
size_type num_trailing_complementary_bits = (bv == bit0)
? _tzcnt(static_cast<word_type>(~*it))
: _tzcnt(static_cast<word_type>(*it));
? std::countr_zero(static_cast<uword_type>(~*it))
: std::countr_zero(static_cast<uword_type>(*it));
return bit_iterator(it, (size_type) num_trailing_complementary_bits);
}
}
Expand All @@ -106,18 +108,18 @@ constexpr bit_iterator<RandomAccessIt> find(
}

if (it != last.base()) {
size_type num_trailing_complementary_bits = (bv == bit0)
? _tzcnt(static_cast<word_type>(~*it))
: _tzcnt(static_cast<word_type>(*it));
return bit_iterator(it, static_cast<size_type>(num_trailing_complementary_bits));
size_type num_trailing_complementary_bits = (bv == bit0)
? std::countr_zero(static_cast<uword_type>(~*it))
: std::countr_zero(static_cast<uword_type>(*it));
return bit_iterator(it, static_cast<size_type>(num_trailing_complementary_bits));
}

// Deal with any unaligned boundaries
if (!is_last_aligned) {
size_type num_trailing_complementary_bits = (bv == bit0)
? _tzcnt(static_cast<word_type>(~*it))
: _tzcnt(static_cast<word_type>(*it));
return bit_iterator(it, static_cast<size_type>(std::min(num_trailing_complementary_bits, last.position())));
size_type num_trailing_complementary_bits = (bv == bit0)
? std::countr_zero(static_cast<uword_type>(~*it))
: std::countr_zero(static_cast<uword_type>(*it));
return bit_iterator(it, static_cast<size_type>(std::min(num_trailing_complementary_bits, last.position())));
}
return last;
}
Expand Down
Loading
Loading