From b25a886891f7172c0abb189ac71bf2bf9b40ec76 Mon Sep 17 00:00:00 2001 From: David Goulet Date: Mon, 22 Aug 2011 14:51:58 -0400 Subject: [PATCH] Initial import of the benchmark branch This branch should be used to benchmark/measure components of lttng-tools. Benchmark can be started with "make bench" and results will be written to /tmp/lttng-bench-results.txt and stdout. Boot time of ltt-sessiond is added with this commit. Signed-off-by: David Goulet --- Makefile.am | 6 ++- benchmark/Makefile.am | 8 ++++ benchmark/benchmark.c | 86 ++++++++++++++++++++++++++++++++++++++++ benchmark/benchmark.h | 40 +++++++++++++++++++ benchmark/cpu.c | 54 +++++++++++++++++++++++++ benchmark/cpu.h | 28 +++++++++++++ benchmark/main.c | 28 +++++++++++++ benchmark/measures.h | 42 ++++++++++++++++++++ benchmark/runall.sh | 54 +++++++++++++++++++++++++ configure.ac | 1 + ltt-sessiond/Makefile.am | 5 ++- ltt-sessiond/main.c | 24 +++++++++++ 12 files changed, 373 insertions(+), 3 deletions(-) create mode 100644 benchmark/Makefile.am create mode 100644 benchmark/benchmark.c create mode 100644 benchmark/benchmark.h create mode 100644 benchmark/cpu.c create mode 100644 benchmark/cpu.h create mode 100644 benchmark/main.c create mode 100644 benchmark/measures.h create mode 100755 benchmark/runall.sh diff --git a/Makefile.am b/Makefile.am index ec8b7fe95..8815acebe 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1,6 +1,7 @@ ACLOCAL_AMFLAGS = -I config -SUBDIRS = liblttng-sessiond-comm \ +SUBDIRS = benchmark \ + liblttng-sessiond-comm \ libkernelctl \ liblttngkconsumerd \ liblttngctl \ @@ -12,3 +13,6 @@ SUBDIRS = liblttng-sessiond-comm \ tests \ include \ doc + +bench: + ./benchmark/runall.sh diff --git a/benchmark/Makefile.am b/benchmark/Makefile.am new file mode 100644 index 000000000..d1a353df0 --- /dev/null +++ b/benchmark/Makefile.am @@ -0,0 +1,8 @@ +AM_CPPFLAGS = -I$(top_srcdir)/include + +noinst_LTLIBRARIES = liblttng-benchmark.la + +liblttng_benchmark_la_SOURCES = benchmark.c benchmark.h cpu.c cpu.h + +bench: + ./runall.sh diff --git a/benchmark/benchmark.c b/benchmark/benchmark.c new file mode 100644 index 000000000..72a75c619 --- /dev/null +++ b/benchmark/benchmark.c @@ -0,0 +1,86 @@ +/* + * Copyright (C) 2011 - David Goulet + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; only version 2 + * of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#include +#include +#include +#include + +#include "benchmark.h" + +static FILE *fp; + +void benchmark_print_boot_results(void) +{ + uint64_t freq = 0; + double res; + int i, nb_calib = 10; + double global_boot_time = 0.0; + + fp = fopen(RESULTS_FILE_NAME, "w"); + if (fp == NULL) { + perror("fopen benchmark"); + return; + } + + /* CPU Frequency calibration */ + for (i = 0; i < nb_calib; i++) { + freq += get_cpu_freq(); + } + freq = freq / nb_calib; + + fprintf(fp, "CPU frequency %lu Ghz\n\n", freq); + + fprintf(fp, "Results:\n----------\n"); + + res = (double) (((double)(time_sessiond_boot_end - time_sessiond_boot_start) + / (((double)freq) / 1000)) / 1000000000); + + fprintf(fp, "Boot time inside main() from start to first pthread_join (blocking state)\n"); + fprintf(fp, "Time: %.20f sec.\n", res); + + global_boot_time += res; + + res = (double) (((double)(time_sessiond_th_kern_poll - time_sessiond_th_kern_start) + / (((double)freq) / 1000)) / 1000000000); + + fprintf(fp, "Boot time of the kernel thread from start to poll() (ready state)\n"); + fprintf(fp, "Time: %.20f sec.\n", res); + + global_boot_time += res; + + res = (double) (((double)(time_sessiond_th_apps_poll - time_sessiond_th_apps_start) + / (((double)freq) / 1000)) / 1000000000); + + fprintf(fp, "Boot time of the application thread from start to poll() (ready state)\n"); + fprintf(fp, "Time: %.20f sec.\n", res); + + global_boot_time += res; + + res = (double) (((double)(time_sessiond_th_cli_poll - time_sessiond_th_cli_start) + / (((double)freq) / 1000)) / 1000000000); + + fprintf(fp, "Boot time of the client thread from start to poll() (ready state)\n"); + fprintf(fp, "Time: %.20f sec.\n", res); + + global_boot_time += res; + + fprintf(fp, "Global Boot Time of ltt-sessiond: %0.20f sec.\n", global_boot_time); + + fclose(fp); +} diff --git a/benchmark/benchmark.h b/benchmark/benchmark.h new file mode 100644 index 000000000..6232dee8c --- /dev/null +++ b/benchmark/benchmark.h @@ -0,0 +1,40 @@ +/* + * Copyright (C) 2011 - David Goulet + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; only version 2 + * of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#ifndef _BENCHMARK_H +#define _BENCHMARK_H + +#include +#include + +#include "cpu.h" +#include "measures.h" + +#define RESULTS_FILE_NAME "/tmp/lttng-bench-results.txt" + +void benchmark_print_boot_results(void); + +#define record_cycles(name) \ + time_##name = get_cycles(); + +#define tracepoint(name, args...) \ + do { \ + record_cycles(name); \ + } while (0) + +#endif /* _BENCHMARK_H */ diff --git a/benchmark/cpu.c b/benchmark/cpu.c new file mode 100644 index 000000000..efaea3878 --- /dev/null +++ b/benchmark/cpu.c @@ -0,0 +1,54 @@ +/* + * Copyright (C) 2011 - David Goulet + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; only version 2 + * of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#include +#include +#include +#include + +#include "cpu.h" + +cycles_t get_cycles(void) +{ + return caa_get_cycles(); +} + +uint64_t get_cpu_freq(void) +{ + struct timezone tz; + struct timeval tvstart, tvstop; + cycles_t c_before, c_after; + unsigned long microseconds; + + memset(&tz, 0, sizeof(tz)); + + gettimeofday(&tvstart, &tz); + c_before = get_cycles(); + gettimeofday(&tvstart, &tz); + + sleep(1); + + gettimeofday(&tvstop, &tz); + c_after = get_cycles(); + gettimeofday(&tvstop, &tz); + + microseconds = ((tvstop.tv_sec - tvstart.tv_sec) * 1000000) + + (tvstop.tv_usec - tvstart.tv_usec); + + return (uint64_t) ((c_after - c_before) / microseconds); +} diff --git a/benchmark/cpu.h b/benchmark/cpu.h new file mode 100644 index 000000000..799ccdf30 --- /dev/null +++ b/benchmark/cpu.h @@ -0,0 +1,28 @@ +/* + * Copyright (C) 2011 - David Goulet + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; only version 2 + * of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#ifndef _CPU_H +#define _CPU_H + +#include +#include + +uint64_t get_cpu_freq(void); +cycles_t get_cycles(void); + +#endif /* _CPU_H */ diff --git a/benchmark/main.c b/benchmark/main.c new file mode 100644 index 000000000..1c176f84c --- /dev/null +++ b/benchmark/main.c @@ -0,0 +1,28 @@ +/* + * Copyright (C) 2011 - David Goulet + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; only version 2 + * of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#include +#include +#include + +#include "benchmark.h" + +int main(int argc, char **argv) +{ + return 0; +} diff --git a/benchmark/measures.h b/benchmark/measures.h new file mode 100644 index 000000000..80cb16780 --- /dev/null +++ b/benchmark/measures.h @@ -0,0 +1,42 @@ +/* + * Copyright (C) 2011 - David Goulet + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; only version 2 + * of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#ifndef _MEASURES_H +#define _MEASURES_H + +/* Session daemon main() time */ +cycles_t time_sessiond_boot_start; +cycles_t time_sessiond_boot_end; + +/* Session daemon thread manage kconsumerd time */ +cycles_t time_sessiond_th_kcon_start; +cycles_t time_sessiond_th_kcon_poll; + +/* Session daemon thread manage kernel time */ +cycles_t time_sessiond_th_kern_start; +cycles_t time_sessiond_th_kern_poll; + +/* Session daemon thread manage apps time */ +cycles_t time_sessiond_th_apps_start; +cycles_t time_sessiond_th_apps_poll; + +/* Session daemon thread manage client time */ +cycles_t time_sessiond_th_cli_start; +cycles_t time_sessiond_th_cli_poll; + +#endif /* _MEASURES_H */ diff --git a/benchmark/runall.sh b/benchmark/runall.sh new file mode 100755 index 000000000..51e9f4d53 --- /dev/null +++ b/benchmark/runall.sh @@ -0,0 +1,54 @@ +#!/bin/bash +# +# Copyright (C) 2011 - David Goulet +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; only version 2 +# of the License. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +# + +SESSIOND_BIN="ltt-sessiond" +RESULTS_PATH="/tmp/lttng-bench-results.txt" +BASEDIR=`dirname $0` + +if [ -e $RESULTS_PATH ]; then + mv $RESULTS_PATH $RESULTS_PATH.`date +%s` +fi + +echo -n "Starting session daemon... " +$BASEDIR/../ltt-sessiond/$SESSIOND_BIN --daemonize --quiet +if [ $? -ne 0 ]; then + echo -e '\e[1;31mFAILED\e[0m' + exit 1 +else + echo -e "\e[1;32mOK\e[0m" +fi + +PID_SESSIOND=`pidof lt-$SESSIOND_BIN` + +# Wait for the benchmark to run +echo -n "Waiting." +sleep 1 +echo -n "." +sleep 1 +echo -n "." +sleep 1 + +kill $PID_SESSIOND + +echo -e "\nResults will be available shortly in $RESULTS_PATH" +echo "" + +tail -F $RESULTS_PATH --pid $PID_SESSIOND 2>/dev/null + +exit 0 diff --git a/configure.ac b/configure.ac index 066c4e20e..24c1b7cb1 100644 --- a/configure.ac +++ b/configure.ac @@ -42,6 +42,7 @@ AC_SUBST(DEFAULT_INCLUDES) AC_CONFIG_FILES([ Makefile include/Makefile + benchmark/Makefile libkernelctl/Makefile liblttngkconsumerd/Makefile liblttngctl/Makefile diff --git a/ltt-sessiond/Makefile.am b/ltt-sessiond/Makefile.am index daa4265c1..c9bdee434 100644 --- a/ltt-sessiond/Makefile.am +++ b/ltt-sessiond/Makefile.am @@ -1,4 +1,4 @@ -AM_CPPFLAGS = -I$(top_srcdir)/include \ +AM_CPPFLAGS = -I$(top_srcdir)/include -I$(top_srcdir)/benchmark \ -I$(top_srcdir)/libkernelctl -I$(top_srcdir)/libustctl \ -DINSTALL_BIN_PATH=\"$(bindir)\" @@ -16,4 +16,5 @@ ltt_sessiond_LDADD = \ $(top_builddir)/liblttng-sessiond-comm/liblttng-sessiond-comm.la \ $(top_builddir)/libkernelctl/libkernelctl.la \ $(top_builddir)/libustctl/libustctl.la \ - $(top_builddir)/liblttngctl/liblttngctl.la + $(top_builddir)/liblttngctl/liblttngctl.la \ + $(top_builddir)/benchmark/liblttng-benchmark.la diff --git a/ltt-sessiond/main.c b/ltt-sessiond/main.c index 70c194b22..ab6d315f3 100644 --- a/ltt-sessiond/main.c +++ b/ltt-sessiond/main.c @@ -54,6 +54,8 @@ #include "ltt-kconsumerd.h" #include "utils.h" +#include "benchmark.h" + /* Const values */ const char default_home_dir[] = DEFAULT_HOME_DIR; const char default_tracing_group[] = LTTNG_DEFAULT_TRACING_GROUP; @@ -231,6 +233,8 @@ static void cleanup(void) DBG("Unloading kernel modules"); modprobe_remove_kernel_modules(); + + benchmark_print_boot_results(); } /* @@ -616,6 +620,8 @@ static void *thread_manage_kernel(void *data) char tmp; int update_poll_flag = 1; + tracepoint(sessiond_th_kern_start); + DBG("Thread manage kernel started"); while (1) { @@ -629,6 +635,8 @@ static void *thread_manage_kernel(void *data) DBG("Polling on %d fds", nb_fd); + tracepoint(sessiond_th_kern_poll); + /* Poll infinite value of time */ ret = poll(kernel_pollfd, nb_fd, -1); if (ret < 0) { @@ -697,6 +705,8 @@ static void *thread_manage_kconsumerd(void *data) enum lttcomm_return_code code; struct pollfd pollfd[2]; + tracepoint(sessiond_th_kcon_start); + DBG("[thread] Manage kconsumerd started"); ret = lttcomm_listen_unix_sock(kconsumerd_err_sock); @@ -711,6 +721,8 @@ static void *thread_manage_kconsumerd(void *data) pollfd[1].fd = kconsumerd_err_sock; pollfd[1].events = POLLIN; + tracepoint(sessiond_th_kcon_poll); + /* Inifinite blocking call, waiting for transmission */ ret = poll(pollfd, 2, -1); if (ret < 0) { @@ -808,6 +820,8 @@ static void *thread_manage_apps(void *data) int sock = 0, ret; struct pollfd pollfd[2]; + tracepoint(sessiond_th_apps_start); + /* TODO: Something more elegant is needed but fine for now */ /* FIXME: change all types to either uint8_t, uint32_t, uint64_t * for 32-bit vs 64-bit compat processes. */ @@ -838,6 +852,8 @@ static void *thread_manage_apps(void *data) while (1) { DBG("Accepting application registration"); + tracepoint(sessiond_th_apps_poll); + /* Inifinite blocking call, waiting for transmission */ ret = poll(pollfd, 2, -1); if (ret < 0) { @@ -2317,6 +2333,8 @@ static void *thread_manage_clients(void *data) struct command_ctx *cmd_ctx = NULL; struct pollfd pollfd[2]; + tracepoint(sessiond_th_cli_start); + DBG("[thread] Manage client started"); ret = lttcomm_listen_unix_sock(client_sock); @@ -2341,6 +2359,8 @@ static void *thread_manage_clients(void *data) while (1) { DBG("Accepting client command ..."); + tracepoint(sessiond_th_cli_poll); + /* Inifinite blocking call, waiting for transmission */ ret = poll(pollfd, 2, -1); if (ret < 0) { @@ -2810,6 +2830,8 @@ int main(int argc, char **argv) void *status; const char *home_path; + tracepoint(sessiond_boot_start); + /* Create thread quit pipe */ if ((ret = init_thread_quit_pipe()) < 0) { goto error; @@ -2956,6 +2978,8 @@ int main(int argc, char **argv) goto exit_kernel; } + tracepoint(sessiond_boot_end); + ret = pthread_join(kernel_thread, &status); if (ret != 0) { perror("pthread_join"); -- 2.34.1