You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
sledge/runtime/include/perf_window.h

104 lines
2.2 KiB

#pragma once
#include <stdint.h>
#include "lock.h"
#include "runtime.h"
#include "worker_thread.h"
/* Should be Power of 2! */
#define PERF_WINDOW_BUFFER_SIZE 16
#if ((PERF_WINDOW_BUFFER_SIZE == 0) || (PERF_WINDOW_BUFFER_SIZE & (PERF_WINDOW_BUFFER_SIZE - 1)) != 0)
#error "PERF_WINDOW_BUFFER_SIZE must be power of 2!"
#endif
struct perf_window {
uint64_t buffer[PERF_WINDOW_BUFFER_SIZE];
uint64_t count;
lock_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(LOCK_IS_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);
LOCK_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);
LOCK_LOCK(&self->lock);
self->buffer[self->count++ % PERF_WINDOW_BUFFER_SIZE] = value;
perf_window_update_mean(self);
LOCK_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;
}