From 85712e6776223ab654bfe9633fcb6f592af442ab Mon Sep 17 00:00:00 2001 From: Bogdan Pricope Date: Fri, 5 Jan 2018 10:57:48 +0200 Subject: [PATCH 1/5] example: add papi path configuration option Signed-off-by: Bogdan Pricope --- example/m4/configure.m4 | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/example/m4/configure.m4 b/example/m4/configure.m4 index 208c5d6d74..0344159038 100644 --- a/example/m4/configure.m4 +++ b/example/m4/configure.m4 @@ -7,6 +7,16 @@ AC_ARG_ENABLE([test-example], [test_example=yes]) AM_CONDITIONAL([test_example], [test x$test_example = xyes ]) +PAPI_PATH="" +code_instrumentation=no +AC_ARG_WITH([papi-path], +AS_HELP_STRING([--with-papi-path=DIR path to papi install directory]), + [PAPI_PATH="$withval" + code_instrumentation=yes],[]) + +AC_SUBST([PAPI_PATH]) +AM_CONDITIONAL([CODE_INSTRUM], [test x$code_instrumentation = xyes ]) + AC_CONFIG_FILES([example/classifier/Makefile example/generator/Makefile example/hello/Makefile From b94a316bc0407c67f480bf5a414d16a29cb51d54 Mon Sep 17 00:00:00 2001 From: Bogdan Pricope Date: Fri, 5 Jan 2018 13:40:24 +0200 Subject: [PATCH 2/5] example: instrum: add skeleton Signed-off-by: Bogdan Pricope --- example/Makefile.am | 4 ++++ example/Makefile.inc | 4 ++++ example/instrum/Makefile.am | 20 ++++++++++++++++++++ example/instrum/instrum.c | 18 ++++++++++++++++++ example/m4/configure.m4 | 1 + 5 files changed, 47 insertions(+) create mode 100644 example/instrum/Makefile.am create mode 100644 example/instrum/instrum.c diff --git a/example/Makefile.am b/example/Makefile.am index b6e8d81fea..99c5726f77 100644 --- a/example/Makefile.am +++ b/example/Makefile.am @@ -13,4 +13,8 @@ SUBDIRS = classifier \ ddf_ifs \ ddf_app +if CODE_INSTRUM +SUBDIRS += instrum +endif + noinst_HEADERS = example_debug.h diff --git a/example/Makefile.inc b/example/Makefile.inc index 31bf7c4356..78b750cda8 100644 --- a/example/Makefile.inc +++ b/example/Makefile.inc @@ -13,4 +13,8 @@ AM_CFLAGS = \ -I$(top_srcdir)/platform/@with_platform@/arch/@ARCH_DIR@ \ -I$(top_builddir)/include +if CODE_INSTRUM +AM_LDFLAGS = -L$(LIB) -lssl -lcrypto -latomic +else AM_LDFLAGS = -L$(LIB) -static +endif diff --git a/example/instrum/Makefile.am b/example/instrum/Makefile.am new file mode 100644 index 0000000000..bf2a19c0dd --- /dev/null +++ b/example/instrum/Makefile.am @@ -0,0 +1,20 @@ +LIB = $(top_builddir)/lib + +AM_CFLAGS = \ + -I$(srcdir) \ + -I$(top_srcdir)/example \ + -I$(top_srcdir)/platform/@with_platform@/include \ + -I$(top_srcdir)/include/ \ + -I$(top_srcdir)/include/odp/arch/@ARCH_ABI@ \ + -I$(top_srcdir)/helper/include \ + -I$(top_builddir)/platform/@with_platform@/include \ + -I$(top_srcdir)/platform/@with_platform@/arch/@ARCH_DIR@ \ + -I$(top_builddir)/include \ + -I$(PAPI_PATH)/include + +AM_LDFLAGS = -L$(PAPI_PATH)/lib -lpapi + +lib_LTLIBRARIES = $(LIB)/libinstrum.la + +__LIB__libinstrum_la_SOURCES = \ + instrum.c diff --git a/example/instrum/instrum.c b/example/instrum/instrum.c new file mode 100644 index 0000000000..88580c58fa --- /dev/null +++ b/example/instrum/instrum.c @@ -0,0 +1,18 @@ +/* Copyright (c) 2017, Linaro Limited + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include + +static __attribute__((constructor)) void setup_wrappers(void) +{ + printf("Setup Wrappers\n"); +} + +static __attribute__((destructor)) void teardown_wrappers(void) +{ + printf("Teardown Wrappers\n"); +} diff --git a/example/m4/configure.m4 b/example/m4/configure.m4 index 0344159038..d2258bf27a 100644 --- a/example/m4/configure.m4 +++ b/example/m4/configure.m4 @@ -31,4 +31,5 @@ AC_CONFIG_FILES([example/classifier/Makefile example/traffic_mgmt/Makefile example/ddf_ifs/Makefile example/ddf_app/Makefile + example/instrum/Makefile example/Makefile]) From 88ab11d0d48ecfe0e15c5fceb57956cffeed241e Mon Sep 17 00:00:00 2001 From: Bogdan Pricope Date: Fri, 5 Jan 2018 14:47:21 +0200 Subject: [PATCH 3/5] example: instrum: use low level API to retrieve performance counters Signed-off-by: Bogdan Pricope --- example/instrum/Makefile.am | 16 +++- example/instrum/drv.c | 39 +++++++++ example/instrum/drv.h | 19 ++++ example/instrum/init.c | 54 ++++++++++++ example/instrum/init.h | 19 ++++ example/instrum/instrum.c | 19 +++- example/instrum/instrum_common.h | 34 ++++++++ example/instrum/papi_cnt.c | 143 +++++++++++++++++++++++++++++++ example/instrum/papi_cnt.h | 28 ++++++ example/instrum/sample.h | 29 +++++++ example/instrum/sched.c | 43 ++++++++++ example/instrum/sched.h | 19 ++++ example/instrum/store.c | 126 +++++++++++++++++++++++++++ example/instrum/store.h | 36 ++++++++ 14 files changed, 622 insertions(+), 2 deletions(-) create mode 100644 example/instrum/drv.c create mode 100644 example/instrum/drv.h create mode 100644 example/instrum/init.c create mode 100644 example/instrum/init.h create mode 100644 example/instrum/instrum_common.h create mode 100644 example/instrum/papi_cnt.c create mode 100644 example/instrum/papi_cnt.h create mode 100644 example/instrum/sample.h create mode 100644 example/instrum/sched.c create mode 100644 example/instrum/sched.h create mode 100644 example/instrum/store.c create mode 100644 example/instrum/store.h diff --git a/example/instrum/Makefile.am b/example/instrum/Makefile.am index bf2a19c0dd..452b36c46b 100644 --- a/example/instrum/Makefile.am +++ b/example/instrum/Makefile.am @@ -16,5 +16,19 @@ AM_LDFLAGS = -L$(PAPI_PATH)/lib -lpapi lib_LTLIBRARIES = $(LIB)/libinstrum.la +noinst_HEADERS = \ + $(srcdir)/instrum_common.h \ + $(srcdir)/sample.h \ + $(srcdir)/store.h \ + $(srcdir)/papi_cnt.h \ + $(srcdir)/init.h \ + $(srcdir)/drv.h \ + $(srcdir)/sched.h + __LIB__libinstrum_la_SOURCES = \ - instrum.c + instrum.c \ + store.c \ + papi_cnt.c \ + init.c \ + drv.c \ + sched.c diff --git a/example/instrum/drv.c b/example/instrum/drv.c new file mode 100644 index 0000000000..d82018ecc1 --- /dev/null +++ b/example/instrum/drv.c @@ -0,0 +1,39 @@ +/* Copyright (c) 2018, Linaro Limited + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include +#include +#include +#include +#include + +static int (*instr_odpdrv_print_all)(void); + +int instr_odpdrv_init(void) +{ + INSTR_FUNCTION(odpdrv_print_all); + + if (!instr_odpdrv_print_all) { + printf("odpdrv_print_all: Not Found\n"); + return -1; + } + + return 0; +} + +int odpdrv_print_all(void) +{ + int ret; + + STORE_SAMPLE_INIT; + + STORE_SAMPLE_START; + ret = (*instr_odpdrv_print_all)(); + STORE_SAMPLE_END; + + return ret; +} diff --git a/example/instrum/drv.h b/example/instrum/drv.h new file mode 100644 index 0000000000..12441a7e4f --- /dev/null +++ b/example/instrum/drv.h @@ -0,0 +1,19 @@ +/* Copyright (c) 2018, Linaro Limited + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef __INSTRUM_DRV_H__ +#define __INSTRUM_DRV_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +int instr_odpdrv_init(void); + +#ifdef __cplusplus +} +#endif +#endif /* __INSTRUM_DRV_H__ */ diff --git a/example/instrum/init.c b/example/instrum/init.c new file mode 100644 index 0000000000..8691ff978a --- /dev/null +++ b/example/instrum/init.c @@ -0,0 +1,54 @@ +/* Copyright (c) 2018, Linaro Limited + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include +#include +#include +#include +#include + +static int (*instr_odp_init_local)(odp_instance_t instance, + odp_thread_type_t thr_type); + +static int (*instr_odp_term_local)(void); + +int instr_odpinit_init(void) +{ + INSTR_FUNCTION(odp_init_local); + + if (!instr_odp_init_local) { + printf("odp_init_local: Not Found\n"); + return -1; + } + + INSTR_FUNCTION(odp_term_local); + + if (!instr_odp_term_local) { + printf("odp_term_local: Not Found\n"); + return -1; + } + + return 0; +} + +int odp_init_local(odp_instance_t instance, odp_thread_type_t thr_type) +{ + int ret; + + ret = (*instr_odp_init_local)(instance, thr_type); + + instr_store_init_local(); + + return ret; +} + +int odp_term_local(void) +{ + instr_store_term_local(); + + return (*instr_odp_term_local)(); +} diff --git a/example/instrum/init.h b/example/instrum/init.h new file mode 100644 index 0000000000..b92e9d4a3b --- /dev/null +++ b/example/instrum/init.h @@ -0,0 +1,19 @@ +/* Copyright (c) 2018, Linaro Limited + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef __INSTRUM_INIT_H__ +#define __INSTRUM_INIT_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +int instr_odpinit_init(void); + +#ifdef __cplusplus +} +#endif +#endif /*__INSTRUM_INIT_H__*/ diff --git a/example/instrum/instrum.c b/example/instrum/instrum.c index 88580c58fa..05b38da680 100644 --- a/example/instrum/instrum.c +++ b/example/instrum/instrum.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2017, Linaro Limited +/* Copyright (c) 2018, Linaro Limited * All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause @@ -6,13 +6,30 @@ #include #include +#include +#include +#include +#include static __attribute__((constructor)) void setup_wrappers(void) { printf("Setup Wrappers\n"); + + if (instr_store_init()) + return; + + if (instr_odpinit_init()) + return; + + if (instr_odpdrv_init()) + return; + + if (instr_odpsched_init()) + return; } static __attribute__((destructor)) void teardown_wrappers(void) { printf("Teardown Wrappers\n"); + instr_store_term(); } diff --git a/example/instrum/instrum_common.h b/example/instrum/instrum_common.h new file mode 100644 index 0000000000..594423e1fb --- /dev/null +++ b/example/instrum/instrum_common.h @@ -0,0 +1,34 @@ +/* Copyright (c) 2018, Linaro Limited + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef __INSTRUM_COMMON_H__ +#define __INSTRUM_COMMON_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef RTLD_NEXT +/*#define __GNU_SOURCE*/ +#define __USE_GNU +#endif + +#include +#include + +#define INSTR_FUNCTION(func) do { \ + instr_##func = dlsym(RTLD_NEXT, #func); \ + if (dlerror()) { \ + errno = EACCES; \ + instr_##func = NULL; \ + } \ + } while (0) + +#ifdef __cplusplus +} +#endif + +#endif /* __INSTRUM_COMMON_H__ */ diff --git a/example/instrum/papi_cnt.c b/example/instrum/papi_cnt.c new file mode 100644 index 0000000000..c38c856a06 --- /dev/null +++ b/example/instrum/papi_cnt.c @@ -0,0 +1,143 @@ +/* Copyright (c) 2018, Linaro Limited + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include +#include +#include +#include + +static int papi_event_tab[SAMPLE_COUNTER_TAB_SIZE] = {PAPI_BR_CN, PAPI_L2_DCM}; + +static __thread int event_set = PAPI_NULL; + +int papi_init(void) +{ + int retval, i; + + retval = PAPI_library_init(PAPI_VER_CURRENT); + if (retval != PAPI_VER_CURRENT) { + printf("PAPI Library initialization error!\n"); + return -1; + } + + retval = PAPI_thread_init((unsigned long(*)(void))(pthread_self)); + if (retval != PAPI_OK) { + printf("PAPI_thread_init error!\n"); + goto err_shutdown; + } + + if (PAPI_set_granularity(PAPI_GRN_THR) != PAPI_OK) { + printf("PAPI_set_granularity error!\n"); + goto err_shutdown; + } + + for (i = 0; i < SAMPLE_COUNTER_TAB_SIZE; i++) { + retval = PAPI_query_event(papi_event_tab[i]); + if (retval != PAPI_OK) { + printf("PAPI_query_event %d - error\n", i); + goto err_shutdown; + } + } + + return 0; + +err_shutdown: + PAPI_shutdown(); + + return -1; +} + +void papi_term(void) +{ + PAPI_shutdown(); +} + +int papi_init_local(void) +{ + int retval; + + retval = PAPI_register_thread(); + if (retval != PAPI_OK) { + printf("PAPI_register_thread failed - %d\n", retval); + return -1; + } + + /* Create LL event set */ + event_set = PAPI_NULL; + retval = PAPI_create_eventset(&event_set); + if (retval != PAPI_OK) { + printf("PAPI_create_eventset error: %d\n", retval); + return -1; + } + + retval = PAPI_add_events(event_set, papi_event_tab, + SAMPLE_COUNTER_TAB_SIZE); + if (retval != PAPI_OK) { + printf("PAPI_add_events error: %d\n", retval); + goto err_clean_evset; + } + + retval = PAPI_start(event_set); + if (retval != PAPI_OK) { + printf("PAPI_start error: %d\n", retval); + goto err_clean_evset; + } + + return 0; + +err_clean_evset: + PAPI_cleanup_eventset(event_set); + PAPI_destroy_eventset(&event_set); + + return -1; +} + +int papi_term_local(void) +{ + long long last_counters[SAMPLE_COUNTER_TAB_SIZE]; + + if (PAPI_stop(event_set, last_counters) == PAPI_OK) { + int i; + + for (i = 0; i < SAMPLE_COUNTER_TAB_SIZE; i++) + printf("Counter[%d] = %lld\n", i, last_counters[i]); + } + + PAPI_cleanup_eventset(event_set); + PAPI_destroy_eventset(&event_set); + + return 0; +} + +int papi_sample_start(profiling_sample_t *spl) +{ + spl->timestamp_ns = PAPI_get_real_nsec(); + if (PAPI_read_ts(event_set, spl->counters, &spl->diff_cyc) != PAPI_OK) { + fprintf(stderr, "PAPI_read_counters - FAILED\n"); + return -1; + } + + return 0; +} + +int papi_sample_end(profiling_sample_t *spl) +{ + long long end_counters[SAMPLE_COUNTER_TAB_SIZE], end_cyc; + int i; + + if (PAPI_read_ts(event_set, end_counters, &end_cyc) != PAPI_OK) { + fprintf(stderr, "PAPI_read_counters - FAILED\n"); + return -1; + } + + for (i = 0; i < SAMPLE_COUNTER_TAB_SIZE; i++) + spl->counters[i] = end_counters[i] - spl->counters[i]; + + spl->diff_cyc = end_cyc - spl->diff_cyc; + + return 0; +} diff --git a/example/instrum/papi_cnt.h b/example/instrum/papi_cnt.h new file mode 100644 index 0000000000..72e49c72ca --- /dev/null +++ b/example/instrum/papi_cnt.h @@ -0,0 +1,28 @@ +/* Copyright (c) 2018, Linaro Limited + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef __INSTRUM_PAPI_COUNTERS_H__ +#define __INSTRUM_PAPI_COUNTERS_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +int papi_init(void); +void papi_term(void); +int papi_init_local(void); +int papi_term_local(void); + +int papi_sample_start(profiling_sample_t *spl); +int papi_sample_end(profiling_sample_t *spl); + +#ifdef __cplusplus +} +#endif +#endif /* __INSTRUM_PAPI_COUNTERS_H__ */ + diff --git a/example/instrum/sample.h b/example/instrum/sample.h new file mode 100644 index 0000000000..ca5f183a12 --- /dev/null +++ b/example/instrum/sample.h @@ -0,0 +1,29 @@ +/* Copyright (c) 2018, Linaro Limited + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef __INSTRUM_SAMPLE_H__ +#define __INSTRUM_SAMPLE_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#define SAMPLE_NAME_SIZE_MAX 20 +#define SAMPLE_COUNTER_TAB_SIZE 2 + +typedef struct { + char name[SAMPLE_NAME_SIZE_MAX]; + long long timestamp_ns; + long long diff_cyc; + + long long counters[SAMPLE_COUNTER_TAB_SIZE]; +} profiling_sample_t; + +#ifdef __cplusplus +} +#endif +#endif /* __INSTRUM_SAMPLE_H__ */ + diff --git a/example/instrum/sched.c b/example/instrum/sched.c new file mode 100644 index 0000000000..3e4a03bf1c --- /dev/null +++ b/example/instrum/sched.c @@ -0,0 +1,43 @@ +/* Copyright (c) 2018, Linaro Limited + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include +#include +#include +#include +#include + +static int (*instr_odp_schedule_multi)(odp_queue_t *from, + uint64_t wait, + odp_event_t events[], + int num); + +int instr_odpsched_init(void) +{ + INSTR_FUNCTION(odp_schedule_multi); + + if (!instr_odp_schedule_multi) { + printf("odp_schedule_multi: Not Found\n"); + return -1; + } + + return 0; +} + +int odp_schedule_multi(odp_queue_t *from, uint64_t wait, odp_event_t events[], + int num) +{ + int ret; + + STORE_SAMPLE_INIT; + + STORE_SAMPLE_START; + ret = (*instr_odp_schedule_multi)(from, wait, events, num); + STORE_SAMPLE_END; + + return ret; +} diff --git a/example/instrum/sched.h b/example/instrum/sched.h new file mode 100644 index 0000000000..2a092b0ed7 --- /dev/null +++ b/example/instrum/sched.h @@ -0,0 +1,19 @@ +/* Copyright (c) 2018, Linaro Limited + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef __INSTRUM_SCHED_H__ +#define __INSTRUM_SCHED_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +int instr_odpsched_init(void); + +#ifdef __cplusplus +} +#endif +#endif /* __INSTRUM_SCHED_H__ */ diff --git a/example/instrum/store.c b/example/instrum/store.c new file mode 100644 index 0000000000..aa338aa6c3 --- /dev/null +++ b/example/instrum/store.c @@ -0,0 +1,126 @@ +/* Copyright (c) 2018, Linaro Limited + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include +#include +#include +#include +#include + +#define SAMPLE_TAB_SIZE 50000 + +static __thread profiling_sample_t profile_sample_tab[SAMPLE_TAB_SIZE]; +static __thread uint64_t profile_sample_idx; +static __thread uint64_t profile_sample_ovf; + +#define STORE_DIR_ENV "ODP_INSTRUM_STORE_DIR" +#define STORE_DIR_NAME_DFLT "/tmp" +#define STORE_DIR_NAME_SIZE_MAX 250 +#define STORE_FILE_NAME_SIZE_MAX 250 + +static char store_dir[STORE_DIR_NAME_SIZE_MAX]; + +int instr_store_init(void) +{ + const char *store_dir_env = NULL; + + store_dir_env = getenv(STORE_DIR_ENV); + if (!store_dir_env) + store_dir_env = STORE_DIR_NAME_DFLT; + + strncpy(store_dir, store_dir_env, STORE_DIR_NAME_SIZE_MAX); + store_dir[STORE_DIR_NAME_SIZE_MAX - 1] = '\0'; + + if (papi_init()) + return -1; + + return 0; +} + +void instr_store_term(void) +{ + papi_term(); +} + +int instr_store_init_local(void) +{ + return papi_init_local(); +} + +int instr_store_term_local(void) +{ + return papi_term_local(); +} + +static void store_dump(void) +{ + FILE *f = NULL; + char file_name[STORE_DIR_NAME_SIZE_MAX + STORE_FILE_NAME_SIZE_MAX]; + char smpl[250], smpl_tmp[250]; + int i, j; + + sprintf(file_name, "%s/profile_%d_%ju.csv", + store_dir, odp_thread_id(), + profile_sample_ovf); + + f = fopen(file_name, "w"); + if (f == NULL) { + printf("Failed to create profiling file %s\n", file_name); + return; + } + + for (i = 0; i < SAMPLE_TAB_SIZE; i++) { + sprintf(smpl, "%lld,%lld,%s", + profile_sample_tab[i].timestamp_ns, + profile_sample_tab[i].diff_cyc, + profile_sample_tab[i].name); + for (j = 0; j < SAMPLE_COUNTER_TAB_SIZE; j++) { + sprintf(smpl_tmp, ",%lld", + profile_sample_tab[i].counters[j]); + strcat(smpl, smpl_tmp); + } + fprintf(f, "%s\n", smpl); + } + + fclose(f); +} + +instr_profiling_sample_t store_sample_start(const char *func) +{ + profiling_sample_t *spl = NULL; + + if (profile_sample_idx == SAMPLE_TAB_SIZE) + return NULL; + + spl = &profile_sample_tab[profile_sample_idx]; + + strncpy(spl->name, func, SAMPLE_NAME_SIZE_MAX); + spl->name[SAMPLE_NAME_SIZE_MAX - 1] = '\0'; + + if (papi_sample_start(spl)) + return NULL; + + profile_sample_idx++; + return spl; +} + +void store_sample_end(instr_profiling_sample_t _spl) +{ + profiling_sample_t *spl = _spl; + + if (!spl) /* failed sample - on start */ + return; + + if (papi_sample_end(spl)) + spl->name[0] = 0; /* failed sample - on end*/ + + if (profile_sample_idx == SAMPLE_TAB_SIZE) { + store_dump(); + profile_sample_idx = 0; + profile_sample_ovf++; + } +} diff --git a/example/instrum/store.h b/example/instrum/store.h new file mode 100644 index 0000000000..1d671fbfdf --- /dev/null +++ b/example/instrum/store.h @@ -0,0 +1,36 @@ +/* Copyright (c) 2018, Linaro Limited + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef __INSTRUM_STORE_H__ +#define __INSTRUM_STORE_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +typedef void *instr_profiling_sample_t; + +#define STORE_SAMPLE_INIT \ + instr_profiling_sample_t _spl + +#define STORE_SAMPLE_START \ + (_spl = store_sample_start(__func__)) + +#define STORE_SAMPLE_END \ + store_sample_end(_spl) + +int instr_store_init(void); +void instr_store_term(void); +int instr_store_init_local(void); +int instr_store_term_local(void); + +instr_profiling_sample_t store_sample_start(const char *); +void store_sample_end(instr_profiling_sample_t); + +#ifdef __cplusplus +} +#endif +#endif /* __INSTRUM_STORE_H__ */ From d714e01b64b10bb141e4b2595157d393c7a72ca3 Mon Sep 17 00:00:00 2001 From: Bogdan Pricope Date: Mon, 15 Jan 2018 09:55:51 +0200 Subject: [PATCH 4/5] example: instrum: configure papi event set Configure the set of papi counters to be acquired via an environment variable. Signed-off-by: Bogdan Pricope --- example/instrum/papi_cnt.c | 44 +++++++++++++++++++++++++++++++++----- example/instrum/papi_cnt.h | 2 ++ example/instrum/sample.h | 2 +- example/instrum/store.c | 4 +++- 4 files changed, 45 insertions(+), 7 deletions(-) diff --git a/example/instrum/papi_cnt.c b/example/instrum/papi_cnt.c index c38c856a06..da8267834f 100644 --- a/example/instrum/papi_cnt.c +++ b/example/instrum/papi_cnt.c @@ -6,17 +6,25 @@ #include #include +#include #include #include #include -static int papi_event_tab[SAMPLE_COUNTER_TAB_SIZE] = {PAPI_BR_CN, PAPI_L2_DCM}; +#define PAPI_EVENTS_ENV "ODP_INSTRUM_PAPI_EVENTS" + +#define PAPI_EVENT_TAB_SIZE_DFLT 2 +int papi_event_tab_dflt[PAPI_EVENT_TAB_SIZE_DFLT] = {PAPI_BR_CN, PAPI_L2_DCM}; + +static int papi_event_tab[SAMPLE_COUNTER_TAB_SIZE]; +static int papi_event_tab_size; static __thread int event_set = PAPI_NULL; int papi_init(void) { int retval, i; + char *papi_events_env = NULL; retval = PAPI_library_init(PAPI_VER_CURRENT); if (retval != PAPI_VER_CURRENT) { @@ -35,7 +43,28 @@ int papi_init(void) goto err_shutdown; } - for (i = 0; i < SAMPLE_COUNTER_TAB_SIZE; i++) { + papi_events_env = getenv(PAPI_EVENTS_ENV); + if (papi_events_env) { + char *tk = strtok(papi_events_env, ","); + int papi_event; + + while (tk != NULL && + papi_event_tab_size < SAMPLE_COUNTER_TAB_SIZE) { + if (PAPI_event_name_to_code(tk, &papi_event) == PAPI_OK) + papi_event_tab[papi_event_tab_size++] = + papi_event; + + tk = strtok(NULL, ","); + } + } + + if (!papi_event_tab_size) { + for (i = 0; i < PAPI_EVENT_TAB_SIZE_DFLT; i++) + papi_event_tab[i] = papi_event_tab_dflt[i]; + papi_event_tab_size = PAPI_EVENT_TAB_SIZE_DFLT; + } + + for (i = 0; i < papi_event_tab_size; i++) { retval = PAPI_query_event(papi_event_tab[i]); if (retval != PAPI_OK) { printf("PAPI_query_event %d - error\n", i); @@ -75,7 +104,7 @@ int papi_init_local(void) } retval = PAPI_add_events(event_set, papi_event_tab, - SAMPLE_COUNTER_TAB_SIZE); + papi_event_tab_size); if (retval != PAPI_OK) { printf("PAPI_add_events error: %d\n", retval); goto err_clean_evset; @@ -103,7 +132,7 @@ int papi_term_local(void) if (PAPI_stop(event_set, last_counters) == PAPI_OK) { int i; - for (i = 0; i < SAMPLE_COUNTER_TAB_SIZE; i++) + for (i = 0; i < papi_event_tab_size; i++) printf("Counter[%d] = %lld\n", i, last_counters[i]); } @@ -113,6 +142,11 @@ int papi_term_local(void) return 0; } +int papi_counters_cnt(void) +{ + return papi_event_tab_size; +} + int papi_sample_start(profiling_sample_t *spl) { spl->timestamp_ns = PAPI_get_real_nsec(); @@ -134,7 +168,7 @@ int papi_sample_end(profiling_sample_t *spl) return -1; } - for (i = 0; i < SAMPLE_COUNTER_TAB_SIZE; i++) + for (i = 0; i < papi_event_tab_size; i++) spl->counters[i] = end_counters[i] - spl->counters[i]; spl->diff_cyc = end_cyc - spl->diff_cyc; diff --git a/example/instrum/papi_cnt.h b/example/instrum/papi_cnt.h index 72e49c72ca..db55e75e0b 100644 --- a/example/instrum/papi_cnt.h +++ b/example/instrum/papi_cnt.h @@ -18,6 +18,8 @@ void papi_term(void); int papi_init_local(void); int papi_term_local(void); +int papi_counters_cnt(void); + int papi_sample_start(profiling_sample_t *spl); int papi_sample_end(profiling_sample_t *spl); diff --git a/example/instrum/sample.h b/example/instrum/sample.h index ca5f183a12..e88ef4f966 100644 --- a/example/instrum/sample.h +++ b/example/instrum/sample.h @@ -12,7 +12,7 @@ extern "C" { #endif #define SAMPLE_NAME_SIZE_MAX 20 -#define SAMPLE_COUNTER_TAB_SIZE 2 +#define SAMPLE_COUNTER_TAB_SIZE 10 typedef struct { char name[SAMPLE_NAME_SIZE_MAX]; diff --git a/example/instrum/store.c b/example/instrum/store.c index aa338aa6c3..ccc6f05aec 100644 --- a/example/instrum/store.c +++ b/example/instrum/store.c @@ -23,6 +23,7 @@ static __thread uint64_t profile_sample_ovf; #define STORE_FILE_NAME_SIZE_MAX 250 static char store_dir[STORE_DIR_NAME_SIZE_MAX]; +static int counters_cnt; int instr_store_init(void) { @@ -38,6 +39,7 @@ int instr_store_init(void) if (papi_init()) return -1; + counters_cnt = papi_counters_cnt(); return 0; } @@ -78,7 +80,7 @@ static void store_dump(void) profile_sample_tab[i].timestamp_ns, profile_sample_tab[i].diff_cyc, profile_sample_tab[i].name); - for (j = 0; j < SAMPLE_COUNTER_TAB_SIZE; j++) { + for (j = 0; j < counters_cnt; j++) { sprintf(smpl_tmp, ",%lld", profile_sample_tab[i].counters[j]); strcat(smpl, smpl_tmp); From 8a589ef28a879756585bfcc4eb803ddc02a3e345 Mon Sep 17 00:00:00 2001 From: Bogdan Pricope Date: Thu, 18 Jan 2018 15:31:28 +0200 Subject: [PATCH 5/5] example: instrum: configure instrumented API set Add configure time option to trim API set to be instrumented. Signed-off-by: Bogdan Pricope --- example/instrum/Makefile.am | 18 ++++++++++++++---- example/instrum/drv.h | 3 +++ example/instrum/instrum.c | 4 ++++ example/instrum/sched.h | 3 +++ example/m4/configure.m4 | 17 ++++++++++++----- 5 files changed, 36 insertions(+), 9 deletions(-) diff --git a/example/instrum/Makefile.am b/example/instrum/Makefile.am index 452b36c46b..30c26046f5 100644 --- a/example/instrum/Makefile.am +++ b/example/instrum/Makefile.am @@ -25,10 +25,20 @@ noinst_HEADERS = \ $(srcdir)/drv.h \ $(srcdir)/sched.h -__LIB__libinstrum_la_SOURCES = \ +INSTRUM_SRC = \ instrum.c \ store.c \ papi_cnt.c \ - init.c \ - drv.c \ - sched.c + init.c + +if CODE_INSTRUM_SCHED +AM_CFLAGS += -DCODE_INSTRUM_SCHED +INSTRUM_SRC += sched.c +endif + +if CODE_INSTRUM_DDF +AM_CFLAGS += -DCODE_INSTRUM_DDF +INSTRUM_SRC += drv.c +endif + +__LIB__libinstrum_la_SOURCES = $(INSTRUM_SRC) diff --git a/example/instrum/drv.h b/example/instrum/drv.h index 12441a7e4f..ed3dd7a086 100644 --- a/example/instrum/drv.h +++ b/example/instrum/drv.h @@ -7,6 +7,8 @@ #ifndef __INSTRUM_DRV_H__ #define __INSTRUM_DRV_H__ +#ifdef CODE_INSTRUM_DDF + #ifdef __cplusplus extern "C" { #endif @@ -16,4 +18,5 @@ int instr_odpdrv_init(void); #ifdef __cplusplus } #endif +#endif /* CODE_INSTRUM_DDF */ #endif /* __INSTRUM_DRV_H__ */ diff --git a/example/instrum/instrum.c b/example/instrum/instrum.c index 05b38da680..93b6cc78f2 100644 --- a/example/instrum/instrum.c +++ b/example/instrum/instrum.c @@ -21,11 +21,15 @@ static __attribute__((constructor)) void setup_wrappers(void) if (instr_odpinit_init()) return; +#ifdef CODE_INSTRUM_DDF if (instr_odpdrv_init()) return; +#endif /* CODE_INSTRUM_DDF */ +#ifdef CODE_INSTRUM_SCHED if (instr_odpsched_init()) return; +#endif /* CODE_INSTRUM_SCHED */ } static __attribute__((destructor)) void teardown_wrappers(void) diff --git a/example/instrum/sched.h b/example/instrum/sched.h index 2a092b0ed7..6cfc40bdcb 100644 --- a/example/instrum/sched.h +++ b/example/instrum/sched.h @@ -7,6 +7,8 @@ #ifndef __INSTRUM_SCHED_H__ #define __INSTRUM_SCHED_H__ +#ifdef CODE_INSTRUM_SCHED + #ifdef __cplusplus extern "C" { #endif @@ -16,4 +18,5 @@ int instr_odpsched_init(void); #ifdef __cplusplus } #endif +#endif /* CODE_INSTRUM_SCHED */ #endif /* __INSTRUM_SCHED_H__ */ diff --git a/example/m4/configure.m4 b/example/m4/configure.m4 index d2258bf27a..970dfd9274 100644 --- a/example/m4/configure.m4 +++ b/example/m4/configure.m4 @@ -7,15 +7,22 @@ AC_ARG_ENABLE([test-example], [test_example=yes]) AM_CONDITIONAL([test_example], [test x$test_example = xyes ]) -PAPI_PATH="" -code_instrumentation=no AC_ARG_WITH([papi-path], AS_HELP_STRING([--with-papi-path=DIR path to papi install directory]), [PAPI_PATH="$withval" - code_instrumentation=yes],[]) - + code_instrumentation=yes], + [PAPI_PATH="" + code_instrumentation=no]) AC_SUBST([PAPI_PATH]) -AM_CONDITIONAL([CODE_INSTRUM], [test x$code_instrumentation = xyes ]) +AM_CONDITIONAL([CODE_INSTRUM], [test x$code_instrumentation = xyes]) + +AC_ARG_WITH([code-instrum-profile], +AS_HELP_STRING([--with-code-instrum-profile=all|scheduler|ddf set code instrumentation profile]), + [code_instrum_profile="$withval"], + [code_instrum_profile="all"]) + +AM_CONDITIONAL([CODE_INSTRUM_SCHED],[test $code_instrum_profile = "all" || test $code_instrum_profile = "scheduler"]) +AM_CONDITIONAL([CODE_INSTRUM_DDF],[test $code_instrum_profile = "all" || test $code_instrum_profile = "ddf"]) AC_CONFIG_FILES([example/classifier/Makefile example/generator/Makefile