Project
Loading...
Searching...
No Matches
benchmark_FullVsDiff.cxx
Go to the documentation of this file.
1// Copyright 2019-2020 CERN and copyright holders of ALICE O2.
2// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders.
3// All rights not expressly granted are reserved.
4//
5// This software is distributed under the terms of the GNU General Public
6// License v3 (GPL Version 3), copied verbatim in the file "COPYING".
7//
8// In applying this license CERN does not waive the privileges and immunities
9// granted to it by virtue of its status as an Intergovernmental Organization
10// or submit itself to any jurisdiction.
11#include <benchmark/benchmark.h>
12
13#include <TObjArray.h>
14#include <TH1.h>
15#include <TH2.h>
16#include <TH3.h>
17#include <TTree.h>
18#include <THnSparse.h>
19#include <TF1.h>
20#include <TF2.h>
21#include <TF3.h>
22#include <TRandom.h>
23#include <TRandomGen.h>
24#include <chrono>
25#include <ctime>
26
27const size_t entriesInDiff = 50;
28const size_t entriesInFull = 5000;
29const size_t collectionSize = 100;
30
31#define DIFF_OBJECTS 0
32#define FULL_OBJECTS 1
33
34static void BM_MergingTH1I(benchmark::State& state)
35{
36 const size_t entries = state.range(0) == FULL_OBJECTS ? entriesInFull : entriesInDiff;
37 const size_t bins = 62500; // makes 250kB
38
39 TCollection* collection = new TObjArray();
40 collection->SetOwner(true);
41 TF1* uni = new TF1("uni", "1", 0, 1000000);
42 for (size_t i = 0; i < collectionSize; i++) {
43 TH1I* h = new TH1I(("test" + std::to_string(i)).c_str(), "test", bins, 0, 1000000);
44 h->FillRandom("uni", entries);
45 collection->Add(h);
46 }
47
48 TH1I* m = new TH1I("merged", "merged", bins, 0, 1000000);
49 // avoid memory overcommitment by doing something with data.
50 for (size_t i = 0; i < bins; i++) {
51 m->SetBinContent(i, 1);
52 }
53
54 for (auto _ : state) {
55 if (state.range(0) == FULL_OBJECTS) {
56 m->Reset();
57 }
58
59 auto start = std::chrono::high_resolution_clock::now();
60 m->Merge(collection, "-NOCHECK");
61 auto end = std::chrono::high_resolution_clock::now();
62
63 auto elapsed_seconds = std::chrono::duration_cast<std::chrono::duration<double>>(end - start);
64 state.SetIterationTime(elapsed_seconds.count());
65 }
66
67 delete collection;
68 delete m;
69 delete uni;
70}
71
72static void BM_MergingTH2I(benchmark::State& state)
73{
74 const size_t entries = state.range(0) == FULL_OBJECTS ? entriesInFull : entriesInDiff;
75 size_t bins = 250; // 250 bins * 250 bins * 4B makes 250kB
76
77 TCollection* collection = new TObjArray();
78 collection->SetOwner(true);
79 TF2* uni = new TF2("uni", "1", 0, 1000000, 0, 1000000);
80 for (size_t i = 0; i < collectionSize; i++) {
81 TH2I* h = new TH2I(("test" + std::to_string(i)).c_str(), "test", bins, 0, 1000000, bins, 0, 1000000);
82 h->FillRandom("uni", entries);
83 collection->Add(h);
84 }
85
86 TH2I* m = new TH2I("merged", "merged", bins, 0, 1000000, bins, 0, 1000000);
87 // avoid memory overcommitment by doing something with data.
88 for (size_t i = 0; i < bins; i++) {
89 m->SetBinContent(i, 1);
90 }
91
92 for (auto _ : state) {
93 if (state.range(0) == FULL_OBJECTS) {
94 m->Reset();
95 }
96
97 auto start = std::chrono::high_resolution_clock::now();
98 m->Merge(collection, "-NOCHECK");
99 auto end = std::chrono::high_resolution_clock::now();
100
101 auto elapsed_seconds = std::chrono::duration_cast<std::chrono::duration<double>>(end - start);
102 state.SetIterationTime(elapsed_seconds.count());
103 }
104
105 delete collection;
106 delete m;
107}
108
109static void BM_MergingTH3I(benchmark::State& state)
110{
111 const size_t entries = state.range(0) == FULL_OBJECTS ? entriesInFull : entriesInDiff;
112 size_t bins = 40; // 40 bins * 40 bins * 40 bins * 4B makes 256kB
113
114 TCollection* collection = new TObjArray();
115 collection->SetOwner(true);
116 TF3* uni = new TF3("uni", "1", 0, 1000000, 0, 1000000, 0, 1000000);
117 for (size_t i = 0; i < collectionSize; i++) {
118 TH3I* h = new TH3I(("test" + std::to_string(i)).c_str(), "test",
119 bins, 0, 1000000,
120 bins, 0, 1000000,
121 bins, 0, 1000000);
122 h->FillRandom("uni", entries);
123 collection->Add(h);
124 }
125
126 TH3I* m = new TH3I("merged", "merged", bins, 0, 1000000, bins, 0, 1000000, bins, 0, 1000000);
127 // avoid memory overcommitment by doing something with data.
128 for (size_t i = 0; i < bins; i++) {
129 m->SetBinContent(i, 1);
130 }
131
132 for (auto _ : state) {
133 if (state.range(0) == FULL_OBJECTS) {
134 m->Reset();
135 }
136
137 auto start = std::chrono::high_resolution_clock::now();
138 m->Merge(collection, "-NOCHECK");
139 auto end = std::chrono::high_resolution_clock::now();
140
141 auto elapsed_seconds = std::chrono::duration_cast<std::chrono::duration<double>>(end - start);
142 state.SetIterationTime(elapsed_seconds.count());
143 }
144
145 delete collection;
146 delete m;
147}
148
149static void BM_MergingTHnSparse(benchmark::State& state)
150{
151 const size_t entries = state.range(0) == FULL_OBJECTS ? entriesInFull : entriesInDiff;
152
153 const Double_t min = 0.0;
154 const Double_t max = 1000000.0;
155 const size_t dim = 10;
156 const Int_t bins = 250;
157 const Int_t binsDims[dim] = {bins, bins, bins, bins, bins, bins, bins, bins, bins, bins};
158 const Double_t mins[dim] = {min, min, min, min, min, min, min, min, min, min};
159 const Double_t maxs[dim] = {max, max, max, max, max, max, max, max, max, max};
160
161 TRandomMixMax gen;
162 gen.SetSeed(std::random_device()());
163 Double_t randomArray[dim];
164 auto* m = new THnSparseI("merged", "merged", dim, binsDims, mins, maxs);
165 for (auto _ : state) {
166
167 TCollection* collection = new TObjArray();
168 collection->SetOwner(true);
169 for (size_t i = 0; i < collectionSize; i++) {
170
171 auto* h = new THnSparseI(("test" + std::to_string(i)).c_str(), "test", dim, binsDims, mins, maxs);
172 for (size_t entry = 0; entry < entries; entry++) {
173 gen.RndmArray(dim, randomArray);
174 for (double& r : randomArray) {
175 r *= max;
176 }
177 h->Fill(randomArray);
178 }
179 collection->Add(h);
180 }
181
182 if (state.range(0) == FULL_OBJECTS) {
183 m->Reset();
184 }
185
186 auto start = std::chrono::high_resolution_clock::now();
187 m->Merge(collection);
188 auto end = std::chrono::high_resolution_clock::now();
189
190 auto elapsed_seconds = std::chrono::duration_cast<std::chrono::duration<double>>(end - start);
191 state.SetIterationTime(elapsed_seconds.count());
192
193 delete collection;
194 }
195 delete m;
196}
197
198static void BM_MergingTTree(benchmark::State& state)
199{
200 const size_t entries = state.range(0) == FULL_OBJECTS ? entriesInFull : entriesInDiff;
201
202 struct format1 {
203 Int_t a;
204 Long64_t b;
205 Float_t c;
206 Double_t d;
207 } branch1;
208 ULong64_t branch2;
209
210 auto createTree = [&](std::string name) -> TTree* {
211 TTree* tree = new TTree();
212 tree->SetName(name.c_str());
213 tree->Branch("b1", &branch1, "a/I:b/L:c/F:d/D");
214 tree->Branch("b2", &branch2);
215 return tree;
216 };
217
218 TRandomMixMax gen;
219 gen.SetSeed(std::random_device()());
220 Double_t randomArray[5];
221 TTree* merged = createTree("merged");
222
223 for (auto _ : state) {
224 TCollection* collection = new TObjArray();
225 collection->SetOwner(true);
226 for (size_t i = 0; i < collectionSize; i++) {
227 TTree* t = createTree(std::to_string(i));
228 for (size_t entry = 0; entry < entries; entry++) {
229 gen.RndmArray(5, randomArray);
230 branch1 = {static_cast<Int_t>(randomArray[0]), static_cast<Long64_t>(randomArray[1]), static_cast<Float_t>(randomArray[2]), randomArray[3]};
231 branch2 = randomArray[4];
232 t->Fill();
233 }
234 collection->Add(t);
235 }
236
237 if (state.range(0) == FULL_OBJECTS) {
238 merged->Reset();
239 }
240
241 auto start = std::chrono::high_resolution_clock::now();
242 merged->Merge(collection, "-NOCHECK");
243 auto end = std::chrono::high_resolution_clock::now();
244
245 auto elapsed_seconds = std::chrono::duration_cast<std::chrono::duration<double>>(end - start);
246 state.SetIterationTime(elapsed_seconds.count());
247 }
248 delete merged;
249}
250
251BENCHMARK(BM_MergingTH1I)->Arg(DIFF_OBJECTS)->UseManualTime();
252BENCHMARK(BM_MergingTH1I)->Arg(FULL_OBJECTS)->UseManualTime();
253BENCHMARK(BM_MergingTH2I)->Arg(DIFF_OBJECTS)->UseManualTime();
254BENCHMARK(BM_MergingTH2I)->Arg(FULL_OBJECTS)->UseManualTime();
255BENCHMARK(BM_MergingTH3I)->Arg(DIFF_OBJECTS)->UseManualTime();
256BENCHMARK(BM_MergingTH3I)->Arg(FULL_OBJECTS)->UseManualTime();
257BENCHMARK(BM_MergingTHnSparse)->Arg(DIFF_OBJECTS)->UseManualTime();
258BENCHMARK(BM_MergingTHnSparse)->Arg(FULL_OBJECTS)->UseManualTime();
259BENCHMARK(BM_MergingTTree)->Arg(DIFF_OBJECTS)->UseManualTime();
260BENCHMARK(BM_MergingTTree)->Arg(FULL_OBJECTS)->UseManualTime();
261
benchmark::State & state
default_random_engine gen(dev())
const auto bins
Definition PID.cxx:49
int32_t i
uint32_t c
Definition RawData.h:2
BENCHMARK(BM_MergingTH1I) -> Arg(DIFF_OBJECTS) ->UseManualTime()
const size_t entriesInDiff
BENCHMARK_MAIN()
const size_t entriesInFull
#define FULL_OBJECTS
#define DIFF_OBJECTS
const size_t collectionSize
Class for time synchronization of RawReader instances.
const GLfloat * m
Definition glcorearb.h:4066
GLuint entry
Definition glcorearb.h:5735
GLuint GLuint end
Definition glcorearb.h:469
GLuint const GLchar * name
Definition glcorearb.h:781
GLboolean GLboolean GLboolean b
Definition glcorearb.h:1233
GLboolean r
Definition glcorearb.h:1233
GLuint start
Definition glcorearb.h:469
GLboolean GLboolean GLboolean GLboolean a
Definition glcorearb.h:1233
std::string to_string(gsl::span< T, Size > span)
Definition common.h:52
constexpr size_t min
constexpr size_t max
std::unique_ptr< TTree > tree((TTree *) flIn.Get(std::string(o2::base::NameConf::CTFTREENAME).c_str()))