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