util: Infrastructure for computing recent averages

This module computes the average of a set of values within a time
window, keeping also track of the minimum and maximum values.

In order to produce more accurate results it works internally by
creating two time windows of the same period, offsetted by half of
that period. Values are accounted on both windows and the data is
always returned from the oldest one.

[Add missing util/replay.o to test-timed-average dependencies to fix the
build.
--Stefan]

Signed-off-by: Alberto Garcia <berto@igalia.com>
Message-id: 201b09c21bbc9c329779d2b2365ee2b9c80dceeb.1446044837.git.berto@igalia.com
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
This commit is contained in:
Alberto Garcia 2015-10-28 17:33:01 +02:00 committed by Kevin Wolf
parent 5519593c07
commit bd797fc15b
5 changed files with 368 additions and 0 deletions

View file

@ -0,0 +1,90 @@
/*
* Timed average computation tests
*
* Copyright Nodalink, EURL. 2014
*
* Authors:
* Benoît Canet <benoit.canet@nodalink.com>
*
* This work is licensed under the terms of the GNU LGPL, version 2 or later.
* See the COPYING.LIB file in the top-level directory.
*/
#include <glib.h>
#include <unistd.h>
#include "qemu/timed-average.h"
/* This is the clock for QEMU_CLOCK_VIRTUAL */
static int64_t my_clock_value;
int64_t cpu_get_clock(void)
{
return my_clock_value;
}
static void account(TimedAverage *ta)
{
timed_average_account(ta, 1);
timed_average_account(ta, 5);
timed_average_account(ta, 2);
timed_average_account(ta, 4);
timed_average_account(ta, 3);
}
static void test_average(void)
{
TimedAverage ta;
uint64_t result;
int i;
/* we will compute some average on a period of 1 second */
timed_average_init(&ta, QEMU_CLOCK_VIRTUAL, NANOSECONDS_PER_SECOND);
result = timed_average_min(&ta);
g_assert(result == 0);
result = timed_average_avg(&ta);
g_assert(result == 0);
result = timed_average_max(&ta);
g_assert(result == 0);
for (i = 0; i < 100; i++) {
account(&ta);
result = timed_average_min(&ta);
g_assert(result == 1);
result = timed_average_avg(&ta);
g_assert(result == 3);
result = timed_average_max(&ta);
g_assert(result == 5);
my_clock_value += NANOSECONDS_PER_SECOND / 10;
}
my_clock_value += NANOSECONDS_PER_SECOND * 100;
result = timed_average_min(&ta);
g_assert(result == 0);
result = timed_average_avg(&ta);
g_assert(result == 0);
result = timed_average_max(&ta);
g_assert(result == 0);
for (i = 0; i < 100; i++) {
account(&ta);
result = timed_average_min(&ta);
g_assert(result == 1);
result = timed_average_avg(&ta);
g_assert(result == 3);
result = timed_average_max(&ta);
g_assert(result == 5);
my_clock_value += NANOSECONDS_PER_SECOND / 10;
}
}
int main(int argc, char **argv)
{
/* tests in the same order as the header function declarations */
g_test_init(&argc, &argv, NULL);
g_test_add_func("/timed-average/average", test_average);
return g_test_run();
}