Skip to content

Commit

Permalink
ARROW-5557: [C++] Add VisitBits benchmark
Browse files Browse the repository at this point in the history
Author: Antoine Pitrou <[email protected]>

Closes apache#4550 from pitrou/ARROW-5557-visit-bits-benchmark and squashes the following commits:

9d502b2 <Antoine Pitrou> ARROW-5557:  Add VisitBits benchmark
  • Loading branch information
pitrou authored and wesm committed Jun 18, 2019
1 parent 5c562e8 commit bffe31b
Show file tree
Hide file tree
Showing 6 changed files with 75 additions and 17 deletions.
3 changes: 3 additions & 0 deletions cpp/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -697,6 +697,9 @@ if(ARROW_BUILD_BENCHMARKS)

set(ARROW_BENCHMARK_LINK_LIBS benchmark::benchmark_main benchmark::benchmark
${ARROW_TEST_LINK_LIBS})
if(WIN32)
set(ARROW_BENCHMARK_LINK_LIBS Shlwapi.dll ${ARROW_BENCHMARK_LINK_LIBS})
endif()
endif()

set(ARROW_SYSTEM_LINK_LIBS)
Expand Down
10 changes: 6 additions & 4 deletions cpp/src/arrow/builder-benchmark.cc
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,7 @@ static void BuildChunkedBinaryArray(

static void BuildFixedSizeBinaryArray(
benchmark::State& state) { // NOLINT non-const reference
auto type = fixed_size_binary(kBinaryView.size());
auto type = fixed_size_binary(static_cast<int32_t>(kBinaryView.size()));

for (auto _ : state) {
FixedSizeBinaryBuilder builder(type);
Expand Down Expand Up @@ -227,7 +227,8 @@ static std::vector<Integer> MakeRandomIntDictFodder() {
[&]() { return static_cast<Integer>(values_dist(gen)); });
}
{
std::uniform_int_distribution<int32_t> indices_dist(0, kDistinctElements - 1);
std::uniform_int_distribution<int32_t> indices_dist(
0, static_cast<int32_t>(kDistinctElements - 1));
std::generate(values.begin(), values.end(),
[&]() { return values_dict[indices_dist(gen)]; });
}
Expand Down Expand Up @@ -262,7 +263,8 @@ static std::vector<std::string> MakeStringDictFodder() {
});
}
{
std::uniform_int_distribution<int32_t> indices_dist(0, kDistinctElements - 1);
std::uniform_int_distribution<int32_t> indices_dist(
0, static_cast<int32_t>(kDistinctElements - 1));
std::generate(values.begin(), values.end(),
[&] { return values_dict[indices_dist(gen)]; });
}
Expand Down Expand Up @@ -311,7 +313,7 @@ static void BuildStringDictionaryArray(
benchmark::State& state) { // NOLINT non-const reference
const auto fodder = MakeStringDictFodder();
auto fodder_size =
std::accumulate(fodder.begin(), fodder.end(), 0UL,
std::accumulate(fodder.begin(), fodder.end(), 0ULL,
[&](size_t acc, const std::string& s) { return acc + s.size(); });

for (auto _ : state) {
Expand Down
6 changes: 3 additions & 3 deletions cpp/src/arrow/csv/parser-benchmark.cc
Original file line number Diff line number Diff line change
Expand Up @@ -33,11 +33,11 @@ namespace csv {
const char* one_row = "abc,\"d,f\",12.34,\n";
const char* one_row_escaped = "abc,d\\,f,12.34,\n";

size_t num_rows = (1024 * 64) / strlen(one_row);
const auto num_rows = static_cast<int32_t>((1024 * 64) / strlen(one_row));

static std::string BuildCSVData(const std::string& row, size_t repeat) {
static std::string BuildCSVData(const std::string& row, int32_t repeat) {
std::stringstream ss;
for (size_t i = 0; i < repeat; ++i) {
for (int32_t i = 0; i < repeat; ++i) {
ss << row;
}
return ss.str();
Expand Down
67 changes: 59 additions & 8 deletions cpp/src/arrow/util/bit-util-benchmark.cc
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,30 @@ static void BenchmarkBitmapReader(benchmark::State& state, int64_t nbytes) {
state.SetBytesProcessed(2LL * state.iterations() * nbytes);
}

template <typename VisitBitsFunctorType>
static void BenchmarkVisitBits(benchmark::State& state, int64_t nbytes) {
std::shared_ptr<Buffer> buffer = CreateRandomBuffer(nbytes);

const int64_t num_bits = nbytes * 8;
const uint8_t* bitmap = buffer->data();

for (auto _ : state) {
{
int64_t total = 0;
const auto visit = [&total](bool value) -> void { total += value; };
VisitBitsFunctorType()(bitmap, 0, num_bits, visit);
benchmark::DoNotOptimize(total);
}
{
int64_t total = 0;
const auto visit = [&total](bool value) -> void { total += value; };
VisitBitsFunctorType()(bitmap, 0, num_bits, visit);
benchmark::DoNotOptimize(total);
}
}
state.SetBytesProcessed(2LL * state.iterations() * nbytes);
}

constexpr bool pattern[] = {false, false, false, true, true, true};
static_assert(
(sizeof(pattern) / sizeof(pattern[0])) % 8 != 0,
Expand Down Expand Up @@ -204,6 +228,22 @@ struct GenerateBitsUnrolledFunctor {
}
};

struct VisitBitsFunctor {
template <class Visitor>
void operator()(const uint8_t* bitmap, int64_t start_offset, int64_t length,
Visitor&& g) {
return internal::VisitBits(bitmap, start_offset, length, g);
}
};

struct VisitBitsUnrolledFunctor {
template <class Visitor>
void operator()(const uint8_t* bitmap, int64_t start_offset, int64_t length,
Visitor&& g) {
return internal::VisitBitsUnrolled(bitmap, start_offset, length, g);
}
};

static void GenerateBits(benchmark::State& state) {
BenchmarkGenerateBits<GenerateBitsFunctor>(state, state.range(0));
}
Expand All @@ -212,6 +252,14 @@ static void GenerateBitsUnrolled(benchmark::State& state) {
BenchmarkGenerateBits<GenerateBitsUnrolledFunctor>(state, state.range(0));
}

static void VisitBits(benchmark::State& state) {
BenchmarkVisitBits<VisitBitsFunctor>(state, state.range(0));
}

static void VisitBitsUnrolled(benchmark::State& state) {
BenchmarkVisitBits<VisitBitsUnrolledFunctor>(state, state.range(0));
}

constexpr int64_t kBufferSize = 1024 * 8;

template <int64_t Offset = 0>
Expand Down Expand Up @@ -246,29 +294,32 @@ static void CopyBitmapWithOffset(benchmark::State& state) { // NOLINT non-const
}

#ifdef ARROW_WITH_BENCHMARKS_REFERENCE

static void ReferenceNaiveBitmapReader(benchmark::State& state) {
BenchmarkBitmapReader<NaiveBitmapReader>(state, state.range(0));
}

BENCHMARK(ReferenceNaiveBitmapReader)->Arg(kBufferSize);
#endif

BENCHMARK(BitmapReader)->Arg(kBufferSize);
BENCHMARK(VisitBits)->Arg(kBufferSize);
BENCHMARK(VisitBitsUnrolled)->Arg(kBufferSize);

#ifdef ARROW_WITH_BENCHMARKS_REFERENCE
static void ReferenceNaiveBitmapWriter(benchmark::State& state) {
BenchmarkBitmapWriter<NaiveBitmapWriter>(state, state.range(0));
}

BENCHMARK(ReferenceNaiveBitmapWriter)->Arg(kBufferSize);
BENCHMARK(ReferenceNaiveBitmapReader)->Arg(kBufferSize);

#endif

BENCHMARK(CopyBitmapWithoutOffset)->Arg(kBufferSize);
BENCHMARK(CopyBitmapWithOffset)->Arg(kBufferSize);

BENCHMARK(BitmapReader)->Arg(kBufferSize);
BENCHMARK(BitmapWriter)->Arg(kBufferSize);

BENCHMARK(FirstTimeBitmapWriter)->Arg(kBufferSize);
BENCHMARK(GenerateBits)->Arg(kBufferSize);
BENCHMARK(GenerateBitsUnrolled)->Arg(kBufferSize);

BENCHMARK(CopyBitmapWithoutOffset)->Arg(kBufferSize);
BENCHMARK(CopyBitmapWithOffset)->Arg(kBufferSize);

} // namespace BitUtil
} // namespace arrow
4 changes: 3 additions & 1 deletion cpp/src/arrow/util/hashing.h
Original file line number Diff line number Diff line change
Expand Up @@ -716,10 +716,12 @@ class BinaryMemoTable : public MemoTable {

int32_t left_offset = offsets_[start];

// Ensure that the data_length is exactly missing width_size bytes to fit
// Ensure that the data length is exactly missing width_size bytes to fit
// in the expected output (n_values * width_size).
#ifndef NDEBUG
int64_t data_length = values_.size() - static_cast<size_t>(left_offset);
assert(data_length + width_size == out_size);
#endif

auto in_data = values_.data() + left_offset;
// The null use 0-length in the data, slice the data in 2 and skip by
Expand Down
2 changes: 1 addition & 1 deletion cpp/src/arrow/util/thread-pool-benchmark.cc
Original file line number Diff line number Diff line change
Expand Up @@ -172,7 +172,7 @@ static void ThreadPoolSpawn_Customize(benchmark::internal::Benchmark* b) {
// This benchmark simply provides a baseline indicating the raw cost of our workload
// depending on the workload size. Number of items / second in this (serial)
// benchmark can be compared to the numbers obtained in ThreadPoolSpawn.
static void WorkloadCost(benchmark::State& state) {
static void ReferenceWorkloadCost(benchmark::State& state) {
const auto workload_size = static_cast<int32_t>(state.range(0));

Workload workload(workload_size);
Expand Down

0 comments on commit bffe31b

Please sign in to comment.