From 0e578927180ac933a0211ef9ad7f063fe1e4d6bc Mon Sep 17 00:00:00 2001 From: Sergei Vinogradov Date: Mon, 3 Jun 2019 05:50:55 -0700 Subject: [PATCH] Add ITT instrumentation for slab and cuckoo MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit To build pelikan with ITT instrumentation you should have the Intel® VTune™Amplifier installed and source the amplxe-vars.sh. Run cmake with the -DHAVE_ITT_INSTRUMENTATION=yes option. Co-authored-by: Michal Biesek Co-authored-by: Piotr Balcer --- CMakeLists.txt | 12 +++++ cmake/FindITTNOTIFY.cmake | 65 ++++++++++++++++++++++++ cmake/config.h.in | 2 + deps/ccommon/CMakeLists.txt | 12 +++++ deps/ccommon/cmake/FindITTNOTIFY.cmake | 65 ++++++++++++++++++++++++ deps/ccommon/config.h.in | 2 + deps/ccommon/include/cc_define.h | 4 ++ deps/ccommon/include/cc_itt.h | 69 ++++++++++++++++++++++++++ src/storage/cuckoo/cuckoo.c | 9 ++++ src/storage/slab/item.c | 3 ++ src/storage/slab/slab.c | 6 +++ src/storage/slab/slab.h | 3 ++ 12 files changed, 252 insertions(+) create mode 100644 cmake/FindITTNOTIFY.cmake create mode 100644 deps/ccommon/cmake/FindITTNOTIFY.cmake create mode 100644 deps/ccommon/include/cc_itt.h diff --git a/CMakeLists.txt b/CMakeLists.txt index ad7a4eda2..084723a9d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -48,6 +48,7 @@ option(HAVE_RUST "build features written in rust" OFF) option(RUST_USE_MUSL "build rust deps against musl" OFF) option(BUILD_AND_INSTALL_CHECK "build our own version of check and link against it" OFF) option(USE_PMEM "build persistent memory features" OFF) +option(HAVE_ITT_INSTRUMENTATION "instrument code with ITT API" OFF) option(COVERAGE "code coverage" OFF) @@ -160,6 +161,17 @@ if (USE_PMEM) link_directories(${LIBPMEM_LIBRARY_DIRS}) endif(USE_PMEM) +if (HAVE_ITT_INSTRUMENTATION) + if(PKG_CONFIG_FOUND) + pkg_check_modules(ITTNOTIFY REQUIRED ittnotify>=1.0) + else() + find_package(ITTNOTIFY REQUIRED 1.0) + endif() + include_directories(${ITTNOTIFY_INCLUDE_DIRS}) + link_directories(${ITTNOTIFY_LIBRARY_DIRS}) + link_libraries(${ITTNOTIFY_LIBRARIES}) +endif(HAVE_ITT_INSTRUMENTATION) + find_package(Threads) if(TARGET_CDB) diff --git a/cmake/FindITTNOTIFY.cmake b/cmake/FindITTNOTIFY.cmake new file mode 100644 index 000000000..b0ed605ac --- /dev/null +++ b/cmake/FindITTNOTIFY.cmake @@ -0,0 +1,65 @@ +# ITTNOTIFY is the instrumentation and tracing technology (ITT) APIs provided by +# the Intel® VTune™Amplifier enable your application to generate and control +# the collection of trace data during its execution. +# +# The following variables are set when ITTNOTIFY is found: +# ITTNOTIFY_FOUND = Set to true, if all components of ITTNOTIFY have been found. +# ITTNOTIFY_INCLUDE_DIRS = Include path for the header files of ITTNOTIFY. +# ITTNOTIFY_LIBRARY_DIRS = Library search path for the ITTNOTIFY libraries. +# ITTNOTIFY_LIBRARIES = Link these to use ITTNOTIFY. +# ITTNOTIFY_LFLAGS = Linker flags (optional). + +if (NOT ITTNOTIFY_FOUND) + + find_program(VTUNE_EXECUTABLE amplxe-cl) + + if(NOT VTUNE_EXECUTABLE) + set(ITTNOTIFY_FOUND false) + return() + endif() + + get_filename_component(VTUNE_DIR ${VTUNE_EXECUTABLE} PATH) + set(ITTNOTIFY_ROOT_DIR "${VTUNE_DIR}/..") + + ##_____________________________________________________________________________ + ## Check for the header files + + find_path (ITTNOTIFY_INCLUDE_DIRS + NAMES ittnotify.h + HINTS ${ITTNOTIFY_ROOT_DIR} + PATHS /usr /usr/local + PATH_SUFFIXES include + ) + + ##_____________________________________________________________________________ + ## Check for the library + + find_library (ITTNOTIFY_LIBRARIES ittnotify + HINTS ${ITTNOTIFY_ROOT_DIR} + PATHS /usr /usr/local /opt/local + PATH_SUFFIXES lib64 lib + ) + + ##_____________________________________________________________________________ + ## Actions taken when all components have been found + + find_package_handle_standard_args (ITTNOTIFY DEFAULT_MSG ITTNOTIFY_LIBRARIES ITTNOTIFY_INCLUDE_DIRS) + + if (ITTNOTIFY_FOUND) + if (NOT ITTNOTIFY_FIND_QUIETLY) + message (STATUS "Found components for ITTNOTIFY") + message (STATUS "ITTNOTIFY_ROOT_DIR = ${ITTNOTIFY_ROOT_DIR}") + message (STATUS "ITTNOTIFY_INCLUDE_DIRS = ${ITTNOTIFY_INCLUDE_DIRS}") + message (STATUS "ITTNOTIFY_LIBRARIES = ${ITTNOTIFY_LIBRARIES}") + endif (NOT ITTNOTIFY_FIND_QUIETLY) + else (ITTNOTIFY_FOUND) + if (ITTNOTIFY_FIND_REQUIRED) + message (FATAL_ERROR "Could not find ITTNOTIFY!") + endif (ITTNOTIFY_FIND_REQUIRED) + endif (ITTNOTIFY_FOUND) + + if(UNIX) + list(APPEND ITTNOTIFY_LIBRARIES dl) + endif() + +endif (NOT ITTNOTIFY_FOUND) diff --git a/cmake/config.h.in b/cmake/config.h.in index 596843a86..9cba341e6 100644 --- a/cmake/config.h.in +++ b/cmake/config.h.in @@ -16,6 +16,8 @@ #cmakedefine HAVE_STATS +#cmakedefine HAVE_ITT_INSTRUMENTATION + #cmakedefine TARGET_SLIMCACHE #cmakedefine TARGET_TWEMCACHE diff --git a/deps/ccommon/CMakeLists.txt b/deps/ccommon/CMakeLists.txt index e81bac89c..633c52090 100644 --- a/deps/ccommon/CMakeLists.txt +++ b/deps/ccommon/CMakeLists.txt @@ -57,6 +57,7 @@ option(HAVE_STATS "stats enabled by default" ON) option(HAVE_DEBUG_MM "debugging oriented memory management disabled by default" OFF) option(COVERAGE "code coverage" OFF) option(HAVE_RUST "rust bindings not built by default" OFF) +option(HAVE_ITT_INSTRUMENTATION "instrument code with ITT API" OFF) if(HAVE_RUST) option(RUST_VERBOSE_BUILD "pass -vv to cargo compilation" OFF) @@ -164,6 +165,17 @@ if(NOT CHECK_FOUND) find_package(Check QUIET 0.10) endif() +if (HAVE_ITT_INSTRUMENTATION) + if(PKG_CONFIG_FOUND) + pkg_check_modules(ITTNOTIFY REQUIRED ittnotify>=1.0) + else() + find_package(ITTNOTIFY REQUIRED 1.0) + endif() + include_directories(${ITTNOTIFY_INCLUDE_DIRS}) + link_directories(${ITTNOTIFY_LIBRARY_DIRS}) + link_libraries(${ITTNOTIFY_LIBRARIES}) +endif(HAVE_ITT_INSTRUMENTATION) + find_package(Threads) diff --git a/deps/ccommon/cmake/FindITTNOTIFY.cmake b/deps/ccommon/cmake/FindITTNOTIFY.cmake new file mode 100644 index 000000000..0c1ae6bc5 --- /dev/null +++ b/deps/ccommon/cmake/FindITTNOTIFY.cmake @@ -0,0 +1,65 @@ +# ITTNOTIFY is the instrumentation and tracing technology (ITT) APIs provided by +# the Intel® VTune™Amplifier enable your application to generate and control +# the collection of trace data during its execution. +# +# The following variables are set when ITTNOTIFY is found: +# ITTNOTIFY_FOUND = Set to true, if all components of ITTNOTIFY have been found. +# ITTNOTIFY_INCLUDE_DIRS = Include path for the header files of ITTNOTIFY. +# ITTNOTIFY_LIBRARY_DIRS = Library search path for the ITTNOTIFY libraries. +# ITTNOTIFY_LIBRARIES = Link these to use ITTNOTIFY. +# ITTNOTIFY_LFLAGS = Linker flags (optional). + +if (NOT ITTNOTIFY_FOUND) + + find_program(VTUNE_EXECUTABLE amplxe-cl) + + if(NOT VTUNE_EXECUTABLE) + set(ITTNOTIFY_FOUND false) + return() + endif() + + get_filename_component(VTUNE_DIR ${VTUNE_EXECUTABLE} PATH) + set(ITTNOTIFY_ROOT_DIR "${VTUNE_DIR}/..") + + ##_____________________________________________________________________________ + ## Check for the header files + + find_path (ITTNOTIFY_INCLUDE_DIRS + NAMES ittnotify.h + HINTS ${ITTNOTIFY_ROOT_DIR} + PATHS /usr /usr/local + PATH_SUFFIXES include + ) + + ##_____________________________________________________________________________ + ## Check for the library + + find_library (ITTNOTIFY_LIBRARIES ittnotify + HINTS ${ITTNOTIFY_ROOT_DIR} + PATHS /usr /usr/local /opt/local + PATH_SUFFIXES lib64 lib + ) + + ##_____________________________________________________________________________ + ## Actions taken when all components have been found + + find_package_handle_standard_args (ITTNOTIFY DEFAULT_MSG ITTNOTIFY_LIBRARIES ITTNOTIFY_INCLUDE_DIRS) + + if (ITTNOTIFY_FOUND) + if (NOT ITTNOTIFY_FIND_QUIETLY) + message (STATUS "Found components for ITTNOTIFY") + message (STATUS "ITTNOTIFY_ROOT_DIR = ${ITTNOTIFY_ROOT_DIR}") + message (STATUS "ITTNOTIFY_INCLUDE_DIRS = ${ITTNOTIFY_INCLUDE_DIRS}") + message (STATUS "ITTNOTIFY_LIBRARIES = ${ITTNOTIFY_LIBRARIES}") + endif (NOT ITTNOTIFY_FIND_QUIETLY) + else (ITTNOTIFY_FOUND) + if (ITTNOTIFY_FIND_REQUIRED) + message (FATAL_ERROR "Could not find ITTNOTIFY!") + endif (ITTNOTIFY_FIND_REQUIRED) + endif (ITTNOTIFY_FOUND) + + if(UNIX) + list(APPEND ITTNOTIFY_LIBRARIES dl) + endif() + +endif (NOT ITTNOTIFY_FOUND) diff --git a/deps/ccommon/config.h.in b/deps/ccommon/config.h.in index 5ead881f8..f2fe91ba5 100644 --- a/deps/ccommon/config.h.in +++ b/deps/ccommon/config.h.in @@ -19,3 +19,5 @@ #cmakedefine HAVE_STATS #cmakedefine HAVE_DEBUG_MM + +#cmakedefine HAVE_ITT_INSTRUMENTATION diff --git a/deps/ccommon/include/cc_define.h b/deps/ccommon/include/cc_define.h index 33a9983ee..6a207036f 100644 --- a/deps/ccommon/include/cc_define.h +++ b/deps/ccommon/include/cc_define.h @@ -55,6 +55,10 @@ extern "C" { #define CC_DEBUG_MM 1 #endif +#ifdef HAVE_ITT_INSTRUMENTATION +#define CC_ITT 1 +#endif + #define CC_OK 0 #define CC_ERROR -1 diff --git a/deps/ccommon/include/cc_itt.h b/deps/ccommon/include/cc_itt.h new file mode 100644 index 000000000..583c72d93 --- /dev/null +++ b/deps/ccommon/include/cc_itt.h @@ -0,0 +1,69 @@ +#pragma once + +#include + +#ifdef CC_ITT +#include "ittnotify.h" +#endif + +#ifdef __cplusplus +extern "C" { +#endif +#ifdef CC_ITT + +#define ITT_DOMAIN_NAME "cc_itt" + +#define cc_declare_itt_function(_keyword, _name) \ + _keyword __itt_heap_function _name + +#define cc_create_itt_malloc(_name) \ + _name = __itt_heap_function_create(#_name, ITT_DOMAIN_NAME) + +#define cc_create_itt_free(_name) \ + _name = __itt_heap_function_create(#_name, ITT_DOMAIN_NAME) + +#define cc_create_itt_realloc(_name) \ + _name = __itt_heap_function_create(#_name, ITT_DOMAIN_NAME) + +#define cc_itt_alloc(_itt_heap_f, _p, _s) do { \ + __itt_heap_allocate_begin(_itt_heap_f, (size_t)(_s), 0); \ + __itt_heap_allocate_end(_itt_heap_f, (void *)&(_p), (size_t)(_s), 0); \ +} while (0) + +#define cc_itt_zalloc(_itt_heap_f, _p, _s) do { \ + __itt_heap_allocate_begin(_itt_heap_f, (size_t)(_s), 1); \ + __itt_heap_allocate_end(_itt_heap_f, (void *)&(_p), (size_t)(_s), 1); \ +} while (0) + +#define cc_itt_free(_itt_heap_f, _p) do { \ + __itt_heap_free_begin(_itt_heap_f, _p); \ + __itt_heap_free_end(_itt_heap_f, _p); \ +} while (0) + +#define cc_itt_realloc(_itt_heap_f, _p, _np, _s) do { \ + __itt_heap_reallocate_begin(_itt_heap_f, _p, (size_t)(_s), 0); \ + __itt_heap_reallocate_end(_itt_heap_f, _p, (void *)&(_np), (size_t)(_s), 0); \ +} while (0) + +#define cc_itt_heap_internal_access() \ + __itt_heap_internal_access_begin() + +#define cc_itt_heap_internal_access_end() \ + __itt_heap_internal_access_end() + +#else +#define cc_declare_itt_function(_keyword, _name) +#define cc_create_itt_malloc(_name) +#define cc_create_itt_free(_name) +#define cc_create_itt_realloc(_name) +#define cc_itt_alloc(_itt_heap_f, _p, _s) +#define cc_itt_zalloc(_itt_heap_f, _p, _s) +#define cc_itt_free(_itt_heap_f, _p) +#define cc_itt_realloc(_itt_heap_f, _p, _np, _s) +#define cc_itt_heap_internal_access_begin() +#define cc_itt_heap_internal_access_end() +#endif /* CC_ITT */ + +#ifdef __cplusplus +} +#endif diff --git a/src/storage/cuckoo/cuckoo.c b/src/storage/cuckoo/cuckoo.c index a5f494987..30bf9746a 100644 --- a/src/storage/cuckoo/cuckoo.c +++ b/src/storage/cuckoo/cuckoo.c @@ -4,6 +4,7 @@ #include #include #include +#include #include @@ -62,6 +63,9 @@ static size_t hash_size; /* item_size * max_nitem, computed at setup */ DECR_N(cuckoo_metrics, item_data_curr, item_datalen(it)); \ } while(0) +cc_declare_itt_function(static, cuckoo_malloc); +cc_declare_itt_function(static, cuckoo_free); + static inline uint32_t vlen(struct val *val) { if (val->type == VAL_TYPE_INT) { @@ -291,6 +295,9 @@ cuckoo_setup(cuckoo_options_st *options, cuckoo_metrics_st *metrics) } ds = datapool_addr(pool); + cc_create_itt_malloc(cuckoo_malloc); + cc_create_itt_free(cuckoo_free); + cuckoo_init = true; } @@ -395,6 +402,7 @@ cuckoo_insert(struct bstring *key, struct val *val, proc_time_i expire) item_set(it, key, val, expire); INCR(cuckoo_metrics, item_insert); ITEM_METRICS_INCR(it); + cc_itt_alloc(cuckoo_malloc, it, item_size); return it; } @@ -438,6 +446,7 @@ cuckoo_delete(struct bstring *key) ITEM_METRICS_DECR(it); item_delete(it); log_verb("deleting item at location %p", it); + cc_itt_free(cuckoo_free, it); return true; } else { diff --git a/src/storage/slab/item.c b/src/storage/slab/item.c index 088a2811d..39f5e408a 100644 --- a/src/storage/slab/item.c +++ b/src/storage/slab/item.c @@ -98,6 +98,7 @@ _item_dealloc(struct item **it_p) PERSLAB_DECR(id, item_curr); slab_put_item(*it_p, id); + cc_itt_free(slab_free, *it_p); *it_p = NULL; } @@ -147,6 +148,8 @@ item_insert(struct item *it, const struct bstring *key) _item_link(it, false); log_verb("insert it %p of id %"PRIu8" for key %.*s", it, it->id, key->len, key->data); + + cc_itt_alloc(slab_malloc, it, item_size(it)); } /* diff --git a/src/storage/slab/slab.c b/src/storage/slab/slab.c index 874e20d9c..2cf1c9fab 100644 --- a/src/storage/slab/slab.c +++ b/src/storage/slab/slab.c @@ -61,6 +61,9 @@ delta_time_i max_ttl = ITEM_MAX_TTL; static bool slab_init = false; slab_metrics_st *slab_metrics = NULL; +cc_declare_itt_function(,slab_malloc); +cc_declare_itt_function(,slab_free); + void slab_print(void) { @@ -595,6 +598,9 @@ slab_setup(slab_options_st *options, slab_metrics_st *metrics) goto error; } + cc_create_itt_malloc(slab_malloc); + cc_create_itt_free(slab_free); + slab_init = true; return; diff --git a/src/storage/slab/slab.h b/src/storage/slab/slab.h index dd04cc2b9..908a0b5ac 100644 --- a/src/storage/slab/slab.h +++ b/src/storage/slab/slab.h @@ -5,6 +5,7 @@ #include "slabclass.h" #include +#include #include #include #include @@ -146,6 +147,8 @@ TAILQ_HEAD(slab_tqh, slab); extern struct hash_table *hash_table; extern size_t slab_size; extern slab_metrics_st *slab_metrics; +cc_declare_itt_function(extern, slab_malloc); +cc_declare_itt_function(extern, slab_free); /* * Return the usable space for item sized chunks that would be carved out