Skip to content

Commit

Permalink
Implement Topdown metric support
Browse files Browse the repository at this point in the history
This commit adds support for the topdown metrics (fe-bound, be-bound
etc.) as seen in perf
  • Loading branch information
cvonelm committed Feb 6, 2024
1 parent 32266e2 commit 6a3724c
Show file tree
Hide file tree
Showing 12 changed files with 382 additions and 0 deletions.
3 changes: 3 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,9 @@ set(SOURCE_FILES
src/perf/counter/userspace/reader.cpp

src/perf/counter/userspace/writer.cpp
src/perf/counter/topdown/reader.cpp

src/perf/counter/topdown/writer.cpp
src/perf/counter/group/writer.cpp

src/perf/sample/writer.cpp
Expand Down
2 changes: 2 additions & 0 deletions include/lo2s/config.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,8 @@ struct Config
bool use_nec;
std::chrono::microseconds nec_read_interval;
std::chrono::milliseconds nec_check_interval;
//topdown
bool topdown;
};

const Config& config();
Expand Down
8 changes: 8 additions & 0 deletions include/lo2s/measurement_scope.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ enum class MeasurementScopeType
USERSPACE_METRIC,
BIO,
SYSCALL,
TOPDOWN,
UNKNOWN
};

Expand Down Expand Up @@ -71,6 +72,11 @@ struct MeasurementScope
return { MeasurementScopeType::SYSCALL, s };
}

static MeasurementScope topdown(ExecutionScope s)
{
return { MeasurementScopeType::SYSCALL, s };
}

friend bool operator==(const MeasurementScope& lhs, const MeasurementScope& rhs)
{
return (lhs.scope == rhs.scope) && lhs.type == rhs.type;
Expand Down Expand Up @@ -101,6 +107,8 @@ struct MeasurementScope
return fmt::format("block layer I/O events for {}", scope.name());
case MeasurementScopeType::SYSCALL:
return fmt::format("syscall events for {}", scope.name());
case MeasurementScopeType::TOPDOWN:
return fmt::format("topdown events for {}", scope.name());
default:
throw new std::runtime_error("Unknown ExecutionScopeType!");
}
Expand Down
3 changes: 3 additions & 0 deletions include/lo2s/monitor/scope_monitor.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
#include <lo2s/monitor/poll_monitor.hpp>

#include <lo2s/perf/counter/group/writer.hpp>
#include <lo2s/perf/counter/topdown/writer.hpp>
#include <lo2s/perf/counter/userspace/writer.hpp>

#include <lo2s/perf/sample/writer.hpp>
Expand Down Expand Up @@ -74,6 +75,8 @@ class ScopeMonitor : public PollMonitor
std::unique_ptr<perf::sample::Writer> sample_writer_;
std::unique_ptr<perf::counter::group::Writer> group_counter_writer_;
std::unique_ptr<perf::counter::userspace::Writer> userspace_counter_writer_;

std::unique_ptr<perf::counter::topdown::Writer> topdown_writer_;
};
} // namespace monitor
} // namespace lo2s
72 changes: 72 additions & 0 deletions include/lo2s/perf/counter/topdown/reader.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
/*
* This file is part of the lo2s software.
* Linux OTF2 sampling
*
* Copyright (c) 2021,
* Technische Universitaet Dresden, Germany
*
* lo2s is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* lo2s is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with lo2s. If not, see <http://www.gnu.org/licenses/>.
*/

#pragma once

#include <lo2s/execution_scope.hpp>
#include <lo2s/perf/counter/counter_collection.hpp>
#include <lo2s/trace/trace.hpp>

#include <cstdint>

#include <vector>

#include <cstdlib>
namespace lo2s
{
namespace perf
{
namespace counter
{
namespace topdown
{
struct TopdownEvent
{
uint64_t nr;
uint64_t slots;
uint64_t retiring;
uint64_t bad_spec;
uint64_t fe_bound;
uint64_t be_bound;
};

template <class T>
class Reader
{
public:
Reader(ExecutionScope scope);

void read();

int fd()
{
return timer_fd_;
}

protected:
int leader_fd_;
std::vector<int> counter_fds_;
int timer_fd_;
};
} // namespace topdown
} // namespace counter
} // namespace perf
} // namespace lo2s
54 changes: 54 additions & 0 deletions include/lo2s/perf/counter/topdown/writer.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
/*
* This file is part of the lo2s software.
* Linux OTF2 sampling
*
* Copyright (c) 2018,
* Technische Universitaet Dresden, Germany
*
* lo2s is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* lo2s is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with lo2s. If not, see <http://www.gnu.org/licenses/>.
*/

#pragma once

#include <lo2s/perf/counter/counter_collection.hpp>
#include <lo2s/perf/counter/metric_writer.hpp>
#include <lo2s/perf/counter/topdown/reader.hpp>
#include <lo2s/perf/time/converter.hpp>
#include <lo2s/trace/trace.hpp>

namespace lo2s
{
namespace perf
{
namespace counter
{
namespace topdown
{
class Writer : public Reader<Writer>
{
public:
Writer(ExecutionScope scope, trace::Trace& trace);

bool handle(TopdownEvent* ev);

private:
time::Converter time_converter_;
otf2::writer::local& writer_;
otf2::definition::metric_instance metric_instance_;
otf2::event::metric metric_event_;
};
} // namespace topdown
} // namespace counter
} // namespace perf
} // namespace lo2s
28 changes: 28 additions & 0 deletions include/lo2s/trace/trace.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,7 @@ class Trace
otf2::definition::mapping_table merge_syscall_contexts(const std::set<int64_t>& used_syscalls);

otf2::writer::local& sample_writer(const ExecutionScope& scope);
otf2::writer::local& topdown_writer(const ExecutionScope& scope);
otf2::writer::local& metric_writer(const MeasurementScope& scope);
otf2::writer::local& syscall_writer(const Cpu& cpu);
otf2::writer::local& bio_writer(BlockDevice dev);
Expand Down Expand Up @@ -169,6 +170,32 @@ class Trace
return cpuid_metric_class_;
}

otf2::definition::metric_class topdown_metric_class()
{
if (!topdown_metric_class_)
{
topdown_metric_class_ = registry_.create<otf2::definition::metric_class>(
otf2::common::metric_occurence::async, otf2::common::recorder_kind::abstract);
topdown_metric_class_->add_member(metric_member(
"slots", "Number of UOPS slots", otf2::common::metric_mode::absolute_point,
otf2::common::type::int64, "slots"));
topdown_metric_class_->add_member(metric_member(
"retiring", "Number of UOPS retired", otf2::common::metric_mode::absolute_point,
otf2::common::type::int64, "slots"));
topdown_metric_class_->add_member(metric_member(
"bad_spec", "Number of UOPS lost to bad speculation",
otf2::common::metric_mode::absolute_point, otf2::common::type::int64, "slots"));
topdown_metric_class_->add_member(metric_member(
"fe_bound", "Number of front-end bound UOPS",
otf2::common::metric_mode::absolute_point, otf2::common::type::int64, "slots"));
topdown_metric_class_->add_member(metric_member(
"be_bound", "Number of back-end bound UOPS",
otf2::common::metric_mode::absolute_point, otf2::common::type::int64, "slots"));
}

return topdown_metric_class_;
}

otf2::definition::metric_member& get_event_metric_member(perf::EventDescription event)
{
return registry_.emplace<otf2::definition::metric_member>(
Expand Down Expand Up @@ -347,6 +374,7 @@ class Trace
otf2::definition::regions_group& syscall_regions_group_;

otf2::definition::detail::weak_ref<otf2::definition::metric_class> cpuid_metric_class_;
otf2::definition::detail::weak_ref<otf2::definition::metric_class> topdown_metric_class_;
std::map<std::set<Cpu>, otf2::definition::detail::weak_ref<otf2::definition::metric_class>>
perf_group_metric_classes_;
std::map<std::set<Cpu>, otf2::definition::detail::weak_ref<otf2::definition::metric_class>>
Expand Down
4 changes: 4 additions & 0 deletions src/config.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,7 @@ void parse_program_options(int argc, const char** argv)
auto& sensors_options = parser.group("sensors options");
auto& io_options = parser.group("I/O recording options");
auto& nec_options = parser.group("NEC SX-Aurora Tsubasa recording options");
auto& topdown_options = parser.group("Topdown metrics recording options");

lo2s::Config config;

Expand Down Expand Up @@ -344,6 +345,8 @@ void parse_program_options(int argc, const char** argv)
.metavar("MSEC")
.default_value("100");

topdown_options.toggle("topdown", "Enable recording of topdown metrics");

nitro::options::arguments arguments;
try
{
Expand All @@ -370,6 +373,7 @@ void parse_program_options(int argc, const char** argv)
config.use_sensors = arguments.given("sensors");
config.use_block_io = arguments.given("block-io");
config.use_nec = arguments.given("nec");
config.topdown = arguments.given("topdown");
config.command = arguments.positionals();

if (arguments.given("help"))
Expand Down
9 changes: 9 additions & 0 deletions src/monitor/scope_monitor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,11 @@ ScopeMonitor::ScopeMonitor(ExecutionScope scope, MainMonitor& parent, bool enabl
add_fd(userspace_counter_writer_->fd());
}

if(config().topdown)
{
topdown_writer_ = std::make_unique<perf::counter::topdown::Writer>(scope, parent.trace());
add_fd(topdown_writer_->fd());
}
// note: start() can now be called
}

Expand Down Expand Up @@ -116,6 +121,10 @@ void ScopeMonitor::monitor(int fd)
{
userspace_counter_writer_->read();
}
if (fd == topdown_writer_->fd())
{
topdown_writer_->read();
}
}
} // namespace monitor
} // namespace lo2s
Loading

0 comments on commit 6a3724c

Please sign in to comment.