1
1
mirror of https://github.com/rui314/mold.git synced 2024-09-11 13:06:59 +03:00
mold/perf.cc

107 lines
2.4 KiB
C++
Raw Normal View History

2020-11-03 11:26:42 +03:00
#include "mold.h"
2021-01-25 09:23:04 +03:00
#include <functional>
2020-12-10 16:32:47 +03:00
#include <iomanip>
#include <ios>
2020-12-11 10:51:20 +03:00
#include <sys/resource.h>
#include <sys/time.h>
2020-12-10 16:32:47 +03:00
namespace mold {
2021-01-25 09:23:04 +03:00
i64 Counter::get_value() {
return values.combine(std::plus());
}
2020-11-03 11:26:42 +03:00
void Counter::print() {
2021-01-25 09:23:04 +03:00
sort(instances, [](Counter *a, Counter *b) {
return a->get_value() > b->get_value();
});
2020-11-03 11:26:42 +03:00
2021-01-25 09:23:04 +03:00
for (Counter *c : instances)
std::cout << std::setw(20) << std::right << c->name
<< "=" << c->get_value() << "\n";
2020-11-03 11:26:42 +03:00
}
2020-12-11 10:51:20 +03:00
2021-01-24 07:26:03 +03:00
static i64 now_nsec() {
2020-12-11 10:51:20 +03:00
struct timespec t;
clock_gettime(CLOCK_MONOTONIC, &t);
2021-01-24 07:26:03 +03:00
return (i64)t.tv_sec * 1000000000 + t.tv_nsec;
2020-12-11 10:51:20 +03:00
}
2021-01-24 07:26:03 +03:00
static i64 to_nsec(struct timeval t) {
return (i64)t.tv_sec * 1000000000 + t.tv_usec * 1000;
2020-12-11 10:51:20 +03:00
}
2021-04-07 09:38:31 +03:00
TimerRecord::TimerRecord(std::string name, TimerRecord *parent)
: name(name), parent(parent) {
2020-12-11 10:51:20 +03:00
struct rusage usage;
getrusage(RUSAGE_SELF, &usage);
start = now_nsec();
2020-12-11 10:52:19 +03:00
user = to_nsec(usage.ru_utime);
sys = to_nsec(usage.ru_stime);
2021-04-07 09:38:31 +03:00
if (parent)
parent->children.push_back(this);
2020-12-11 10:51:20 +03:00
}
2021-01-09 12:15:09 +03:00
void TimerRecord::stop() {
2020-12-11 10:51:20 +03:00
if (stopped)
return;
stopped = true;
struct rusage usage;
getrusage(RUSAGE_SELF, &usage);
end = now_nsec();
2020-12-11 10:52:19 +03:00
user = to_nsec(usage.ru_utime) - user;
sys = to_nsec(usage.ru_stime) - sys;
2020-12-11 10:51:20 +03:00
}
2021-04-04 12:46:43 +03:00
static void print_rec(TimerRecord &rec, i64 indent) {
printf(" % 8.3f % 8.3f % 8.3f %s%s\n",
((double)rec.user / 1000000000),
((double)rec.sys / 1000000000),
(((double)rec.end - rec.start) / 1000000000),
std::string(indent * 2, ' ').c_str(),
rec.name.c_str());
2021-04-07 09:38:31 +03:00
sort(rec.children, [](TimerRecord *a, TimerRecord *b) {
return a->start < b->start;
});
2021-04-04 12:46:43 +03:00
for (TimerRecord *child : rec.children)
print_rec(*child, indent + 1);
}
void print_timer_records(
tbb::concurrent_vector<std::unique_ptr<TimerRecord>> &records) {
2021-01-24 06:01:43 +03:00
for (i64 i = records.size() - 1; i >= 0; i--)
2021-01-09 12:15:09 +03:00
records[i]->stop();
2020-12-11 10:51:20 +03:00
2021-04-04 12:46:43 +03:00
for (i64 i = 0; i < records.size(); i++) {
TimerRecord &inner = *records[i];
if (inner.parent)
continue;
for (i64 j = i - 1; j >= 0; j--) {
TimerRecord &outer = *records[j];
if (outer.start <= inner.start && inner.end <= outer.end) {
inner.parent = &outer;
outer.children.push_back(&inner);
break;
}
}
}
2020-12-11 10:51:20 +03:00
std::cout << " User System Real Name\n";
2021-04-07 09:38:31 +03:00
for (std::unique_ptr<TimerRecord> &rec : records)
2021-04-04 12:46:43 +03:00
if (!rec->parent)
print_rec(*rec, 0);
2020-12-11 10:52:19 +03:00
2020-12-11 10:51:20 +03:00
std::cout << std::flush;
}
2021-04-07 09:38:31 +03:00
} // namespace mold