1 /*
2  * Copyright (c) Facebook, Inc. and its affiliates.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #include <folly/Benchmark.h>
18 #include <folly/experimental/symbolizer/StackTrace.h>
19 #include <folly/init/Init.h>
20 
21 using namespace folly;
22 using namespace folly::symbolizer;
23 
basic(size_t nFrames)24 unsigned int basic(size_t nFrames) {
25   unsigned int iters = 1000000;
26   constexpr size_t kMaxAddresses = 100;
27   uintptr_t addresses[kMaxAddresses];
28 
29   CHECK_LE(nFrames, kMaxAddresses);
30 
31   for (unsigned int i = 0; i < iters; ++i) {
32     ssize_t n = getStackTrace(addresses, nFrames);
33     CHECK_NE(n, -1);
34   }
35   // Reduce iters by nFrames as the recursive call will add it up.
36   return iters - nFrames;
37 }
38 
Recurse(size_t nFrames,size_t remaining)39 unsigned int Recurse(size_t nFrames, size_t remaining) {
40   if (remaining == 0) {
41     return basic(nFrames);
42   } else {
43     // +1 to prevent tail recursion optimization from kicking in.
44     return Recurse(nFrames, remaining - 1) + 1;
45   }
46 }
47 
SetupStackAndTest(int,size_t nFrames)48 unsigned int SetupStackAndTest(int /* iters */, size_t nFrames) {
49   return Recurse(nFrames, nFrames);
50 }
51 
52 BENCHMARK_NAMED_PARAM_MULTI(SetupStackAndTest, 2_frames, 2)
53 BENCHMARK_NAMED_PARAM_MULTI(SetupStackAndTest, 4_frames, 4)
54 BENCHMARK_NAMED_PARAM_MULTI(SetupStackAndTest, 8_frames, 8)
55 BENCHMARK_NAMED_PARAM_MULTI(SetupStackAndTest, 16_frames, 16)
56 BENCHMARK_NAMED_PARAM_MULTI(SetupStackAndTest, 32_frames, 32)
57 BENCHMARK_NAMED_PARAM_MULTI(SetupStackAndTest, 64_frames, 64)
58 
59 /**
60 ============================================================================
61                                                           time/iter  iters/s
62 ============================================================================
63 SetupStackAndTest(2_frames)                                 51.68ns   19.35M
64 SetupStackAndTest(4_frames)                                 72.59ns   13.78M
65 SetupStackAndTest(8_frames)                                117.03ns    8.54M
66 SetupStackAndTest(16_frames)                               195.54ns    5.11M
67 SetupStackAndTest(32_frames)                               384.70ns    2.60M
68 SetupStackAndTest(64_frames)                               728.65ns    1.37M
69 ============================================================================
70 */
71 
main(int argc,char * argv[])72 int main(int argc, char* argv[]) {
73   folly::init(&argc, &argv, true);
74   folly::runBenchmarks();
75   return 0;
76 }
77