-
Notifications
You must be signed in to change notification settings - Fork 1.5k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[vector.bool] Optimize copy / move algorithms (#3353)
Co-authored-by: Stephan T. Lavavej <[email protected]>
- Loading branch information
1 parent
8f67ece
commit f6580c2
Showing
7 changed files
with
1,606 additions
and
67 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
100 changes: 100 additions & 0 deletions
100
benchmarks/src/std/containers/sequences/vector.bool/copy/test.cpp
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,100 @@ | ||
// Copyright (c) Microsoft Corporation. | ||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | ||
|
||
#include <benchmark/benchmark.h> | ||
// | ||
#include <algorithm> | ||
#include <random> | ||
#include <vector> | ||
|
||
using namespace std; | ||
|
||
static vector<bool> createRandomVector(const size_t size) { | ||
static mt19937 gen{random_device{}()}; | ||
vector<bool> result(size); | ||
generate_n(result.begin(), size, [] { return bernoulli_distribution{0.5}(gen); }); | ||
return result; | ||
} | ||
|
||
static void copy_block_aligned(benchmark::State& state) { | ||
const auto size = state.range(0); | ||
const vector<bool> source = createRandomVector(size); | ||
vector<bool> dest(size, false); | ||
|
||
for (auto _ : state) { | ||
copy(source.cbegin(), source.cend(), dest.begin()); | ||
} | ||
} | ||
|
||
static void copy_source_misaligned(benchmark::State& state) { | ||
const auto size = state.range(0); | ||
const vector<bool> source = createRandomVector(size); | ||
vector<bool> dest(size, false); | ||
|
||
for (auto _ : state) { | ||
copy(source.cbegin() + 1, source.cend(), dest.begin()); | ||
} | ||
} | ||
|
||
static void copy_dest_misaligned(benchmark::State& state) { | ||
const auto size = state.range(0); | ||
const vector<bool> source = createRandomVector(size); | ||
vector<bool> dest(size, false); | ||
|
||
for (auto _ : state) { | ||
copy(source.cbegin(), source.cend() - 1, dest.begin() + 1); | ||
} | ||
} | ||
|
||
// Special benchmark for matching char alignment | ||
static void copy_matching_alignment(benchmark::State& state) { | ||
const auto size = state.range(0); | ||
const vector<bool> source = createRandomVector(size); | ||
vector<bool> dest(size, false); | ||
|
||
for (auto _ : state) { | ||
copy(source.cbegin() + 5, source.cend(), dest.begin() + 5); | ||
} | ||
} | ||
|
||
// Special benchmarks for single block corner case | ||
static void copy_both_single_blocks(benchmark::State& state) { | ||
const vector<bool> source = createRandomVector(50); | ||
vector<bool> dest(50, false); | ||
|
||
const size_t length = 20; | ||
for (auto _ : state) { | ||
copy(source.cbegin() + 5, source.cbegin() + 5 + length, dest.begin() + 5); | ||
} | ||
} | ||
|
||
static void copy_source_single_block(benchmark::State& state) { | ||
const vector<bool> source = createRandomVector(50); | ||
vector<bool> dest(50, false); | ||
|
||
const size_t length = 20; | ||
for (auto _ : state) { | ||
copy(source.cbegin() + 5, source.cbegin() + 5 + length, dest.begin() + 25); | ||
} | ||
} | ||
|
||
static void copy_dest_single_block(benchmark::State& state) { | ||
const vector<bool> source = createRandomVector(50); | ||
vector<bool> dest(50, false); | ||
|
||
const size_t length = 20; | ||
for (auto _ : state) { | ||
copy(source.cbegin() + 25, source.cbegin() + 25 + length, dest.begin() + 5); | ||
} | ||
} | ||
|
||
BENCHMARK(copy_block_aligned)->RangeMultiplier(64)->Range(64, 64 << 10); | ||
BENCHMARK(copy_source_misaligned)->RangeMultiplier(64)->Range(64, 64 << 10); | ||
BENCHMARK(copy_dest_misaligned)->RangeMultiplier(64)->Range(64, 64 << 10); | ||
BENCHMARK(copy_matching_alignment)->RangeMultiplier(64)->Range(64, 64 << 10); | ||
|
||
BENCHMARK(copy_both_single_blocks); | ||
BENCHMARK(copy_source_single_block); | ||
BENCHMARK(copy_dest_single_block); | ||
|
||
BENCHMARK_MAIN(); |
100 changes: 100 additions & 0 deletions
100
benchmarks/src/std/containers/sequences/vector.bool/copy_n/test.cpp
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,100 @@ | ||
// Copyright (c) Microsoft Corporation. | ||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | ||
|
||
#include <benchmark/benchmark.h> | ||
// | ||
#include <algorithm> | ||
#include <random> | ||
#include <vector> | ||
|
||
using namespace std; | ||
|
||
static vector<bool> createRandomVector(const size_t size) { | ||
static mt19937 gen{random_device{}()}; | ||
vector<bool> result(size); | ||
generate_n(result.begin(), size, [] { return bernoulli_distribution{0.5}(gen); }); | ||
return result; | ||
} | ||
|
||
static void copy_n_block_aligned(benchmark::State& state) { | ||
const auto size = state.range(0); | ||
const vector<bool> source = createRandomVector(size); | ||
vector<bool> dest(size, false); | ||
|
||
for (auto _ : state) { | ||
copy_n(source.cbegin(), size, dest.begin()); | ||
} | ||
} | ||
|
||
static void copy_n_source_misaligned(benchmark::State& state) { | ||
const auto size = state.range(0); | ||
const vector<bool> source = createRandomVector(size); | ||
vector<bool> dest(size, false); | ||
|
||
for (auto _ : state) { | ||
copy_n(source.cbegin() + 1, size - 1, dest.begin()); | ||
} | ||
} | ||
|
||
static void copy_n_dest_misaligned(benchmark::State& state) { | ||
const auto size = state.range(0); | ||
const vector<bool> source = createRandomVector(size); | ||
vector<bool> dest(size, false); | ||
|
||
for (auto _ : state) { | ||
copy_n(source.cbegin(), size - 1, dest.begin() + 1); | ||
} | ||
} | ||
|
||
// Special benchmark for matching char alignment | ||
static void copy_n_matching_alignment(benchmark::State& state) { | ||
const auto size = state.range(0); | ||
const vector<bool> source = createRandomVector(size); | ||
vector<bool> dest(size, false); | ||
|
||
for (auto _ : state) { | ||
copy_n(source.cbegin() + 5, size - 5, dest.begin() + 5); | ||
} | ||
} | ||
|
||
// Special benchmarks for single block corner case | ||
static void copy_n_both_single_blocks(benchmark::State& state) { | ||
const vector<bool> source = createRandomVector(50); | ||
vector<bool> dest(50, false); | ||
|
||
const size_t length = 20; | ||
for (auto _ : state) { | ||
copy_n(source.cbegin() + 5, length, dest.begin() + 5); | ||
} | ||
} | ||
|
||
static void copy_n_source_single_block(benchmark::State& state) { | ||
const vector<bool> source = createRandomVector(50); | ||
vector<bool> dest(50, false); | ||
|
||
const size_t length = 20; | ||
for (auto _ : state) { | ||
copy_n(source.cbegin() + 5, length, dest.begin() + 25); | ||
} | ||
} | ||
|
||
static void copy_n_dest_single_block(benchmark::State& state) { | ||
const vector<bool> source = createRandomVector(50); | ||
vector<bool> dest(50, false); | ||
|
||
const size_t length = 20; | ||
for (auto _ : state) { | ||
copy_n(source.cbegin() + 25, length, dest.begin() + 5); | ||
} | ||
} | ||
|
||
BENCHMARK(copy_n_block_aligned)->RangeMultiplier(64)->Range(64, 64 << 10); | ||
BENCHMARK(copy_n_source_misaligned)->RangeMultiplier(64)->Range(64, 64 << 10); | ||
BENCHMARK(copy_n_dest_misaligned)->RangeMultiplier(64)->Range(64, 64 << 10); | ||
BENCHMARK(copy_n_matching_alignment)->RangeMultiplier(64)->Range(64, 64 << 10); | ||
|
||
BENCHMARK(copy_n_both_single_blocks); | ||
BENCHMARK(copy_n_source_single_block); | ||
BENCHMARK(copy_n_dest_single_block); | ||
|
||
BENCHMARK_MAIN(); |
100 changes: 100 additions & 0 deletions
100
benchmarks/src/std/containers/sequences/vector.bool/move/test.cpp
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,100 @@ | ||
// Copyright (c) Microsoft Corporation. | ||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | ||
|
||
#include <benchmark/benchmark.h> | ||
// | ||
#include <algorithm> | ||
#include <random> | ||
#include <vector> | ||
|
||
using namespace std; | ||
|
||
static vector<bool> createRandomVector(const size_t size) { | ||
static mt19937 gen{random_device{}()}; | ||
vector<bool> result(size); | ||
generate_n(result.begin(), size, [] { return bernoulli_distribution{0.5}(gen); }); | ||
return result; | ||
} | ||
|
||
static void move_block_aligned(benchmark::State& state) { | ||
const auto size = state.range(0); | ||
const vector<bool> source = createRandomVector(size); | ||
vector<bool> dest(size, false); | ||
|
||
for (auto _ : state) { | ||
move(source.cbegin(), source.cend(), dest.begin()); | ||
} | ||
} | ||
|
||
static void move_source_misaligned(benchmark::State& state) { | ||
const auto size = state.range(0); | ||
const vector<bool> source = createRandomVector(size); | ||
vector<bool> dest(size, false); | ||
|
||
for (auto _ : state) { | ||
move(source.cbegin() + 1, source.cend(), dest.begin()); | ||
} | ||
} | ||
|
||
static void move_dest_misaligned(benchmark::State& state) { | ||
const auto size = state.range(0); | ||
const vector<bool> source = createRandomVector(size); | ||
vector<bool> dest(size, false); | ||
|
||
for (auto _ : state) { | ||
move(source.cbegin(), source.cend() - 1, dest.begin() + 1); | ||
} | ||
} | ||
|
||
// Special benchmark for matching char alignment | ||
static void move_matching_alignment(benchmark::State& state) { | ||
const auto size = state.range(0); | ||
const vector<bool> source = createRandomVector(size); | ||
vector<bool> dest(size, false); | ||
|
||
for (auto _ : state) { | ||
move(source.cbegin() + 5, source.cend(), dest.begin() + 5); | ||
} | ||
} | ||
|
||
// Special benchmarks for single block corner case | ||
static void move_both_single_blocks(benchmark::State& state) { | ||
const vector<bool> source = createRandomVector(50); | ||
vector<bool> dest(50, false); | ||
|
||
const size_t length = 20; | ||
for (auto _ : state) { | ||
move(source.cbegin() + 5, source.cbegin() + 5 + length, dest.begin() + 5); | ||
} | ||
} | ||
|
||
static void move_source_single_block(benchmark::State& state) { | ||
const vector<bool> source = createRandomVector(50); | ||
vector<bool> dest(50, false); | ||
|
||
const size_t length = 20; | ||
for (auto _ : state) { | ||
move(source.cbegin() + 5, source.cbegin() + 5 + length, dest.begin() + 25); | ||
} | ||
} | ||
|
||
static void move_dest_single_block(benchmark::State& state) { | ||
const vector<bool> source = createRandomVector(50); | ||
vector<bool> dest(50, false); | ||
|
||
const size_t length = 20; | ||
for (auto _ : state) { | ||
move(source.cbegin() + 25, source.cbegin() + 25 + length, dest.begin() + 5); | ||
} | ||
} | ||
|
||
BENCHMARK(move_block_aligned)->RangeMultiplier(64)->Range(64, 64 << 10); | ||
BENCHMARK(move_source_misaligned)->RangeMultiplier(64)->Range(64, 64 << 10); | ||
BENCHMARK(move_dest_misaligned)->RangeMultiplier(64)->Range(64, 64 << 10); | ||
BENCHMARK(move_matching_alignment)->RangeMultiplier(64)->Range(64, 64 << 10); | ||
|
||
BENCHMARK(move_both_single_blocks); | ||
BENCHMARK(move_source_single_block); | ||
BENCHMARK(move_dest_single_block); | ||
|
||
BENCHMARK_MAIN(); |
Oops, something went wrong.