X-Git-Url: https://gerrit.opnfv.org/gerrit/gitweb?a=blobdiff_plain;f=src%2Fceph%2Fsrc%2Fperf_histogram.h;fp=src%2Fceph%2Fsrc%2Fperf_histogram.h;h=0000000000000000000000000000000000000000;hb=7da45d65be36d36b880cc55c5036e96c24b53f00;hp=06ebaf805bfef2b7fa49b1fc86c73f399175ef4d;hpb=691462d09d0987b47e112d6ee8740375df3c51b2;p=stor4nfv.git diff --git a/src/ceph/src/perf_histogram.h b/src/ceph/src/perf_histogram.h deleted file mode 100644 index 06ebaf8..0000000 --- a/src/ceph/src/perf_histogram.h +++ /dev/null @@ -1,227 +0,0 @@ -// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- -// vim: ts=8 sw=2 smarttab -/* - * Ceph - scalable distributed file system - * - * Copyright (C) 2017 OVH - * - * This is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License version 2.1, as published by the Free Software - * Foundation. See file COPYING. - * - */ - -#ifndef CEPH_COMMON_PERF_HISTOGRAM_H -#define CEPH_COMMON_PERF_HISTOGRAM_H - -#include "common/Formatter.h" -#include "include/int_types.h" - -#include -#include -#include -#include - -class PerfHistogramCommon { -public: - enum scale_type_d : uint8_t { - SCALE_LINEAR = 1, - SCALE_LOG2 = 2, - }; - - struct axis_config_d { - const char *m_name = nullptr; - scale_type_d m_scale_type = SCALE_LINEAR; - int64_t m_min = 0; - int64_t m_quant_size = 0; - int32_t m_buckets = 0; - axis_config_d() = default; - axis_config_d(const char* name, - scale_type_d scale_type, - int64_t min, - int64_t quant_size, - int32_t buckets) - : m_name(name), - m_scale_type(scale_type), - m_min(min), - m_quant_size(quant_size), - m_buckets(buckets) - {} - }; - -protected: - /// Dump configuration of one axis to a formatter - static void dump_formatted_axis(ceph::Formatter *f, const axis_config_d &ac); - - /// Quantize given value and convert to bucket number on given axis - static int64_t get_bucket_for_axis(int64_t value, const axis_config_d &ac); - - /// Calculate inclusive ranges of axis values for each bucket on that axis - static std::vector> get_axis_bucket_ranges( - const axis_config_d &ac); -}; - -/// PerfHistogram does trace a histogram of input values. It's an extended -/// version of a standard histogram which does trace characteristics of a single -/// one value only. In this implementation, values can be traced in multiple -/// dimensions - i.e. we can create a histogram of input request size (first -/// dimension) and processing latency (second dimension). Creating standard -/// histogram out of such multidimensional one is trivial and requires summing -/// values across dimensions we're not interested in. -template -class PerfHistogram : public PerfHistogramCommon { -public: - /// Initialize new histogram object - PerfHistogram(std::initializer_list axes_config) { - assert(axes_config.size() == DIM && - "Invalid number of axis configuration objects"); - - int i = 0; - for (const auto &ac : axes_config) { - assert(ac.m_buckets > 0 && "Must have at least one bucket on axis"); - assert(ac.m_quant_size > 0 && - "Quantization unit must be non-zero positive integer value"); - - m_axes_config[i++] = ac; - } - - m_rawData.reset(new std::atomic[get_raw_size()]); - } - - /// Copy from other histogram object - PerfHistogram(const PerfHistogram &other) - : m_axes_config(other.m_axes_config) { - int64_t size = get_raw_size(); - m_rawData.reset(new std::atomic[size]); - for (int64_t i = 0; i < size; i++) { - m_rawData[i] = other.m_rawData[i]; - } - } - - /// Set all histogram values to 0 - void reset() { - auto size = get_raw_size(); - for (auto i = size; --i >= 0;) { - m_rawData[i] = 0; - } - } - - /// Increase counter for given axis values by one - template - void inc(T... axis) { - auto index = get_raw_index_for_value(axis...); - m_rawData[index] += 1; - } - - /// Increase counter for given axis buckets by one - template - void inc_bucket(T... bucket) { - auto index = get_raw_index_for_bucket(bucket...); - m_rawData[index] += 1; - } - - /// Read value from given bucket - template - uint64_t read_bucket(T... bucket) const { - auto index = get_raw_index_for_bucket(bucket...); - return m_rawData[index]; - } - - /// Dump data to a Formatter object - void dump_formatted(ceph::Formatter *f) const { - // Dump axes configuration - f->open_array_section("axes"); - for (auto &ac : m_axes_config) { - dump_formatted_axis(f, ac); - } - f->close_section(); - - // Dump histogram values - dump_formatted_values(f); - } - -protected: - /// Raw data stored as linear space, internal indexes are calculated on - /// demand. - std::unique_ptr[]> m_rawData; - - /// Configuration of axes - std::array m_axes_config; - - /// Dump histogram counters to a formatter - void dump_formatted_values(ceph::Formatter *f) const { - visit_values([f](int) { f->open_array_section("values"); }, - [f](int64_t value) { f->dump_unsigned("value", value); }, - [f](int) { f->close_section(); }); - } - - /// Get number of all histogram counters - int64_t get_raw_size() { - int64_t ret = 1; - for (const auto &ac : m_axes_config) { - ret *= ac.m_buckets; - } - return ret; - } - - /// Calculate m_rawData index from axis values - template - int64_t get_raw_index_for_value(T... axes) const { - static_assert(sizeof...(T) == DIM, "Incorrect number of arguments"); - return get_raw_index_internal<0>(get_bucket_for_axis, 0, axes...); - } - - /// Calculate m_rawData index from axis bucket numbers - template - int64_t get_raw_index_for_bucket(T... buckets) const { - static_assert(sizeof...(T) == DIM, "Incorrect number of arguments"); - return get_raw_index_internal<0>( - [](int64_t bucket, const axis_config_d &ac) { - assert(bucket >= 0 && "Bucket index can not be negative"); - assert(bucket < ac.m_buckets && "Bucket index too large"); - return bucket; - }, - 0, buckets...); - } - - template - int64_t get_raw_index_internal(F bucket_evaluator, int64_t startIndex, - int64_t value, T... tail) const { - static_assert(level + 1 + sizeof...(T) == DIM, - "Internal consistency check"); - auto &ac = m_axes_config[level]; - auto bucket = bucket_evaluator(value, ac); - return get_raw_index_internal( - bucket_evaluator, ac.m_buckets * startIndex + bucket, tail...); - } - - template - int64_t get_raw_index_internal(F, int64_t startIndex) const { - static_assert(level == DIM, "Internal consistency check"); - return startIndex; - } - - /// Visit all histogram counters, call onDimensionEnter / onDimensionLeave - /// when starting / finishing traversal - /// on given axis, call onValue when dumping raw histogram counter value. - template - void visit_values(FDE onDimensionEnter, FV onValue, FDL onDimensionLeave, - int level = 0, int startIndex = 0) const { - if (level == DIM) { - onValue(m_rawData[startIndex]); - return; - } - - onDimensionEnter(level); - auto &ac = m_axes_config[level]; - startIndex *= ac.m_buckets; - for (int32_t i = 0; i < ac.m_buckets; ++i, ++startIndex) { - visit_values(onDimensionEnter, onValue, onDimensionLeave, level + 1, - startIndex); - } - onDimensionLeave(level); - } -}; - -#endif