mirror of
https://github.com/matrix-construct/construct
synced 2024-12-27 07:54:05 +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 syscall_timer;
|
||||
enum dpl :uint8_t;
|
||||
enum counter :uint8_t;
|
||||
enum cacheop :uint8_t;
|
||||
using group = std::vector<std::unique_ptr<event>>;
|
||||
IRCD_OVERLOAD(sample)
|
||||
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_thrd(); ///< Nanoseconds of CPU time for thread.
|
||||
|
||||
// Observe
|
||||
system &hotsample(system &) noexcept;
|
||||
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);
|
||||
|
||||
using read_closure = std::function<void (const type &, const uint64_t &val)>;
|
||||
void for_each(const const_buffer &read, const read_closure &);
|
||||
|
||||
// Control
|
||||
void stop(group &);
|
||||
void start(group &);
|
||||
|
@ -200,13 +200,17 @@ struct ircd::prof::system
|
|||
struct ircd::prof::type
|
||||
{
|
||||
enum dpl dpl {0};
|
||||
enum counter counter {0};
|
||||
enum cacheop cacheop {0};
|
||||
uint8_t type_id {0};
|
||||
uint8_t counter {0};
|
||||
uint8_t cacheop {0};
|
||||
uint8_t cacheres {0};
|
||||
|
||||
type(const event &);
|
||||
type(const enum dpl & = (enum dpl)0,
|
||||
const enum counter & = (enum counter)0,
|
||||
const enum cacheop & = (enum cacheop)0);
|
||||
const uint8_t &attr_type = 0,
|
||||
const uint8_t &counter = 0,
|
||||
const uint8_t &cacheop = 0,
|
||||
const uint8_t &cacheres = 0);
|
||||
};
|
||||
|
||||
enum ircd::prof::dpl
|
||||
|
@ -216,48 +220,6 @@ enum ircd::prof::dpl
|
|||
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
|
||||
{
|
||||
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 &);
|
||||
|
||||
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 *
|
||||
create(group &,
|
||||
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))
|
||||
};
|
||||
|
||||
// Start with the pseudo-results under TIME_PROF type, these should
|
||||
// always be the same for non-hw profiling, so the DPL is meaningless.
|
||||
closure(type{dpl::KERNEL, counter::TIME_PROF}, head->te);
|
||||
closure(type{dpl::USER, counter::TIME_PROF}, head->tr);
|
||||
// Start with the pseudo-results; these should always be the same for
|
||||
// non-hw profiling, so the DPL is meaningless.
|
||||
closure(type{dpl::KERNEL, uint8_t(-1)}, head->te);
|
||||
closure(type{dpl::USER, uint8_t(-1)}, head->tr);
|
||||
|
||||
// Iterate the result list
|
||||
for(size_t i(0); i < head->nr; ++i)
|
||||
|
@ -785,141 +782,40 @@ const
|
|||
//
|
||||
|
||||
ircd::prof::type::type(const enum dpl &dpl,
|
||||
const enum counter &counter,
|
||||
const enum cacheop &cacheop)
|
||||
const uint8_t &type_id,
|
||||
const uint8_t &counter,
|
||||
const uint8_t &cacheop,
|
||||
const uint8_t &cacheres)
|
||||
:dpl{dpl}
|
||||
,type_id{type_id}
|
||||
,counter{counter}
|
||||
,cacheop{cacheop}
|
||||
,cacheres{cacheres}
|
||||
{
|
||||
}
|
||||
|
||||
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