Commit 887d59a6 authored by Kevin Modzelewski's avatar Kevin Modzelewski

Switch stats to cache the pointer directly

I would have expected this to help a bunch but it seems to actually hurt
parent 28df5108
...@@ -123,7 +123,7 @@ uint8_t* PystonMemoryManager::allocateSection(MemoryGroup& MemGroup, uintptr_t S ...@@ -123,7 +123,7 @@ uint8_t* PystonMemoryManager::allocateSection(MemoryGroup& MemGroup, uintptr_t S
} }
std::string stat_name = "mem_section_" + std::string(SectionName); std::string stat_name = "mem_section_" + std::string(SectionName);
Stats::log(Stats::getStatId(stat_name), MB.size()); Stats::log(Stats::getStatCounter(stat_name), MB.size());
// Save this address as the basis for our next request // Save this address as the basis for our next request
MemGroup.Near = MB; MemGroup.Near = MB;
......
...@@ -23,17 +23,6 @@ namespace pyston { ...@@ -23,17 +23,6 @@ namespace pyston {
#if !DISABLE_STATS #if !DISABLE_STATS
#if STAT_TIMERS #if STAT_TIMERS
extern "C" const char* getStatTimerNameById(int id) {
return Stats::getStatName(id).c_str();
}
extern "C" int getStatTimerId() {
return StatTimer::getStack()->getId();
}
extern "C" const char* getStatTimerName() {
return getStatTimerNameById(getStatTimerId());
}
__thread StatTimer* StatTimer::stack; __thread StatTimer* StatTimer::stack;
...@@ -50,42 +39,46 @@ StatTimer* StatTimer::swapStack(StatTimer* s, uint64_t at_time) { ...@@ -50,42 +39,46 @@ StatTimer* StatTimer::swapStack(StatTimer* s, uint64_t at_time) {
} }
#endif #endif
std::vector<uint64_t>* Stats::counts; std::unordered_map<uint64_t*, std::string>* Stats::names;
std::unordered_map<int, std::string>* Stats::names;
bool Stats::enabled; bool Stats::enabled;
timespec Stats::start_ts; timespec Stats::start_ts;
uint64_t Stats::start_tick; uint64_t Stats::start_tick;
StatCounter::StatCounter(const std::string& name) : id(Stats::getStatId(name)) { StatCounter::StatCounter(const std::string& name) : counter(Stats::getStatCounter(name)) {
} }
StatPerThreadCounter::StatPerThreadCounter(const std::string& name) { StatPerThreadCounter::StatPerThreadCounter(const std::string& name) {
char buf[80]; char buf[80];
snprintf(buf, 80, "%s_t%ld", name.c_str(), pthread_self()); snprintf(buf, 80, "%s_t%ld", name.c_str(), pthread_self());
id = Stats::getStatId(buf); counter = Stats::getStatCounter(buf);
} }
int Stats::getStatId(const std::string& name) { static std::vector<uint64_t*>* counts;
uint64_t* Stats::getStatCounter(const std::string& name) {
// hacky but easy way of getting around static constructor ordering issues for now: // hacky but easy way of getting around static constructor ordering issues for now:
static std::unordered_map<int, std::string> names; static std::unordered_map<uint64_t*, std::string> names;
Stats::names = &names; Stats::names = &names;
static std::vector<uint64_t> counts; static std::unordered_map<std::string, uint64_t*> made;
Stats::counts = &counts; // TODO: can do better than doing a malloc per counter:
static std::unordered_map<std::string, int> made; static std::vector<uint64_t*> counts;
pyston::counts = &counts;
if (made.count(name)) if (made.count(name))
return made[name]; return made[name];
int rtn = names.size(); uint64_t* rtn = new uint64_t(0);
names[rtn] = name; names[rtn] = name;
made[name] = rtn; made[name] = rtn;
counts.push_back(0); counts.push_back(rtn);
return rtn; return rtn;
} }
std::string Stats::getStatName(int id) { void Stats::clear() {
return (*names)[id]; assert(counts);
for (auto p : *counts) {
*p = 0;
}
} }
void Stats::startEstimatingCPUFreq() { void Stats::startEstimatingCPUFreq() {
...@@ -119,7 +112,7 @@ void Stats::dump(bool includeZeros) { ...@@ -119,7 +112,7 @@ void Stats::dump(bool includeZeros) {
fprintf(stderr, "Counters:\n"); fprintf(stderr, "Counters:\n");
std::vector<std::pair<std::string, int>> pairs; std::vector<std::pair<std::string, uint64_t*>> pairs;
for (const auto& p : *names) { for (const auto& p : *names) {
pairs.push_back(make_pair(p.second, p.first)); pairs.push_back(make_pair(p.second, p.first));
} }
...@@ -129,19 +122,19 @@ void Stats::dump(bool includeZeros) { ...@@ -129,19 +122,19 @@ void Stats::dump(bool includeZeros) {
uint64_t ticks_in_main = 0; uint64_t ticks_in_main = 0;
uint64_t accumulated_stat_timer_ticks = 0; uint64_t accumulated_stat_timer_ticks = 0;
for (int i = 0; i < pairs.size(); i++) { for (int i = 0; i < pairs.size(); i++) {
if (includeZeros || (*counts)[pairs[i].second] > 0) { uint64_t count = *pairs[i].second;
if (includeZeros || count > 0) {
if (startswith(pairs[i].first, "us_") || startswith(pairs[i].first, "_init_us_")) { if (startswith(pairs[i].first, "us_") || startswith(pairs[i].first, "_init_us_")) {
fprintf(stderr, "%s: %lu\n", pairs[i].first.c_str(), fprintf(stderr, "%s: %lu\n", pairs[i].first.c_str(), (uint64_t)(count / cycles_per_us));
(uint64_t)((*counts)[pairs[i].second] / cycles_per_us));
} else } else
fprintf(stderr, "%s: %lu\n", pairs[i].first.c_str(), (*counts)[pairs[i].second]); fprintf(stderr, "%s: %lu\n", pairs[i].first.c_str(), count);
if (startswith(pairs[i].first, "us_timer_")) if (startswith(pairs[i].first, "us_timer_"))
accumulated_stat_timer_ticks += (*counts)[pairs[i].second]; accumulated_stat_timer_ticks += count;
if (pairs[i].first == "ticks_in_main") if (pairs[i].first == "ticks_in_main")
ticks_in_main = (*counts)[pairs[i].second]; ticks_in_main = count;
} }
} }
...@@ -165,10 +158,10 @@ void Stats::dump(bool includeZeros) { ...@@ -165,10 +158,10 @@ void Stats::dump(bool includeZeros) {
} }
void Stats::endOfInit() { void Stats::endOfInit() {
int orig_names = names->size(); std::unordered_map<uint64_t*, std::string> names_copy(names->begin(), names->end());
for (int orig_id = 0; orig_id < orig_names; orig_id++) { for (const auto& p : names_copy) {
int init_id = getStatId("_init_" + (*names)[orig_id]); uint64_t* init_id = getStatCounter("_init_" + p.second);
log(init_id, (*counts)[orig_id]); log(init_id, *p.first);
} }
}; };
......
...@@ -33,11 +33,11 @@ namespace pyston { ...@@ -33,11 +33,11 @@ namespace pyston {
#if STAT_TIMERS #if STAT_TIMERS
#define STAT_TIMER(id, name) \ #define STAT_TIMER(id, name) \
static int _stid##id = Stats::getStatId(name); \ static uint64_t* _stcounter##id = Stats::getStatCounter(name); \
StatTimer _st##id(_stid##id) StatTimer _st##id(_stcounter##id)
#define STAT_TIMER2(id, name, at_time) \ #define STAT_TIMER2(id, name, at_time) \
static int _stid##id = Stats::getStatId(name); \ static uint64_t* _stcounter##id = Stats::getStatCounter(name); \
StatTimer _st##id(_stid##id, at_time) StatTimer _st##id(_stcounter##id, at_time)
#else #else
#define STAT_TIMER(id, name) StatTimer _st##id(0); #define STAT_TIMER(id, name) StatTimer _st##id(0);
#define STAT_TIMER2(id, name, at_time) StatTimer _st##id(0); #define STAT_TIMER2(id, name, at_time) StatTimer _st##id(0);
...@@ -48,8 +48,7 @@ namespace pyston { ...@@ -48,8 +48,7 @@ namespace pyston {
#if !DISABLE_STATS #if !DISABLE_STATS
struct Stats { struct Stats {
private: private:
static std::vector<uint64_t>* counts; static std::unordered_map<uint64_t*, std::string>* names;
static std::unordered_map<int, std::string>* names;
static bool enabled; static bool enabled;
static timespec start_ts; static timespec start_ts;
...@@ -59,35 +58,34 @@ public: ...@@ -59,35 +58,34 @@ public:
static void startEstimatingCPUFreq(); static void startEstimatingCPUFreq();
static double estimateCPUFreq(); static double estimateCPUFreq();
static int getStatId(const std::string& name); static uint64_t* getStatCounter(const std::string& name);
static std::string getStatName(int id);
static void setEnabled(bool enabled) { Stats::enabled = enabled; } static void setEnabled(bool enabled) { Stats::enabled = enabled; }
static void log(int id, uint64_t count = 1) { (*counts)[id] += count; } static void log(uint64_t* counter, uint64_t count = 1) { *counter += count; }
static void clear() { std::fill(counts->begin(), counts->end(), 0); } static void clear();
static void dump(bool includeZeros = true); static void dump(bool includeZeros = true);
static void endOfInit(); static void endOfInit();
}; };
struct StatCounter { struct StatCounter {
private: private:
int id; uint64_t* counter;
public: public:
StatCounter(const std::string& name); StatCounter(const std::string& name);
void log(uint64_t count = 1) { Stats::log(id, count); } void log(uint64_t count = 1) { *counter += count; }
}; };
struct StatPerThreadCounter { struct StatPerThreadCounter {
private: private:
int id = 0; uint64_t* counter = 0;
public: public:
StatPerThreadCounter(const std::string& name); StatPerThreadCounter(const std::string& name);
void log(uint64_t count = 1) { Stats::log(id, count); } void log(uint64_t count = 1) { *counter += count; }
}; };
#else #else
...@@ -123,13 +121,13 @@ private: ...@@ -123,13 +121,13 @@ private:
StatTimer* _prev; StatTimer* _prev;
int _statid; uint64_t* _statcounter;
public: public:
StatTimer(int statid, bool push = true) { StatTimer(uint64_t* counter, bool push = true) {
uint64_t at_time = getCPUTicks(); uint64_t at_time = getCPUTicks();
_start_time = 0; _start_time = 0;
_statid = statid; _statcounter = counter;
if (!push) { if (!push) {
_prev = NULL; _prev = NULL;
...@@ -144,9 +142,9 @@ public: ...@@ -144,9 +142,9 @@ public:
resume(at_time); resume(at_time);
} }
StatTimer(int statid, uint64_t at_time) { StatTimer(uint64_t* counter, uint64_t at_time) {
_start_time = 0; _start_time = 0;
_statid = statid; _statcounter = counter;
_prev = stack; _prev = stack;
stack = this; stack = this;
if (_prev) { if (_prev) {
...@@ -178,7 +176,7 @@ public: ...@@ -178,7 +176,7 @@ public:
assert(at_time > _start_time); assert(at_time > _start_time);
uint64_t _duration = at_time - _start_time; uint64_t _duration = at_time - _start_time;
Stats::log(_statid, _duration); Stats::log(_statcounter, _duration);
_start_time = 0; _start_time = 0;
_last_pause_time = at_time; _last_pause_time = at_time;
...@@ -191,7 +189,6 @@ public: ...@@ -191,7 +189,6 @@ public:
} }
bool isPaused() const { return _start_time == 0; } bool isPaused() const { return _start_time == 0; }
int getId() const { return _statid; }
static StatTimer* getStack() { return stack; } static StatTimer* getStack() { return stack; }
......
...@@ -32,7 +32,7 @@ namespace pyston { ...@@ -32,7 +32,7 @@ namespace pyston {
namespace gc { namespace gc {
#if STAT_TIMERS #if STAT_TIMERS
int gc_alloc_stattimer_id = Stats::getStatId("us_timer_gc_alloc"); uint64_t* gc_alloc_stattimer_counter = Stats::getStatCounter("us_timer_gc_alloc");
#endif #endif
extern "C" void* gc_compat_malloc(size_t sz) noexcept { extern "C" void* gc_compat_malloc(size_t sz) noexcept {
......
...@@ -41,11 +41,11 @@ static StatCounter gc_alloc_bytes_typed[] = { ...@@ -41,11 +41,11 @@ static StatCounter gc_alloc_bytes_typed[] = {
#endif #endif
#if STAT_TIMERS #if STAT_TIMERS
extern int gc_alloc_stattimer_id; extern uint64_t* gc_alloc_stattimer_counter;
#endif #endif
extern "C" inline void* gc_alloc(size_t bytes, GCKind kind_id) { extern "C" inline void* gc_alloc(size_t bytes, GCKind kind_id) {
#if STAT_TIMERS #if STAT_TIMERS
StatTimer gc_alloc_stattimer(gc_alloc_stattimer_id); StatTimer gc_alloc_stattimer(gc_alloc_stattimer_counter);
#endif #endif
size_t alloc_bytes = bytes + sizeof(GCAllocation); size_t alloc_bytes = bytes + sizeof(GCAllocation);
......
...@@ -124,13 +124,13 @@ static Box* (*callattrInternal3)(Box*, llvm::StringRef, LookupScope, CallRewrite ...@@ -124,13 +124,13 @@ static Box* (*callattrInternal3)(Box*, llvm::StringRef, LookupScope, CallRewrite
= (Box * (*)(Box*, llvm::StringRef, LookupScope, CallRewriteArgs*, ArgPassSpec, Box*, Box*, Box*))callattrInternal; = (Box * (*)(Box*, llvm::StringRef, LookupScope, CallRewriteArgs*, ArgPassSpec, Box*, Box*, Box*))callattrInternal;
#if STAT_TIMERS #if STAT_TIMERS
static int pyhasher_timer_id = Stats::getStatId("us_timer_PyHasher"); static uint64_t* pyhasher_timer_counter = Stats::getStatCounter("us_timer_PyHasher");
static int pyeq_timer_id = Stats::getStatId("us_timer_PyEq"); static uint64_t* pyeq_timer_counter = Stats::getStatCounter("us_timer_PyEq");
static int pylt_timer_id = Stats::getStatId("us_timer_PyLt"); static uint64_t* pylt_timer_counter = Stats::getStatCounter("us_timer_PyLt");
#endif #endif
size_t PyHasher::operator()(Box* b) const { size_t PyHasher::operator()(Box* b) const {
#if STAT_TIMERS #if STAT_TIMERS
StatTimer _st(pyhasher_timer_id); StatTimer _st(pyhasher_timer_counter);
#endif #endif
if (b->cls == str_cls) { if (b->cls == str_cls) {
StringHash<char> H; StringHash<char> H;
...@@ -143,7 +143,7 @@ size_t PyHasher::operator()(Box* b) const { ...@@ -143,7 +143,7 @@ size_t PyHasher::operator()(Box* b) const {
bool PyEq::operator()(Box* lhs, Box* rhs) const { bool PyEq::operator()(Box* lhs, Box* rhs) const {
#if STAT_TIMERS #if STAT_TIMERS
StatTimer _st(pyeq_timer_id); StatTimer _st(pyeq_timer_counter);
#endif #endif
int r = PyObject_RichCompareBool(lhs, rhs, Py_EQ); int r = PyObject_RichCompareBool(lhs, rhs, Py_EQ);
...@@ -154,7 +154,7 @@ bool PyEq::operator()(Box* lhs, Box* rhs) const { ...@@ -154,7 +154,7 @@ bool PyEq::operator()(Box* lhs, Box* rhs) const {
bool PyLt::operator()(Box* lhs, Box* rhs) const { bool PyLt::operator()(Box* lhs, Box* rhs) const {
#if STAT_TIMERS #if STAT_TIMERS
StatTimer _st(pylt_timer_id); StatTimer _st(pylt_timer_counter);
#endif #endif
int r = PyObject_RichCompareBool(lhs, rhs, Py_LT); int r = PyObject_RichCompareBool(lhs, rhs, Py_LT);
...@@ -1766,8 +1766,8 @@ extern "C" Box* getattr(Box* obj, const char* attr) { ...@@ -1766,8 +1766,8 @@ extern "C" Box* getattr(Box* obj, const char* attr) {
if (VERBOSITY() >= 2) { if (VERBOSITY() >= 2) {
#if !DISABLE_STATS #if !DISABLE_STATS
std::string per_name_stat_name = "getattr__" + std::string(attr); std::string per_name_stat_name = "getattr__" + std::string(attr);
int id = Stats::getStatId(per_name_stat_name); uint64_t* counter = Stats::getStatCounter(per_name_stat_name);
Stats::log(id); Stats::log(counter);
#endif #endif
} }
...@@ -4834,8 +4834,8 @@ extern "C" Box* getGlobal(Box* globals, const std::string* name) { ...@@ -4834,8 +4834,8 @@ extern "C" Box* getGlobal(Box* globals, const std::string* name) {
if (VERBOSITY() >= 2) { if (VERBOSITY() >= 2) {
#if !DISABLE_STATS #if !DISABLE_STATS
std::string per_name_stat_name = "getglobal__" + *name; std::string per_name_stat_name = "getglobal__" + *name;
int id = Stats::getStatId(per_name_stat_name); uint64_t* counter = Stats::getStatCounter(per_name_stat_name);
Stats::log(id); Stats::log(counter);
#endif #endif
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment