예제 #1
0
static void
makeDerivedMetrics(Prof::Metric::Mgr& metricMgr,
		   uint /*Analysis::Args::MetricFlg*/ metrics)
{
  if (Analysis::Args::MetricFlg_isSum(metrics)) {
    bool needAllStats =
      Analysis::Args::MetricFlg_isSet(metrics,
				      Analysis::Args::MetricFlg_StatsAll);
    bool needMultiOccurance = Analysis::Args::MetricFlg_isThread(metrics);
    metricMgr.makeSummaryMetrics(needAllStats, needMultiOccurance);
  }
  
  if (!Analysis::Args::MetricFlg_isThread(metrics)) {
    using namespace Prof;

    for (uint i = 0; i < metricMgr.size(); i++) {
      Metric::ADesc* m = metricMgr.metric(i);
      Metric::SampledDesc* mm = dynamic_cast<Metric::SampledDesc*>(m);
      if (mm) {
	mm->isVisible(false);
	mm->isSortKey(false);
      }
    }

    for (uint i = 0; i < metricMgr.size(); i++) {
      Metric::ADesc* m = metricMgr.metric(i);
      Metric::DerivedDesc* mm = dynamic_cast<Metric::DerivedDesc*>(m);
      if (mm) {
	mm->isSortKey(true);
	break;
      }
    }
  }
}
예제 #2
0
Prof::CallPath::Profile*
read(const char* prof_fnm, uint groupId, uint rFlags)
{
  // -------------------------------------------------------
  // 
  // -------------------------------------------------------

  Prof::CallPath::Profile* prof = NULL;
  try {
    DIAG_MsgIf(0, "Reading: '" << prof_fnm << "'");
    prof = Prof::CallPath::Profile::make(prof_fnm, rFlags, /*outfs*/ NULL);
  }
  catch (...) {
    DIAG_EMsg("While reading profile '" << prof_fnm << "'...");
    throw;
  }

  // -------------------------------------------------------
  // Potentially update the profile's metrics
  // -------------------------------------------------------

  if (groupId > 0) {
    Prof::Metric::Mgr* metricMgr = prof->metricMgr();
    for (uint i = 0; i < metricMgr->size(); ++i) {
      Prof::Metric::ADesc* m = metricMgr->metric(i);
      m->namePfx(StrUtil::toStr(groupId));
    }
    metricMgr->recomputeMaps();
  }

  return prof;
}
예제 #3
0
MetricCursor::MetricCursor(const Prof::Metric::Mgr& metricMgr,
			   const Prof::Flat::LM& proflm, 
			   const BinUtil::LM& lm)
{
  m_loadAddr = (VMA)proflm.load_addr();
  m_doUnrelocate = lm.doUnrelocate(m_loadAddr);
  
  // --------------------------------------------------------
  // Find all metrics for load module and compute totals for each metric
  // For now we have one metric per sampled event.
  // --------------------------------------------------------

  // NOTE: only handles raw events

  for (uint i = 0; i < metricMgr.size(); ++i) {
    const Prof::Metric::ADesc* m = metricMgr.metric(i);
    const Prof::Metric::SampledDesc* mm =
      dynamic_cast<const Prof::Metric::SampledDesc*>(m);
    if (mm) {
      uint mIdx = (uint)StrUtil::toUInt64(mm->profileRelId());
      const Prof::Flat::EventData& profevent = proflm.event(mIdx);
      m_metricDescs.push_back(&profevent);
    }
  }

  m_metricTots.resize(m_metricDescs.size());
  for (uint i = 0; i < m_metricDescs.size(); ++i) {
    const Prof::Flat::EventData& profevent = *(m_metricDescs[i]);
    uint64_t& metricTotal = m_metricTots[i];
    metricTotal = 0;

    for (uint j = 0; j < profevent.num_data(); ++j) {
      const Prof::Flat::Datum& evdat = profevent.datum(j);
      uint32_t count = evdat.second;
      metricTotal += count;
    }
  }

  m_curMetricIdx.resize(m_metricDescs.size());
  for (uint i = 0; i < m_curMetricIdx.size(); ++i) {
    m_curMetricIdx[i] = 0;
  }

  m_metricValAtVMA.resize(m_metricDescs.size());
}
예제 #4
0
// makeReturnCountMetric: A return count refers to the number of times
// a given CCT node is called by its parent context.  However, when
// hpcrun records return counts, there is no structure (e.g. procedure
// frames) in the CCT.  An an example, in the CCT fragment below, the
// return count [3] at 0xc means that 0xc returned to 0xbeef 3 times.
// Simlarly, 0xbeef returned to its caller 5 times.
//
//              |               |
//       ip: 0xbeef [5]         |
//       /      |      \        |
//   0xa [1]  0xb [2]  0xc [3]  |
//      |       |       |       |
//
// To be able to say procedure F is called by procedure G x times
// within this context, it is necessary to aggregate these counts at
// the newly added procedure frames (Struct::ProcFrm).
static void
makeReturnCountMetric(Prof::CallPath::Profile& prof)
{
  std::vector<uint> retCntId;

  // -------------------------------------------------------
  // find return count metrics, if any
  // -------------------------------------------------------
  Prof::Metric::Mgr* metricMgr = prof.metricMgr();
  for (uint i = 0; i < metricMgr->size(); ++i) {
    Prof::Metric::ADesc* m = metricMgr->metric(i);
    if (m->nameBase().find(HPCRUN_METRIC_RetCnt) != string::npos) {
      retCntId.push_back(m->id());
      m->computedType(Prof::Metric::ADesc::ComputedTy_Final);
      m->type(Prof::Metric::ADesc::TyExcl);
    }
  }

  if (retCntId.empty()) {
    return;
  }

  // -------------------------------------------------------
  // propagate and aggregate return counts
  // -------------------------------------------------------
  Prof::CCT::ANode* cct_root = prof.cct()->root();
  Prof::CCT::ANodeIterator it(cct_root, NULL/*filter*/, false/*leavesOnly*/,
			      IteratorStack::PostOrder);
  for (Prof::CCT::ANode* n = NULL; (n = it.current()); ++it) {
    if (typeid(*n) != typeid(Prof::CCT::ProcFrm) && n != cct_root) {
      Prof::CCT::ANode* n_parent = n->parent();
      for (uint i = 0; i < retCntId.size(); ++i) {
	uint mId = retCntId[i];
	n_parent->demandMetric(mId) += n->demandMetric(mId);
	n->metric(mId) = 0.0;
      }
    }
  }
}