mirror of
https://github.com/matrix-construct/construct
synced 2024-12-28 00:14:07 +01:00
ircd::prof: Simplify interface.
This commit is contained in:
parent
74074bfc78
commit
3196bbd26d
2 changed files with 41 additions and 183 deletions
|
@ -21,8 +21,6 @@ namespace ircd::prof
|
||||||
struct resource;
|
struct resource;
|
||||||
struct syscall_timer;
|
struct syscall_timer;
|
||||||
enum dpl :uint8_t;
|
enum dpl :uint8_t;
|
||||||
enum counter :uint8_t;
|
|
||||||
enum cacheop :uint8_t;
|
|
||||||
using group = std::vector<std::unique_ptr<event>>;
|
using group = std::vector<std::unique_ptr<event>>;
|
||||||
IRCD_OVERLOAD(sample)
|
IRCD_OVERLOAD(sample)
|
||||||
IRCD_EXCEPTION(ircd::error, error)
|
IRCD_EXCEPTION(ircd::error, error)
|
||||||
|
@ -34,7 +32,6 @@ namespace ircd::prof
|
||||||
uint64_t time_proc(); ///< Nanoseconds of CPU time for process.
|
uint64_t time_proc(); ///< Nanoseconds of CPU time for process.
|
||||||
uint64_t time_thrd(); ///< Nanoseconds of CPU time for thread.
|
uint64_t time_thrd(); ///< Nanoseconds of CPU time for thread.
|
||||||
|
|
||||||
// Observe
|
|
||||||
system &hotsample(system &) noexcept;
|
system &hotsample(system &) noexcept;
|
||||||
system &operator+=(system &a, const system &b);
|
system &operator+=(system &a, const system &b);
|
||||||
system &operator-=(system &a, const system &b);
|
system &operator-=(system &a, const system &b);
|
||||||
|
@ -46,6 +43,9 @@ namespace ircd::prof
|
||||||
resource operator+(const resource &a, const resource &b);
|
resource operator+(const resource &a, const resource &b);
|
||||||
resource operator-(const resource &a, const resource &b);
|
resource operator-(const resource &a, const resource &b);
|
||||||
|
|
||||||
|
using read_closure = std::function<void (const type &, const uint64_t &val)>;
|
||||||
|
void for_each(const const_buffer &read, const read_closure &);
|
||||||
|
|
||||||
// Control
|
// Control
|
||||||
void stop(group &);
|
void stop(group &);
|
||||||
void start(group &);
|
void start(group &);
|
||||||
|
@ -200,13 +200,17 @@ struct ircd::prof::system
|
||||||
struct ircd::prof::type
|
struct ircd::prof::type
|
||||||
{
|
{
|
||||||
enum dpl dpl {0};
|
enum dpl dpl {0};
|
||||||
enum counter counter {0};
|
uint8_t type_id {0};
|
||||||
enum cacheop cacheop {0};
|
uint8_t counter {0};
|
||||||
|
uint8_t cacheop {0};
|
||||||
|
uint8_t cacheres {0};
|
||||||
|
|
||||||
type(const event &);
|
type(const event &);
|
||||||
type(const enum dpl & = (enum dpl)0,
|
type(const enum dpl & = (enum dpl)0,
|
||||||
const enum counter & = (enum counter)0,
|
const uint8_t &attr_type = 0,
|
||||||
const enum cacheop & = (enum cacheop)0);
|
const uint8_t &counter = 0,
|
||||||
|
const uint8_t &cacheop = 0,
|
||||||
|
const uint8_t &cacheres = 0);
|
||||||
};
|
};
|
||||||
|
|
||||||
enum ircd::prof::dpl
|
enum ircd::prof::dpl
|
||||||
|
@ -216,48 +220,6 @@ enum ircd::prof::dpl
|
||||||
USER = 1,
|
USER = 1,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum ircd::prof::counter
|
|
||||||
:std::underlying_type<ircd::prof::counter>::type
|
|
||||||
{
|
|
||||||
TIME_PROF,
|
|
||||||
TIME_CPU,
|
|
||||||
TIME_TASK,
|
|
||||||
PF_MINOR,
|
|
||||||
PF_MAJOR,
|
|
||||||
SWITCH_TASK,
|
|
||||||
SWITCH_CPU,
|
|
||||||
|
|
||||||
CYCLES,
|
|
||||||
RETIRES,
|
|
||||||
BRANCHES,
|
|
||||||
BRANCHES_MISS,
|
|
||||||
CACHES,
|
|
||||||
CACHES_MISS,
|
|
||||||
STALLS_READ,
|
|
||||||
STALLS_RETIRE,
|
|
||||||
|
|
||||||
CACHE_L1D,
|
|
||||||
CACHE_L1I,
|
|
||||||
CACHE_LL,
|
|
||||||
CACHE_TLBD,
|
|
||||||
CACHE_TLBI,
|
|
||||||
CACHE_BPU,
|
|
||||||
CACHE_NODE,
|
|
||||||
|
|
||||||
_NUM
|
|
||||||
};
|
|
||||||
|
|
||||||
enum ircd::prof::cacheop
|
|
||||||
:std::underlying_type<ircd::prof::cacheop>::type
|
|
||||||
{
|
|
||||||
READ_ACCESS,
|
|
||||||
READ_MISS,
|
|
||||||
WRITE_ACCESS,
|
|
||||||
WRITE_MISS,
|
|
||||||
PREFETCH_ACCESS,
|
|
||||||
PREFETCH_MISS,
|
|
||||||
};
|
|
||||||
|
|
||||||
struct ircd::prof::init
|
struct ircd::prof::init
|
||||||
{
|
{
|
||||||
init();
|
init();
|
||||||
|
|
164
ircd/prof.cc
164
ircd/prof.cc
|
@ -21,9 +21,6 @@ namespace ircd::prof
|
||||||
{
|
{
|
||||||
std::ostream &debug(std::ostream &, const ::perf_event_mmap_page &);
|
std::ostream &debug(std::ostream &, const ::perf_event_mmap_page &);
|
||||||
|
|
||||||
using read_closure = std::function<void (const type &, const uint64_t &val)>;
|
|
||||||
void for_each(const const_buffer &read, const read_closure &);
|
|
||||||
|
|
||||||
template<class... args> event *
|
template<class... args> event *
|
||||||
create(group &,
|
create(group &,
|
||||||
const uint32_t &,
|
const uint32_t &,
|
||||||
|
@ -579,10 +576,10 @@ ircd::prof::for_each(const const_buffer &buf,
|
||||||
reinterpret_cast<const struct body *>(data(buf) + sizeof(struct head))
|
reinterpret_cast<const struct body *>(data(buf) + sizeof(struct head))
|
||||||
};
|
};
|
||||||
|
|
||||||
// Start with the pseudo-results under TIME_PROF type, these should
|
// Start with the pseudo-results; these should always be the same for
|
||||||
// always be the same for non-hw profiling, so the DPL is meaningless.
|
// non-hw profiling, so the DPL is meaningless.
|
||||||
closure(type{dpl::KERNEL, counter::TIME_PROF}, head->te);
|
closure(type{dpl::KERNEL, uint8_t(-1)}, head->te);
|
||||||
closure(type{dpl::USER, counter::TIME_PROF}, head->tr);
|
closure(type{dpl::USER, uint8_t(-1)}, head->tr);
|
||||||
|
|
||||||
// Iterate the result list
|
// Iterate the result list
|
||||||
for(size_t i(0); i < head->nr; ++i)
|
for(size_t i(0); i < head->nr; ++i)
|
||||||
|
@ -785,141 +782,40 @@ const
|
||||||
//
|
//
|
||||||
|
|
||||||
ircd::prof::type::type(const enum dpl &dpl,
|
ircd::prof::type::type(const enum dpl &dpl,
|
||||||
const enum counter &counter,
|
const uint8_t &type_id,
|
||||||
const enum cacheop &cacheop)
|
const uint8_t &counter,
|
||||||
|
const uint8_t &cacheop,
|
||||||
|
const uint8_t &cacheres)
|
||||||
:dpl{dpl}
|
:dpl{dpl}
|
||||||
|
,type_id{type_id}
|
||||||
,counter{counter}
|
,counter{counter}
|
||||||
,cacheop{cacheop}
|
,cacheop{cacheop}
|
||||||
|
,cacheres{cacheres}
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
ircd::prof::type::type(const event &event)
|
ircd::prof::type::type(const event &event)
|
||||||
:type{}
|
:dpl
|
||||||
|
{
|
||||||
|
event.attr.exclude_kernel? dpl::USER : dpl::KERNEL
|
||||||
|
}
|
||||||
|
,type_id
|
||||||
|
{
|
||||||
|
uint8_t(event.attr.type)
|
||||||
|
}
|
||||||
|
,counter
|
||||||
|
{
|
||||||
|
uint8_t(event.attr.config)
|
||||||
|
}
|
||||||
|
,cacheop
|
||||||
|
{
|
||||||
|
uint8_t(event.attr.config >> 8)
|
||||||
|
}
|
||||||
|
,cacheres
|
||||||
|
{
|
||||||
|
uint8_t(event.attr.config >> 16)
|
||||||
|
}
|
||||||
{
|
{
|
||||||
this->dpl = event.attr.exclude_kernel? dpl::USER : dpl::KERNEL;
|
|
||||||
if(event.attr.type == PERF_TYPE_SOFTWARE) switch(event.attr.config)
|
|
||||||
{
|
|
||||||
case PERF_COUNT_SW_CPU_CLOCK:
|
|
||||||
this->counter = counter::TIME_CPU;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case PERF_COUNT_SW_TASK_CLOCK:
|
|
||||||
this->counter = counter::TIME_TASK;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case PERF_COUNT_SW_PAGE_FAULTS_MIN:
|
|
||||||
this->counter = counter::PF_MINOR;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case PERF_COUNT_SW_PAGE_FAULTS_MAJ:
|
|
||||||
this->counter = counter::PF_MAJOR;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case PERF_COUNT_SW_CONTEXT_SWITCHES:
|
|
||||||
this->counter = counter::SWITCH_TASK;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case PERF_COUNT_SW_CPU_MIGRATIONS:
|
|
||||||
this->counter = counter::SWITCH_CPU;
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
else if(event.attr.type == PERF_TYPE_HARDWARE) switch(event.attr.config)
|
|
||||||
{
|
|
||||||
case PERF_COUNT_HW_CPU_CYCLES:
|
|
||||||
this->counter = counter::CYCLES;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case PERF_COUNT_HW_INSTRUCTIONS:
|
|
||||||
this->counter = counter::RETIRES;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case PERF_COUNT_HW_CACHE_REFERENCES:
|
|
||||||
this->counter = counter::CACHES;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case PERF_COUNT_HW_CACHE_MISSES:
|
|
||||||
this->counter = counter::CACHES_MISS;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case PERF_COUNT_HW_BRANCH_INSTRUCTIONS:
|
|
||||||
this->counter = counter::BRANCHES;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case PERF_COUNT_HW_BRANCH_MISSES:
|
|
||||||
this->counter = counter::BRANCHES_MISS;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case PERF_COUNT_HW_STALLED_CYCLES_FRONTEND:
|
|
||||||
this->counter = counter::STALLS_READ;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case PERF_COUNT_HW_STALLED_CYCLES_BACKEND:
|
|
||||||
this->counter = counter::STALLS_RETIRE;
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
else if(event.attr.type == PERF_TYPE_HW_CACHE)
|
|
||||||
{
|
|
||||||
const uint8_t counter(event.attr.config);
|
|
||||||
const uint8_t op(event.attr.config >> 8);
|
|
||||||
const uint8_t res(event.attr.config >> 16);
|
|
||||||
switch(counter)
|
|
||||||
{
|
|
||||||
case PERF_COUNT_HW_CACHE_L1D:
|
|
||||||
this->counter = counter::CACHE_L1D;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case PERF_COUNT_HW_CACHE_L1I:
|
|
||||||
this->counter = counter::CACHE_L1I;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case PERF_COUNT_HW_CACHE_LL:
|
|
||||||
this->counter = counter::CACHE_LL;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case PERF_COUNT_HW_CACHE_DTLB:
|
|
||||||
this->counter = counter::CACHE_TLBD;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case PERF_COUNT_HW_CACHE_ITLB:
|
|
||||||
this->counter = counter::CACHE_TLBI;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case PERF_COUNT_HW_CACHE_BPU:
|
|
||||||
this->counter = counter::CACHE_BPU;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case PERF_COUNT_HW_CACHE_NODE:
|
|
||||||
this->counter = counter::CACHE_NODE;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch(op)
|
|
||||||
{
|
|
||||||
case PERF_COUNT_HW_CACHE_OP_READ:
|
|
||||||
this->cacheop = res == PERF_COUNT_HW_CACHE_RESULT_ACCESS?
|
|
||||||
cacheop::READ_ACCESS:
|
|
||||||
cacheop::READ_MISS;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case PERF_COUNT_HW_CACHE_OP_WRITE:
|
|
||||||
this->cacheop = res == PERF_COUNT_HW_CACHE_RESULT_ACCESS?
|
|
||||||
cacheop::WRITE_ACCESS:
|
|
||||||
cacheop::WRITE_MISS;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case PERF_COUNT_HW_CACHE_OP_PREFETCH:
|
|
||||||
this->cacheop = res == PERF_COUNT_HW_CACHE_RESULT_ACCESS?
|
|
||||||
cacheop::PREFETCH_ACCESS:
|
|
||||||
cacheop::PREFETCH_MISS;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
|
|
Loading…
Reference in a new issue