binary_trees.cc 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109
  1. // -*- 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. /* The Computer Language Benchmarks Game
  13. * http://benchmarksgame.alioth.debian.org/
  14. *
  15. * Contributed by Jon Harrop
  16. * Modified by Alex Mizrahi
  17. * Adapted for gperftools and added threads by Aliaksei Kandratsenka
  18. */
  19. #include <algorithm>
  20. #include <errno.h>
  21. #include <iostream>
  22. #include <pthread.h>
  23. #include <stdint.h>
  24. #include <stdio.h>
  25. #include <stdlib.h>
  26. #include <vector>
  27. struct Node {
  28. Node *l, *r;
  29. int i;
  30. Node(int i2) : l(0), r(0), i(i2) {}
  31. Node(Node *l2, int i2, Node *r2) : l(l2), r(r2), i(i2) {}
  32. ~Node() { delete l; delete r; }
  33. int check() const {
  34. if (l) {
  35. return l->check() + i - r->check();
  36. } else {
  37. return i;
  38. }
  39. }
  40. };
  41. Node *make(int i, int d) {
  42. if (d == 0) return new Node(i);
  43. return new Node(make(2*i-1, d-1), i, make(2*i, d-1));
  44. }
  45. void run(int given_depth) {
  46. int min_depth = 4,
  47. max_depth = std::max(min_depth+2,
  48. given_depth),
  49. stretch_depth = max_depth+1;
  50. {
  51. Node *c = make(0, stretch_depth);
  52. std::cout << "stretch tree of depth " << stretch_depth << "\t "
  53. << "check: " << c->check() << std::endl;
  54. delete c;
  55. }
  56. Node *long_lived_tree=make(0, max_depth);
  57. for (int d=min_depth; d<=max_depth; d+=2) {
  58. int iterations = 1 << (max_depth - d + min_depth), c=0;
  59. for (int i=1; i<=iterations; ++i) {
  60. Node *a = make(i, d), *b = make(-i, d);
  61. c += a->check() + b->check();
  62. delete a;
  63. delete b;
  64. }
  65. std::cout << (2*iterations) << "\t trees of depth " << d << "\t "
  66. << "check: " << c << std::endl;
  67. }
  68. std::cout << "long lived tree of depth " << max_depth << "\t "
  69. << "check: " << (long_lived_tree->check()) << "\n";
  70. delete long_lived_tree;
  71. }
  72. static void *run_tramp(void *_a) {
  73. intptr_t a = reinterpret_cast<intptr_t>(_a);
  74. run(a);
  75. return 0;
  76. }
  77. int main(int argc, char *argv[]) {
  78. int given_depth = argc >= 2 ? atoi(argv[1]) : 20;
  79. int thread_count = std::max(1, argc >= 3 ? atoi(argv[2]) : 1) - 1;
  80. std::vector<pthread_t> threads(thread_count);
  81. for (int i = 0; i < thread_count; i++) {
  82. int rv = pthread_create(&threads[i], NULL,
  83. run_tramp,
  84. reinterpret_cast<void *>(given_depth));
  85. if (rv) {
  86. errno = rv;
  87. perror("pthread_create");
  88. }
  89. }
  90. run_tramp(reinterpret_cast<void *>(given_depth));
  91. for (int i = 0; i < thread_count; i++) {
  92. pthread_join(threads[i], NULL);
  93. }
  94. return 0;
  95. }