- test code for new credit system

svn path=/trunk/boinc/; revision=19462
This commit is contained in:
David Anderson 2009-11-04 21:23:56 +00:00
parent 9f69955a43
commit 8caa2cf3d5
6 changed files with 250 additions and 0 deletions

View File

@ -8889,3 +8889,14 @@ Rom 4 Nov 2009
client
cs_platforms.cpp
David 4 Nov 2009
- test code for new credit system
db/
boinc_db.h
lib/
average.h
sched/
Makefile.am
credit_test.cpp

View File

@ -29,6 +29,7 @@
#include <vector>
#include "db_base.h"
#include "average.h"
extern DB_CONN boinc_db;
@ -75,6 +76,7 @@ struct APP {
// should come from this app
bool beta;
int target_nresults;
AVERAGE vnpfc;
int write(FILE*);
void clear();
@ -115,6 +117,8 @@ struct APP_VERSION {
// the following used by scheduler, not in DB
//
BEST_APP_VERSION* bavp;
AVERAGE pfc;
double pfc_scale_factor;
int write(FILE*);
void clear();
@ -506,6 +510,7 @@ struct RESULT {
int parse_from_client(FILE*);
char platform_name[256];
BEST_APP_VERSION* bavp;
void clear();
int write_to_client(FILE*);
};

View File

@ -187,6 +187,14 @@ $astro_phys_chem = array(
$mixed = array(
"Multiple applications",
array(
array(
"EDGeS@Home",
"http://home.edges-grid.eu/home/",
"MTA-SZTAKI Laboratory of Parallel and Distributed Systems (Budapest)",
"Scientific research in multiple areas",
"The EDGeS@Home Beta project integrates volunteer computing into the service grid network of Europe by allowing service grids to send workunits to be processed by the volunteers of this project. The scientific projects covered by the project include math, physics, biology, etc.",
"logo_edges.png"
),
array(
"Ibercivis",
"http://registro.ibercivis.es/",

58
lib/average.h Normal file
View File

@ -0,0 +1,58 @@
// structure for tracking the recent mean and variance
// of a distribution that may change over time
//
// We maintain the mean/var in two ways:
// 1) over the entire history of samples, using the algorithm from
// http://en.wikipedia.org/wiki/Algorithms_for_calculating_variance
// 2) as an exponentially-smoothed recent average
//
// When the number of samples is small we use 1).
// Then we switch to 2).
#define MIN_SAMPLES 50
// after this many samples, use exponential average
#define SAMPLE_WEIGHT 0.005
// new samples get this weight in exp avg
#define SAMPLE_LIMIT 10
// cap samples at recent_mean*10
struct AVERAGE {
int n;
double mean;
double sum_var;
// sample variance is this divided by (n-1)
double recent_mean;
double recent_var;
void update(double sample) {
if (sample < 0) return;
if (n > MIN_SAMPLES) {
if (sample > recent_mean*SAMPLE_LIMIT) {
sample = recent_mean*SAMPLE_LIMIT;
}
}
n++;
double delta = sample - mean;
mean += delta/n;
sum_var += delta*(sample-mean);
if (n < MIN_SAMPLES) {
recent_mean = mean;
recent_var = sum_var/n;
} else {
// update recent averages
delta = sample - recent_mean;
recent_mean += SAMPLE_WEIGHT*delta;
double d2 = delta*delta - recent_var;
recent_var += SAMPLE_WEIGHT*d2;
}
}
void clear() {
n = 0;
mean = 0;
sum_var = 0;
recent_mean = 0;
recent_var = 0;
}
};

View File

@ -98,6 +98,7 @@ bin_PROGRAMS = \
sched_PROGRAMS = \
census \
credit_test \
db_dump \
db_purge \
feeder \
@ -163,6 +164,10 @@ census_SOURCES = \
hr_info.cpp
census_LDADD = $(SERVERLIBS)
credit_test_SOURCES = \
credit_test.cpp
credit_test_LDADD = $(SERVERLIBS)
feeder_SOURCES = \
feeder.cpp \
hr.cpp \

163
sched/credit_test.cpp Normal file
View File

@ -0,0 +1,163 @@
#include <stdio.h>
#include "sched_config.h"
#include "boinc_db.h"
struct HOST_APP {
int host_id;
int app_id;
AVERAGE vnpfc;
};
struct HOST_APP_VERSION {
int host_id;
int app_version_id;
AVERAGE et;
};
vector<APP_VERSION> app_versions;
vector<APP> apps;
vector<HOST_APP> host_apps;
vector<HOST_APP_VERSION> host_app_versions;
// update app version scale factors
//
void update_av_scales() {
unsigned int i, j;
for (i=0; i<apps.size(); i++) {
APP& app = apps[i];
int n=0;
double min_pfc;
for (j=0; j<app_versions.size(); j++) {
APP_VERSION& av = app_versions[j];
if (av.appid != app.id) continue;
if (av.pfc.n < 10) continue;
if (n) {
if (av.pfc.recent_mean < min_pfc) {
min_pfc = av.pfc.recent_mean;
}
} else {
min_pfc = av.pfc.recent_mean;
}
n++;
}
if (n < 2) continue;
// if at least 2 versions have at least 10 samples,
// update their scale factors
//
for (j=0; j<app_versions.size(); j++) {
APP_VERSION& av = app_versions[j];
if (av.appid != app.id) continue;
if (av.pfc.n < 10) continue;
av.pfc_scale_factor = min_pfc/av.pfc.recent_mean;
}
}
}
void read_db() {
DB_APP app;
DB_APP_VERSION av;
while (!app.enumerate("where deprecated=0")) {
app.vnpfc.clear();
apps.push_back(app);
}
while (!av.enumerate("where deprecated=0")) {
av.pfc.clear();
av.pfc_scale_factor = 1;
app_versions.push_back(av);
}
}
APP_VERSION& lookup_av(int id) {
unsigned int i;
for (i=0; i<app_versions.size(); i++) {
APP_VERSION& av = app_versions[i];
if (av.id == id) return av;
}
printf("missing app version %d\n", id);
}
APP& lookup_app(int id) {
unsigned int i;
for (i=0; i<apps.size(); i++) {
APP& app = apps[i];
if (app.id == id) return app;
}
printf("missing app%d\n", id);
}
HOST_APP& lookup_host_app(int hostid, int appid) {
unsigned int i;
for (i=0; i<host_apps.size(); i++) {
HOST_APP& ha = host_apps[i];
if (ha.host_id != hostid) continue;
if (ha.app_id != appid) continue;
return ha;
}
HOST_APP h;
h.host_id = hostid;
h.app_id = appid;
h.vnpfc.clear();
host_apps.push_back(h);
return host_apps.back();
}
int main() {
DB_RESULT r;
char clause[256];
int retval;
retval = config.parse_file();
if (retval) {printf("no config: %d\n", retval); exit(1);}
retval = boinc_db.open(
config.db_name, config.db_host, config.db_user, config.db_passwd
);
if (retval) {printf("no db\n"); exit(1);}
read_db();
sprintf(clause, "where server_state=%d and outcome=%d limit 1000",
RESULT_SERVER_STATE_OVER, RESULT_OUTCOME_SUCCESS
);
int n=0;
while (!r.enumerate(clause)) {
if (!r.elapsed_time) {printf("no elapsed_time\n"); continue;}
if (!r.flops_estimate) {printf("no flops_estimate\n"); continue;}
if (!r.app_version_id) {printf("no app_version_id\n"); continue;}
double pfc = r.elapsed_time * r.flops_estimate;
printf("handling %s: %f\n", r.name, pfc);
// cross-version normalization
APP_VERSION& av = lookup_av(r.app_version_id);
APP& app = lookup_app(av.appid);
double vnpfc = pfc * av.pfc_scale_factor;
// host normalization
HOST_APP& host_app = lookup_host_app(r.hostid, app.id);
double scale = app.vnpfc.recent_mean/host_app.vnpfc.recent_mean;
double claimed_flops = vnpfc * scale;
double claimed_credit = claimed_flops * 100/86400e9;
printf("cc %f claimed %f granted %f\n", claimed_credit,
r.claimed_credit, r.granted_credit
);
// update averages
av.pfc.update(pfc);
app.vnpfc.update(vnpfc);
host_app.vnpfc.update(vnpfc);
n++;
if (n%20 ==0) {
update_av_scales();
}
}
}