forked from haiwan/sledge
parent
628275f6f9
commit
c307f2a166
@ -0,0 +1,96 @@
|
||||
#pragma once
|
||||
|
||||
#include <spinlock/fas.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#define PERF_WINDOW_BUFFER_SIZE 10
|
||||
|
||||
struct perf_window {
|
||||
uint64_t buffer[PERF_WINDOW_BUFFER_SIZE];
|
||||
uint64_t count;
|
||||
ck_spinlock_fas_t lock;
|
||||
double mean;
|
||||
};
|
||||
|
||||
/**
|
||||
* Iterates through the values in the buffer and updates the mean
|
||||
* Not intended to be called directly!
|
||||
* @param self
|
||||
*/
|
||||
static inline void
|
||||
perf_window_update_mean(struct perf_window *self)
|
||||
{
|
||||
assert(self != NULL);
|
||||
assert(ck_spinlock_fas_locked(&self->lock));
|
||||
|
||||
uint64_t limit = self->count;
|
||||
if (limit > PERF_WINDOW_BUFFER_SIZE) { limit = PERF_WINDOW_BUFFER_SIZE; }
|
||||
|
||||
uint64_t sum = 0;
|
||||
for (uint64_t i = 0; i < limit; i++) sum += self->buffer[i];
|
||||
|
||||
self->mean = (double)(sum) / limit;
|
||||
};
|
||||
|
||||
/**
|
||||
* Iterates through the values in the buffer and updates the mean
|
||||
* Not intended to be called directly!
|
||||
* @param self
|
||||
*/
|
||||
static inline void
|
||||
perf_window_initialize(struct perf_window *self)
|
||||
{
|
||||
assert(self != NULL);
|
||||
|
||||
ck_spinlock_fas_init(&self->lock);
|
||||
self->count = 0;
|
||||
self->mean = 0;
|
||||
memset(&self->buffer, 0, sizeof(uint64_t) * PERF_WINDOW_BUFFER_SIZE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Iterates through the values in the buffer and updates the mean
|
||||
* Not intended to be called directly!
|
||||
* @param self
|
||||
* @param value
|
||||
*/
|
||||
static inline void
|
||||
perf_window_add(struct perf_window *self, uint64_t value)
|
||||
{
|
||||
assert(self != NULL);
|
||||
|
||||
|
||||
/* A successful invocation should run for a non-zero amount of time */
|
||||
assert(value > 0);
|
||||
|
||||
ck_spinlock_fas_lock(&self->lock);
|
||||
self->buffer[self->count++ % PERF_WINDOW_BUFFER_SIZE] = value;
|
||||
perf_window_update_mean(self);
|
||||
ck_spinlock_fas_unlock(&self->lock);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns mean perf value across all executions
|
||||
* @returns mean or -1 if buffer is empty
|
||||
*/
|
||||
static inline double
|
||||
perf_window_get_mean(struct perf_window *self)
|
||||
{
|
||||
assert(self != NULL);
|
||||
|
||||
if (self->count == 0) return -1;
|
||||
|
||||
return self->mean;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the total count of executions
|
||||
* @returns total count
|
||||
*/
|
||||
static inline uint64_t
|
||||
perf_window_get_count(struct perf_window *self)
|
||||
{
|
||||
assert(self != NULL);
|
||||
|
||||
return self->count;
|
||||
}
|
Loading…
Reference in new issue