Files
1brc/source/tricks.cxx
T
2026-09-09 00:52:00 -03:00

65 lines
1.7 KiB
C++

module;
#include <simd>
module tricks;
import std;
namespace brc {
std::size_t find_delim(std::string_view string, char target) {
constexpr auto width = std::simd::vec<std::uint8_t>::size();
const auto needle = std::simd::vec<std::uint8_t>(static_cast<std::uint8_t>(target));
auto i = std::size_t(0);
for (; i + width <= string.size(); i += width) {
const auto chunk = std::simd::vec<std::uint8_t>(
std::span<const std::uint8_t, width>(reinterpret_cast<const std::uint8_t*>(string.data() + i), width));
const auto mask = chunk == needle;
if (const auto bits = mask.to_bitset(); bits.any()) {
return i + std::countr_zero(bits.to_ullong());
}
}
for (; i < string.size(); ++i) {
if (string[i] == target) return i;
}
return string.size();
}
std::inplace_vector<std::size_t, 4> find_delim_batch(std::string_view string, char target) {
constexpr auto BatchSize = 4;
auto sizes = std::inplace_vector<std::size_t, BatchSize>();
constexpr auto width = std::simd::vec<std::uint8_t>::size();
const auto needle = std::simd::vec<std::uint8_t>(static_cast<std::uint8_t>(target));
std::size_t i = 0;
for (; i + width <= string.size() && sizes.size() < BatchSize; i += width) {
const auto chunk = std::simd::vec<std::uint8_t>(
std::span<const std::uint8_t, width>(reinterpret_cast<const std::uint8_t*>(string.data() + i), width));
const auto mask = chunk == needle;
auto bits = mask.to_bitset().to_ullong();
while (bits != 0 && sizes.size() < BatchSize) {
const auto bit_pos = std::countr_zero(bits);
sizes.push_back(i + bit_pos);
bits &= bits - 1;
}
}
for (; i < string.size() && sizes.size() < BatchSize; ++i) {
if (string[i] == target) {
sizes.push_back(i);
}
}
return sizes;
}
} // namespace brc