0
0
Fork 0
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:
Jason Volk 2019-05-07 17:17:44 -07:00
parent 74074bfc78
commit 3196bbd26d
2 changed files with 41 additions and 183 deletions

View file

@ -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();

View file

@ -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;
}
}
}
//