MCPcopy Create free account
hub / github.com/apache/impala / Measure

Method Measure

be/src/util/benchmark.cc:42–115  ·  view source on GitHub ↗

Private measurement function. This function is a bit unusual in that it throws exceptions; the intention is to abort the measurement when an unreliable result is detected, but to also provide some useful context as to which benchmark was being run. The method used to determine whether the measurement is unreliable is detecting context switches using getrusage(). Pass micro_heuristics=false to t

Source from the content-addressed store, hash-verified

40// is detecting context switches using getrusage(). Pass micro_heuristics=false to
41// the class constructor if you do not want this behavior.
42double Benchmark::Measure(BenchmarkFunction function, void* args,
43 int max_time, int batch_size, bool micro_heuristics) {
44 int64_t target_cycles = CpuInfo::cycles_per_ms() * max_time;
45 int64_t iters = 0;
46 struct rusage ru_start;
47 struct rusage ru_stop;
48 StopWatch sw;
49 int64_t lost_time = 0;
50
51 // Run it with the default batch size to roughly estimate how many iterations
52 // it will take.
53 for (;;) {
54 int64 begin_time = sw.ElapsedTime();
55 if (micro_heuristics) getrusage(RUSAGE_THREAD, &ru_start);
56 sw.Start();
57 function(batch_size, args);
58 sw.Stop();
59 if (micro_heuristics) getrusage(RUSAGE_THREAD, &ru_stop);
60 if (!micro_heuristics || ru_stop.ru_nivcsw == ru_start.ru_nivcsw) {
61 iters = batch_size;
62 break;
63 }
64
65 // Taking too long and we keep getting switched out; either the machine is busy,
66 // or the benchmark takes too long to run and should not be used with this
67 // microbenchmark suite. Bail.
68 if (sw.ElapsedTime() > target_cycles) {
69 throw std::runtime_error("Benchmark failed to complete due to context switching.");
70 }
71
72 // Divide the batch size by the number of context switches until we find a size
73 // small enough that we don't switch
74 batch_size = max<int>(1, batch_size / (1+(ru_stop.ru_nivcsw - ru_start.ru_nivcsw)));
75 lost_time += sw.ElapsedTime() - begin_time;
76 }
77
78 double iters_guess = (target_cycles / (sw.ElapsedTime() - lost_time)) * batch_size;
79 // Shoot for 110% of the guess. Going a little over is not a big deal.
80 iters_guess *= 1.1;
81 // Modify the batch size based on the guess. We ran the function a small number
82 // of times to estimate how fast the function is. Run the remaining iterations at
83 // in 20% increments.
84 batch_size = max<int>(1, (iters_guess - iters) / 5);
85
86 while (sw.ElapsedTime() < target_cycles) {
87 int64 begin_time = sw.ElapsedTime();
88 if (micro_heuristics) getrusage(RUSAGE_THREAD, &ru_start);
89 sw.Start();
90 function(batch_size, args);
91 sw.Stop();
92 if (micro_heuristics) getrusage(RUSAGE_THREAD, &ru_stop);
93 if (!micro_heuristics || ru_stop.ru_nivcsw == ru_start.ru_nivcsw) {
94 iters += batch_size;
95 } else {
96 // We could have a vastly different estimate for batch size now and might have
97 // started context switching again. Divide down by 1 + the number of context
98 // switches as a guess of the number of iterations to perform with each batch.
99 lost_time += sw.ElapsedTime() - begin_time;

Callers 15

RunBenchmarksFunction · 0.45
mainFunction · 0.45
mainFunction · 0.45
mainFunction · 0.45
mainFunction · 0.45
RunMethod · 0.45
RunClusterSizeBenchmarkFunction · 0.45
RunNumBlocksBenchmarkFunction · 0.45
mainFunction · 0.45
mainFunction · 0.45
CompileVSRuntimeFunction · 0.45
TypeComparisonFunction · 0.45

Calls 11

sortFunction · 0.85
push_backMethod · 0.80
fnFunction · 0.50
ElapsedTimeMethod · 0.45
StartMethod · 0.45
StopMethod · 0.45
emptyMethod · 0.45
sizeMethod · 0.45
beginMethod · 0.45
endMethod · 0.45
strMethod · 0.45

Tested by

no test coverage detected