Back to home page

Project CMSSW displayed by LXR

 
 

    


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   //Storage class names to the value of the token to which they are assigned
0017   oneapi::tbb::concurrent_unordered_map<std::string, int> s_nameToToken;
0018   std::atomic<int> s_nextTokenValue{0};
0019 }  // namespace
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 /*=false*/) {
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 }