Last active
January 16, 2018 03:00
-
-
Save luked99/7c67d94da5c33cac5a1b41a500013355 to your computer and use it in GitHub Desktop.
libunwind performance test
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Compile with: | |
// arm-linux-gnueabihf-g++ bt_perf.cpp -o bt_perf -std=c++14 -lunwind -lunwind-arm | |
// | |
// Configure libunwind with: | |
// CC=arm-linux-gnueabihf-gcc CFLAGS="-g" configure --disable-debug --host=arm-linux \ | |
// --enable-shared --disable-static --with-sysroot=/home/lgd/arm --enable-maintainer-mode \ | |
// --disable-debug-frame --disable-block-signals | |
#include <stdlib.h> | |
#include <stdio.h> | |
#include <cinttypes> | |
#include <chrono> | |
#include <err.h> | |
#include <stdio.h> | |
#define UNW_LOCAL_ONLY | |
#include <libunwind.h> | |
using namespace std::chrono_literals; | |
std::chrono::steady_clock::duration total_time; | |
unsigned total_backtraces; | |
void init_unwind() | |
{ | |
} | |
void print_stats() | |
{ | |
printf("total time spent: %" PRId64 " ms on %d allocation\n", | |
total_time/1ms, total_backtraces); | |
printf("mean time per backtrace: %" PRId64 " us\n", | |
total_time/1us/total_backtraces); | |
} | |
void do_backtrace() | |
{ | |
void * bt[32]; | |
auto start = std::chrono::steady_clock::now(); | |
unw_backtrace(bt, 32); | |
auto finish = std::chrono::steady_clock::now(); | |
total_time += (finish - start); | |
total_backtraces++; | |
if ((total_backtraces % 100) == 0) | |
print_stats(); | |
} | |
#define CALLERS 32 | |
unsigned max_depth = 16; | |
void doit(int order) | |
{ | |
do_backtrace(); | |
} | |
void toplevel(); | |
int main(int argc, const char **argv) | |
{ | |
if (argc == 2) | |
max_depth = atoi(argv[1]); | |
init_unwind(); | |
srand(0); | |
int i; | |
for (i = 0; i < 128; i++) | |
toplevel(); | |
print_stats(); | |
return 0; | |
} | |
void caller0(unsigned depth); | |
void caller1(unsigned depth); | |
void caller2(unsigned depth); | |
void caller3(unsigned depth); | |
void caller4(unsigned depth); | |
void caller5(unsigned depth); | |
void caller6(unsigned depth); | |
void caller7(unsigned depth); | |
void caller8(unsigned depth); | |
void caller9(unsigned depth); | |
void caller10(unsigned depth); | |
void caller11(unsigned depth); | |
void caller12(unsigned depth); | |
void caller13(unsigned depth); | |
void caller14(unsigned depth); | |
void caller15(unsigned depth); | |
void caller16(unsigned depth); | |
void caller17(unsigned depth); | |
void caller18(unsigned depth); | |
void caller19(unsigned depth); | |
void caller20(unsigned depth); | |
void caller21(unsigned depth); | |
void caller22(unsigned depth); | |
void caller23(unsigned depth); | |
void caller24(unsigned depth); | |
void caller25(unsigned depth); | |
void caller26(unsigned depth); | |
void caller27(unsigned depth); | |
void caller28(unsigned depth); | |
void caller29(unsigned depth); | |
void caller30(unsigned depth); | |
void caller31(unsigned depth); | |
#define MAKE_CALLER(N) \ | |
void caller##N(unsigned depth) { \ | |
doit(0); \ | |
depth++; \ | |
if (depth < max_depth) { \ | |
int next = rand() % 32; \ | |
switch (next) { \ | |
case 0: caller0(depth); break; \ | |
case 1: caller1(depth); break; \ | |
case 2: caller2(depth); break; \ | |
case 3: caller3(depth); break; \ | |
case 4: caller4(depth); break; \ | |
case 5: caller5(depth); break; \ | |
case 6: caller6(depth); break; \ | |
case 7: caller7(depth); break; \ | |
case 8: caller8(depth); break; \ | |
case 9: caller9(depth); break; \ | |
case 10: caller10(depth); break; \ | |
case 11: caller11(depth); break; \ | |
case 12: caller12(depth); break; \ | |
case 13: caller13(depth); break; \ | |
case 14: caller14(depth); break; \ | |
case 15: caller15(depth); break; \ | |
case 16: caller16(depth); break; \ | |
case 17: caller17(depth); break; \ | |
case 18: caller18(depth); break; \ | |
case 19: caller19(depth); break; \ | |
case 20: caller20(depth); break; \ | |
case 21: caller21(depth); break; \ | |
case 22: caller22(depth); break; \ | |
case 23: caller23(depth); break; \ | |
case 24: caller24(depth); break; \ | |
case 25: caller25(depth); break; \ | |
case 26: caller26(depth); break; \ | |
case 27: caller27(depth); break; \ | |
case 28: caller28(depth); break; \ | |
case 29: caller29(depth); break; \ | |
case 30: caller30(depth); break; \ | |
case 31: caller31(depth); break; \ | |
} \ | |
} \ | |
} | |
MAKE_CALLER(0); | |
MAKE_CALLER(1); | |
MAKE_CALLER(2); | |
MAKE_CALLER(3); | |
MAKE_CALLER(4); | |
MAKE_CALLER(5); | |
MAKE_CALLER(6); | |
MAKE_CALLER(7); | |
MAKE_CALLER(8); | |
MAKE_CALLER(9); | |
MAKE_CALLER(10); | |
MAKE_CALLER(11); | |
MAKE_CALLER(12); | |
MAKE_CALLER(13); | |
MAKE_CALLER(14); | |
MAKE_CALLER(15); | |
MAKE_CALLER(16); | |
MAKE_CALLER(17); | |
MAKE_CALLER(18); | |
MAKE_CALLER(19); | |
MAKE_CALLER(20); | |
MAKE_CALLER(21); | |
MAKE_CALLER(22); | |
MAKE_CALLER(23); | |
MAKE_CALLER(24); | |
MAKE_CALLER(25); | |
MAKE_CALLER(26); | |
MAKE_CALLER(27); | |
MAKE_CALLER(28); | |
MAKE_CALLER(29); | |
MAKE_CALLER(30); | |
MAKE_CALLER(31); | |
void toplevel() | |
{ | |
caller0(32); | |
caller1(32); | |
caller2(32); | |
caller3(32); | |
caller4(32); | |
caller5(32); | |
caller6(32); | |
caller7(32); | |
caller8(32); | |
caller9(32); | |
caller10(32); | |
caller11(32); | |
caller12(32); | |
caller13(32); | |
caller14(32); | |
caller15(32); | |
caller16(32); | |
caller17(32); | |
caller18(32); | |
caller19(32); | |
caller20(32); | |
caller21(32); | |
caller22(32); | |
caller23(32); | |
caller24(32); | |
caller25(32); | |
caller26(32); | |
caller27(32); | |
caller28(32); | |
caller29(32); | |
caller30(32); | |
caller31(32); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment