Skip to content

Commit d959668

Browse files
Fixes for benchmark, ostream and gitignore (#5)
1 parent ad17ea8 commit d959668

File tree

5 files changed

+157
-153
lines changed

5 files changed

+157
-153
lines changed

.gitignore

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,6 @@
55
!.gitignore
66
!.travis.yml
77
bazel-*
8-
!bazel-*.sh
98
compile_commands.json
109
perf.data*
1110
build
12-
13-
/bazel-phtree-cpp-public/

phtree/benchmark/benchmark_util.h

Lines changed: 72 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -32,10 +32,11 @@ template <dimension_t DIM>
3232
auto CreateDataCUBE = [](auto& points,
3333
size_t num_entities,
3434
std::uint32_t seed,
35-
double world_length,
35+
double world_mininum,
36+
double world_maximum,
3637
auto set_coordinate) {
3738
std::default_random_engine random_engine{seed};
38-
std::uniform_real_distribution<> distribution(0, world_length);
39+
std::uniform_real_distribution<> distribution(world_mininum, world_maximum);
3940
for (size_t i = 0; i < num_entities; ++i) {
4041
auto& p = points[i];
4142
for (dimension_t d = 0; d < DIM; ++d) {
@@ -48,15 +49,17 @@ template <dimension_t DIM>
4849
auto CreateDataCLUSTER = [](auto& points,
4950
size_t num_entities,
5051
std::uint32_t seed,
51-
double world_length,
52+
double world_mininum,
53+
double world_maximum,
5254
auto set_coordinate) {
5355
std::default_random_engine random_engine{seed};
54-
std::uniform_real_distribution<> distribution(0, world_length);
56+
std::uniform_real_distribution<> distribution(world_mininum, world_maximum);
5557
// SIGMA = 0.0001
5658
std::normal_distribution<> gauss_distribution(0, 0.0001);
5759
const int NUM_PT_PER_CLUSTER = 100;
5860
// 1000 points per cluster, minimum is 1 cluster.
5961
size_t num_cluster = std::max(1, (int)(num_entities / NUM_PT_PER_CLUSTER));
62+
const double world_length = world_maximum - world_mininum;
6063

6164
// loop over clusters
6265
PhPointD<DIM> cp; // center point of cluster
@@ -71,33 +74,35 @@ auto CreateDataCLUSTER = [](auto& points,
7174
for (dimension_t d = 0; d < DIM; ++d) {
7275
// double x = (R.nextGaussian() - 0.5) * GAUSS_SIGMA; // confine to small rectangle
7376
double x = gauss_distribution(random_engine);
74-
x *= world_length; // stretch if domain>1.0
75-
x += cp[d]; // offset of cluster
77+
x *= world_length + world_mininum; // stretch if domain>1.0
78+
x += cp[d]; // offset of cluster
7679
set_coordinate(p, d, x);
7780
}
7881
}
7982
}
8083
};
8184

82-
auto CreateDuplicates = [](auto& points, size_t num_entities, std::uint32_t seed) {
83-
std::default_random_engine random_engine{seed};
84-
std::uniform_int_distribution<> distribution(0, points.size());
85-
for (int i = points.size(); i < num_entities; ++i) {
86-
// copy some random other point or box
87-
points[i] = points[distribution(random_engine)];
88-
}
89-
};
85+
auto CreateDuplicates =
86+
[](auto& points, size_t num_unique_entries, size_t num_total_entities, std::uint32_t seed) {
87+
std::default_random_engine random_engine{seed};
88+
std::uniform_int_distribution<> distribution(0, num_unique_entries);
89+
for (int i = num_unique_entries; i < num_total_entities; ++i) {
90+
// copy some random other point or box
91+
points[i] = points[distribution(random_engine)];
92+
}
93+
};
9094
} // namespace
9195

9296
enum TestGenerator { CUBE, CLUSTER };
9397

9498
template <dimension_t DIM>
95-
auto CreatePointData = [](auto& points,
96-
TestGenerator test_generator,
97-
size_t num_entities,
98-
int seed,
99-
double world_length,
100-
double fraction_of_duplicates = 0.) {
99+
auto CreatePointDataMinMax = [](auto& points,
100+
TestGenerator test_generator,
101+
size_t num_entities,
102+
int seed,
103+
double world_minimum,
104+
double world_maximum,
105+
double fraction_of_duplicates) {
101106
auto set_coordinate_lambda = [](auto& p, dimension_t dim, auto value) { p[dim] = value; };
102107
// Create at least 1 unique point
103108
// Note that the following point generator is likely, but not guaranteed, to created unique
@@ -106,28 +111,30 @@ auto CreatePointData = [](auto& points,
106111
points.reserve(num_entities);
107112
switch (test_generator) {
108113
case CUBE:
109-
CreateDataCUBE<DIM>(points, num_unique_entries, seed, world_length, set_coordinate_lambda);
114+
CreateDataCUBE<DIM>(
115+
points, num_unique_entries, seed, world_minimum, world_maximum, set_coordinate_lambda);
110116
break;
111117
case CLUSTER:
112118
CreateDataCLUSTER<DIM>(
113-
points, num_unique_entries, seed, world_length, set_coordinate_lambda);
119+
points, num_unique_entries, seed, world_minimum, world_maximum, set_coordinate_lambda);
114120
break;
115121
default:
116122
assert(false);
117123
}
118124

119125
// Create duplicates
120-
CreateDuplicates(points, num_entities, seed);
126+
CreateDuplicates(points, num_unique_entries, num_entities, seed);
121127
};
122128

123129
template <dimension_t DIM>
124-
auto CreateBoxData = [](auto& points,
125-
TestGenerator test_generator,
126-
size_t num_entities,
127-
int seed,
128-
double world_length,
129-
double box_length,
130-
double fraction_of_duplicates = 0.) {
130+
auto CreateBoxDataMinMax = [](auto& points,
131+
TestGenerator test_generator,
132+
size_t num_entities,
133+
int seed,
134+
double world_minimum,
135+
double world_maximum,
136+
double box_length,
137+
double fraction_of_duplicates) {
131138
auto set_coordinate_lambda = [box_length](auto& p, dimension_t dim, auto value) {
132139
p.min()[dim] = value;
133140
p.max()[dim] = value + box_length;
@@ -139,19 +146,51 @@ auto CreateBoxData = [](auto& points,
139146
points.reserve(num_entities);
140147
switch (test_generator) {
141148
case CUBE:
142-
CreateDataCUBE<DIM>(points, num_unique_entries, seed, world_length, set_coordinate_lambda);
149+
CreateDataCUBE<DIM>(
150+
points, num_unique_entries, seed, world_minimum, world_maximum, set_coordinate_lambda);
143151
break;
144152
case CLUSTER:
145153
CreateDataCLUSTER<DIM>(
146-
points, num_unique_entries, seed, world_length, set_coordinate_lambda);
154+
points, num_unique_entries, seed, world_minimum, world_maximum, set_coordinate_lambda);
147155
break;
148156
default:
149157
assert(false);
150158
}
151159

152160
// Create duplicates
153-
CreateDuplicates(points, num_entities, seed);
161+
CreateDuplicates(points, num_unique_entries, num_entities, seed);
162+
};
163+
164+
template <dimension_t DIM>
165+
auto CreatePointData = [](auto& points,
166+
TestGenerator test_generator,
167+
size_t num_entities,
168+
int seed,
169+
double world_length,
170+
double fraction_of_duplicates = 0.) {
171+
CreatePointDataMinMax<DIM>(
172+
points, test_generator, num_entities, seed, 0, world_length, fraction_of_duplicates);
154173
};
174+
175+
template <dimension_t DIM>
176+
auto CreateBoxData = [](auto& points,
177+
TestGenerator test_generator,
178+
size_t num_entities,
179+
int seed,
180+
double world_length,
181+
double box_length,
182+
double fraction_of_duplicates = 0.) {
183+
CreateBoxDataMinMax<DIM>(
184+
points,
185+
test_generator,
186+
num_entities,
187+
seed,
188+
0,
189+
world_length,
190+
box_length,
191+
fraction_of_duplicates);
192+
};
193+
155194
} // namespace improbable::phtree::phbenchmark
156195

157196
#endif // PHTREE_BENCHMARK_UTIL_H

phtree/benchmark/update_box_d_benchmark.cc

Lines changed: 43 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -18,14 +18,16 @@
1818
#include <benchmark/benchmark.h>
1919
#include <spdlog/spdlog.h>
2020
#include <spdlog/sinks/ansicolor_sink.h>
21-
#include <random>
2221

2322
using namespace improbable;
2423
using namespace improbable::phtree;
2524
using namespace improbable::phtree::phbenchmark;
2625

2726
namespace {
2827

28+
constexpr int UPDATES_PER_ROUND = 1000;
29+
constexpr double MOVE_DISTANCE = 10;
30+
2931
const double GLOBAL_MAX = 10000;
3032
const double BOX_LEN = 10;
3133

@@ -46,25 +48,26 @@ class IndexBenchmark {
4648
benchmark::State& state,
4749
TestGenerator data_type,
4850
int num_entities,
49-
int updates_per_round,
50-
double move_distance);
51+
int updates_per_round = UPDATES_PER_ROUND,
52+
double move_distance = MOVE_DISTANCE);
5153

5254
void Benchmark(benchmark::State& state);
5355

5456
private:
5557
void SetupWorld(benchmark::State& state);
56-
void BuildUpdate(std::vector<UpdateOp<DIM>>& updates);
57-
void UpdateWorld(benchmark::State& state, std::vector<UpdateOp<DIM>>& updates);
58+
void BuildUpdates();
59+
void UpdateWorld(benchmark::State& state);
5860

5961
const TestGenerator data_type_;
6062
const int num_entities_;
6163
const int updates_per_round_;
6264
const double move_distance_;
6365

6466
PhTreeBoxD<DIM, scalar_t> tree_;
65-
std::default_random_engine random_engine_;
66-
std::uniform_real_distribution<> cube_distribution_;
6767
std::vector<PhBoxD<DIM>> boxes_;
68+
std::vector<UpdateOp<DIM>> updates_;
69+
std::default_random_engine random_engine_;
70+
std::uniform_int_distribution<> entity_id_distribution_;
6871
};
6972

7073
template <dimension_t DIM>
@@ -78,9 +81,10 @@ IndexBenchmark<DIM>::IndexBenchmark(
7881
, num_entities_(num_entities)
7982
, updates_per_round_(updates_per_round)
8083
, move_distance_(move_distance)
81-
, random_engine_{1}
82-
, cube_distribution_{0, GLOBAL_MAX}
83-
, boxes_(num_entities) {
84+
, boxes_(num_entities)
85+
, updates_(updates_per_round)
86+
, random_engine_{0}
87+
, entity_id_distribution_{0, num_entities - 1} {
8488
auto console_sink = std::make_shared<spdlog::sinks::ansicolor_stdout_sink_mt>();
8589
spdlog::set_default_logger(
8690
std::make_shared<spdlog::logger>("", spdlog::sinks_init_list({console_sink})));
@@ -91,41 +95,12 @@ IndexBenchmark<DIM>::IndexBenchmark(
9195

9296
template <dimension_t DIM>
9397
void IndexBenchmark<DIM>::Benchmark(benchmark::State& state) {
94-
std::vector<UpdateOp<DIM>> updates;
95-
updates.reserve(updates_per_round_);
9698
for (auto _ : state) {
9799
state.PauseTiming();
98-
BuildUpdate(updates);
100+
BuildUpdates();
99101
state.ResumeTiming();
100102

101-
UpdateWorld(state, updates);
102-
103-
state.PauseTiming();
104-
for (auto& update : updates) {
105-
boxes_[update.id_] = update.new_;
106-
}
107-
state.ResumeTiming();
108-
}
109-
}
110-
111-
template <dimension_t DIM>
112-
void IndexBenchmark<DIM>::BuildUpdate(std::vector<UpdateOp<DIM>>& updates) {
113-
// Use Delta to avoid moving points in insertion order (not that it matters for the PH-Tree, but
114-
// we may test other trees as well.
115-
int box_id_increment = num_entities_ / updates_per_round_; // int division
116-
int box_id = 0;
117-
updates.clear();
118-
for (size_t i = 0; i < updates_per_round_; ++i) {
119-
assert(box_id >= 0);
120-
assert(box_id < boxes_.size());
121-
auto& old_box = boxes_[box_id];
122-
auto update = UpdateOp<DIM>{box_id, old_box, old_box};
123-
for (dimension_t d = 0; d < DIM; ++d) {
124-
update.new_.min()[d] += move_distance_;
125-
update.new_.max()[d] += move_distance_;
126-
}
127-
updates.emplace_back(update);
128-
box_id += box_id_increment;
103+
UpdateWorld(state);
129104
}
130105
}
131106

@@ -143,10 +118,24 @@ void IndexBenchmark<DIM>::SetupWorld(benchmark::State& state) {
143118
}
144119

145120
template <dimension_t DIM>
146-
void IndexBenchmark<DIM>::UpdateWorld(
147-
benchmark::State& state, std::vector<UpdateOp<DIM>>& updates) {
121+
void IndexBenchmark<DIM>::BuildUpdates() {
122+
for (auto& update : updates_) {
123+
int box_id = entity_id_distribution_(random_engine_);
124+
update.id_ = box_id;
125+
update.old_ = boxes_[box_id];
126+
for (dimension_t d = 0; d < DIM; ++d) {
127+
update.new_.min()[d] = update.old_.min()[d] + move_distance_;
128+
update.new_.max()[d] = update.old_.max()[d] + move_distance_;
129+
}
130+
// update reference data
131+
boxes_[box_id] = update.new_;
132+
}
133+
}
134+
135+
template <dimension_t DIM>
136+
void IndexBenchmark<DIM>::UpdateWorld(benchmark::State& state) {
148137
size_t initial_tree_size = tree_.size();
149-
for (auto& update : updates) {
138+
for (auto& update : updates_) {
150139
size_t result_erase = tree_.erase(update.old_);
151140
auto result_emplace = tree_.emplace(update.new_, update.id_);
152141
assert(result_erase == 1);
@@ -155,7 +144,7 @@ void IndexBenchmark<DIM>::UpdateWorld(
155144

156145
// For normal indexes we expect num_entities==size(), but the PhTree<Map<...>> index has
157146
// size() as low as (num_entities-duplicates).
158-
if (tree_.size() > num_entities_ || tree_.size() < initial_tree_size - updates_per_round_) {
147+
if (tree_.size() > num_entities_ || tree_.size() + updates_per_round_ < initial_tree_size) {
159148
spdlog::error("Invalid index size after update: {}/{}", tree_.size(), num_entities_);
160149
}
161150

@@ -167,35 +156,35 @@ void IndexBenchmark<DIM>::UpdateWorld(
167156

168157
template <typename... Arguments>
169158
void PhTree3D(benchmark::State& state, Arguments&&... arguments) {
170-
IndexBenchmark<4> benchmark{state, arguments...};
159+
IndexBenchmark<3> benchmark{state, arguments...};
171160
benchmark.Benchmark(state);
172161
}
173162

174163
// index type, scenario name, data_type, num_entities, updates_per_round, move_distance
175164
// PhTree3D CUBE
176-
BENCHMARK_CAPTURE(PhTree3D, UPDATE_CU_100_of_1K, TestGenerator::CUBE, 1000, 100, 10.)
165+
BENCHMARK_CAPTURE(PhTree3D, UPDATE_CU_100_of_1K, TestGenerator::CUBE, 1000)
177166
->Unit(benchmark::kMillisecond);
178167

179-
BENCHMARK_CAPTURE(PhTree3D, UPDATE_CU_100_of_10K, TestGenerator::CUBE, 10000, 100, 10.)
168+
BENCHMARK_CAPTURE(PhTree3D, UPDATE_CU_100_of_10K, TestGenerator::CUBE, 10000)
180169
->Unit(benchmark::kMillisecond);
181170

182-
BENCHMARK_CAPTURE(PhTree3D, UPDATE_CU_100_of_100K, TestGenerator::CUBE, 100000, 100, 10.)
171+
BENCHMARK_CAPTURE(PhTree3D, UPDATE_CU_100_of_100K, TestGenerator::CUBE, 100000)
183172
->Unit(benchmark::kMillisecond);
184173

185-
BENCHMARK_CAPTURE(PhTree3D, UPDATE_CU_100_of_1M, TestGenerator::CUBE, 1000000, 100, 10.)
174+
BENCHMARK_CAPTURE(PhTree3D, UPDATE_CU_100_of_1M, TestGenerator::CUBE, 1000000)
186175
->Unit(benchmark::kMillisecond);
187176

188177
// PhTree3D CLUSTER
189-
BENCHMARK_CAPTURE(PhTree3D, UPDATE_CL_100_of_1K, TestGenerator::CLUSTER, 1000, 100, 10.)
178+
BENCHMARK_CAPTURE(PhTree3D, UPDATE_CL_100_of_1K, TestGenerator::CLUSTER, 1000)
190179
->Unit(benchmark::kMillisecond);
191180

192-
BENCHMARK_CAPTURE(PhTree3D, UPDATE_CL_100_of_10K, TestGenerator::CLUSTER, 10000, 100, 10.)
181+
BENCHMARK_CAPTURE(PhTree3D, UPDATE_CL_100_of_10K, TestGenerator::CLUSTER, 10000)
193182
->Unit(benchmark::kMillisecond);
194183

195-
BENCHMARK_CAPTURE(PhTree3D, UPDATE_CL_100_of_100K, TestGenerator::CLUSTER, 100000, 100, 10.)
184+
BENCHMARK_CAPTURE(PhTree3D, UPDATE_CL_100_of_100K, TestGenerator::CLUSTER, 100000)
196185
->Unit(benchmark::kMillisecond);
197186

198-
BENCHMARK_CAPTURE(PhTree3D, UPDATE_CL_100_of_1M, TestGenerator::CLUSTER, 1000000, 100, 10.)
187+
BENCHMARK_CAPTURE(PhTree3D, UPDATE_CL_100_of_1M, TestGenerator::CLUSTER, 1000000)
199188
->Unit(benchmark::kMillisecond);
200189

201190
BENCHMARK_MAIN();

0 commit comments

Comments
 (0)