blob: 4c895b2e961b91f3a3221d09afbea28ed3039981 [file] [log] [blame]
Brian Silverman20350ac2021-11-17 18:19:55 -08001// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
2//
3// Copied from
4// http://benchmarksgame.alioth.debian.org/u64q/program.php?test=binarytrees&lang=gpp&id=2
5// and slightly modified (particularly by adding multi-threaded
6// operation to hit malloc harder).
7//
8// This version of binary trees is mostly new/delete benchmark
9//
10// NOTE: copyright of this code is unclear, but we only distribute
11// source.
12
13/* The Computer Language Benchmarks Game
14 * http://benchmarksgame.alioth.debian.org/
15 *
16 * Contributed by Jon Harrop
17 * Modified by Alex Mizrahi
18 * Adapted for gperftools and added threads by Aliaksei Kandratsenka
19 */
20
21#include <algorithm>
22#include <errno.h>
23#include <iostream>
24#include <pthread.h>
25#include <stdint.h>
26#include <stdio.h>
27#include <stdlib.h>
28#include <vector>
29
30struct Node {
31 Node *l, *r;
32 int i;
33 Node(int i2) : l(0), r(0), i(i2) {}
34 Node(Node *l2, int i2, Node *r2) : l(l2), r(r2), i(i2) {}
35 ~Node() { delete l; delete r; }
36 int check() const {
37 if (l) {
38 return l->check() + i - r->check();
39 } else {
40 return i;
41 }
42 }
43};
44
45Node *make(int i, int d) {
46 if (d == 0) return new Node(i);
47 return new Node(make(2*i-1, d-1), i, make(2*i, d-1));
48}
49
50void run(int given_depth) {
51 int min_depth = 4,
52 max_depth = std::max(min_depth+2,
53 given_depth),
54 stretch_depth = max_depth+1;
55
56 {
57 Node *c = make(0, stretch_depth);
58 std::cout << "stretch tree of depth " << stretch_depth << "\t "
59 << "check: " << c->check() << std::endl;
60 delete c;
61 }
62
63 Node *long_lived_tree=make(0, max_depth);
64
65 for (int d=min_depth; d<=max_depth; d+=2) {
66 int iterations = 1 << (max_depth - d + min_depth), c=0;
67 for (int i=1; i<=iterations; ++i) {
68 Node *a = make(i, d), *b = make(-i, d);
69 c += a->check() + b->check();
70 delete a;
71 delete b;
72 }
73 std::cout << (2*iterations) << "\t trees of depth " << d << "\t "
74 << "check: " << c << std::endl;
75 }
76
77 std::cout << "long lived tree of depth " << max_depth << "\t "
78 << "check: " << (long_lived_tree->check()) << "\n";
79
80 delete long_lived_tree;
81}
82
83static void *run_tramp(void *_a) {
84 intptr_t a = reinterpret_cast<intptr_t>(_a);
85 run(a);
86 return 0;
87}
88
89int main(int argc, char *argv[]) {
90 int given_depth = argc >= 2 ? atoi(argv[1]) : 20;
91 int thread_count = std::max(1, argc >= 3 ? atoi(argv[2]) : 1) - 1;
92 std::vector<pthread_t> threads(thread_count);
93
94 for (int i = 0; i < thread_count; i++) {
95 int rv = pthread_create(&threads[i], NULL,
96 run_tramp,
97 reinterpret_cast<void *>(given_depth));
98 if (rv) {
99 errno = rv;
100 perror("pthread_create");
101 }
102 }
103 run_tramp(reinterpret_cast<void *>(given_depth));
104 for (int i = 0; i < thread_count; i++) {
105 pthread_join(threads[i], NULL);
106 }
107 return 0;
108}