File indexing completed on 2024-04-06 12:31:52
0001 #include "Utilities/StorageFactory/interface/StorageAccount.h"
0002 #include <cassert>
0003 #include <mutex>
0004 #include <sstream>
0005 #include <unistd.h>
0006 #include <sys/time.h>
0007 using namespace edm::storage;
0008
0009 namespace {
0010 char const* const kOperationNames[] = {
0011 "check", "close", "construct", "destruct", "flush", "open",
0012 "position", "prefetch", "read", "readActual", "readAsync", "readPrefetchToCache",
0013 "readViaCache", "readv", "resize", "seek", "stagein", "stat",
0014 "write", "writeActual", "writeViaCache", "writev"};
0015
0016
0017 oneapi::tbb::concurrent_unordered_map<std::string, int> s_nameToToken;
0018 std::atomic<int> s_nextTokenValue{0};
0019 }
0020
0021 StorageAccount::StorageStats StorageAccount::m_stats;
0022
0023 static std::string i2str(int i) {
0024 std::ostringstream t;
0025 t << i;
0026 return t.str();
0027 }
0028
0029 static std::string d2str(double d) {
0030 std::ostringstream t;
0031 t << d;
0032 return t.str();
0033 }
0034
0035 inline char const* StorageAccount::operationName(Operation operation) {
0036 return kOperationNames[static_cast<int>(operation)];
0037 }
0038
0039 StorageAccount::StorageClassToken StorageAccount::tokenForStorageClassName(std::string const& iName) {
0040 auto itFound = s_nameToToken.find(iName);
0041 if (itFound != s_nameToToken.end()) {
0042 return StorageClassToken(itFound->second);
0043 }
0044 int value = s_nextTokenValue++;
0045
0046 s_nameToToken.insert(std::make_pair(iName, value));
0047
0048 return StorageClassToken(value);
0049 }
0050
0051 const std::string& StorageAccount::nameForToken(StorageClassToken iToken) {
0052 for (auto it = s_nameToToken.begin(), itEnd = s_nameToToken.end(); it != itEnd; ++it) {
0053 if (it->second == iToken.value()) {
0054 return it->first;
0055 }
0056 }
0057 assert(false);
0058 }
0059
0060 std::string StorageAccount::summaryText(bool banner ) {
0061 bool first = true;
0062 std::ostringstream os;
0063 if (banner)
0064 os << "stats: class/operation/attempts/successes/amount/time-total/time-min/time-max\n";
0065 for (auto i = s_nameToToken.begin(); i != s_nameToToken.end(); ++i) {
0066 auto const& opStats = m_stats[i->second];
0067 for (auto j = opStats.begin(); j != opStats.end(); ++j, first = false)
0068 os << (first ? "" : "; ") << (i->first) << '/' << kOperationNames[j->first] << '=' << j->second.attempts << '/'
0069 << j->second.successes << '/' << (static_cast<double>(j->second.amount) / 1024 / 1024) << "MB/"
0070 << (static_cast<double>(j->second.timeTotal) / 1000 / 1000) << "ms/"
0071 << (static_cast<double>(j->second.timeMin) / 1000 / 1000) << "ms/"
0072 << (static_cast<double>(j->second.timeMax) / 1000 / 1000) << "ms";
0073 }
0074 return os.str();
0075 }
0076
0077 void StorageAccount::fillSummary(std::map<std::string, std::string>& summary) {
0078 int const oneM = 1000 * 1000;
0079 int const oneMeg = 1024 * 1024;
0080 for (auto i = s_nameToToken.begin(); i != s_nameToToken.end(); ++i) {
0081 auto const& opStats = m_stats[i->second];
0082 for (auto j = opStats.begin(); j != opStats.end(); ++j) {
0083 std::ostringstream os;
0084 os << "Timing-" << i->first << "-" << kOperationNames[j->first] << "-";
0085 summary.insert(std::make_pair(os.str() + "numOperations", i2str(j->second.attempts)));
0086 summary.insert(std::make_pair(os.str() + "numSuccessfulOperations", i2str(j->second.successes)));
0087 summary.insert(
0088 std::make_pair(os.str() + "totalMegabytes", d2str(static_cast<double>(j->second.amount) / oneMeg)));
0089 summary.insert(std::make_pair(os.str() + "totalMsecs", d2str(static_cast<double>(j->second.timeTotal) / oneM)));
0090 summary.insert(std::make_pair(os.str() + "minMsecs", d2str(static_cast<double>(j->second.timeMin) / oneM)));
0091 summary.insert(std::make_pair(os.str() + "maxMsecs", d2str(static_cast<double>(j->second.timeMax) / oneM)));
0092 }
0093 }
0094 }
0095
0096 const StorageAccount::StorageStats& StorageAccount::summary() { return m_stats; }
0097
0098 StorageAccount::Counter& StorageAccount::counter(StorageClassToken token, Operation operation) {
0099 auto& opstats = m_stats[token.value()];
0100
0101 return opstats[static_cast<int>(operation)];
0102 }
0103
0104 StorageAccount::Stamp::Stamp(Counter& counter) : m_counter(counter), m_start(std::chrono::steady_clock::now()) {
0105 m_counter.attempts++;
0106 }
0107
0108 void StorageAccount::Stamp::tick(uint64_t amount, int64_t count) const {
0109 std::chrono::nanoseconds elapsed_ns = std::chrono::steady_clock::now() - m_start;
0110 uint64_t elapsed = elapsed_ns.count();
0111 m_counter.successes++;
0112
0113 m_counter.vector_count += count;
0114 m_counter.vector_square += count * count;
0115 m_counter.amount += amount;
0116 Counter::addTo(m_counter.amount_square, amount * amount);
0117
0118 Counter::addTo(m_counter.timeTotal, elapsed);
0119 if (elapsed < m_counter.timeMin || m_counter.successes == 1)
0120 m_counter.timeMin = elapsed;
0121 if (elapsed > m_counter.timeMax)
0122 m_counter.timeMax = elapsed;
0123 }