- client: change how short term debt is updated.

Old: it's based entirely on CPU time.
        So a GPU project, whose app uses only a fraction
        of a CPU, accrues positive debt.
        This is OK if the project has only GPU apps,
        since STD is not (currently) used for GPU scheduling.
        But some projects have both CPU and GPU apps.
    New: STD is based on total processing.
        It has terms for each resource type.
        The notion of "runnable resource share" is specific to a type.
    Note: the notion of "resource share fraction" appears in
        a couple of other places:
        - it's passed to apps in app_init_data.xml
        - it's passed in scheduler requests.
        It should be broken down by resource type in these cases too.
        Note to self: do this later.

svn path=/trunk/boinc/; revision=19762
This commit is contained in:
David Anderson 2009-12-02 03:41:52 +00:00
parent 67ad130477
commit 59328aaccb
8 changed files with 97 additions and 20 deletions

View File

@ -9607,3 +9607,29 @@ David 1 Dec 2009
client/
work_fetch.cpp
David 1 Dec 2009
- client: change how short term debt is updated.
Old: it's based entirely on CPU time.
So a GPU project, whose app uses only a fraction
of a CPU, accrues positive debt.
This is OK if the project has only GPU apps,
since STD is not (currently) used for GPU scheduling.
But some projects have both CPU and GPU apps.
New: STD is based on total processing.
It has terms for each resource type.
The notion of "runnable resource share" is specific to a type.
Note: the notion of "resource share fraction" appears in
a couple of other places:
- it's passed to apps in app_init_data.xml
- it's passed in scheduler requests.
It should be broken down by resource type in these cases too.
Note to self: do this later.
client/
app_start.cpp
client_state.h
client_types.h
cpu_sched.cpp
cs_scheduler.cpp
work_fetch.cpp,h

View File

@ -207,7 +207,7 @@ int ACTIVE_TASK::write_app_init_file() {
aid.user_expavg_credit = wup->project->user_expavg_credit;
aid.host_total_credit = wup->project->host_total_credit;
aid.host_expavg_credit = wup->project->host_expavg_credit;
double rrs = gstate.runnable_resource_share();
double rrs = gstate.runnable_resource_share(RSC_TYPE_CPU);
if (rrs) {
aid.resource_share_fraction = wup->project->resource_share/rrs;
} else {

View File

@ -320,7 +320,7 @@ private:
double nearly_runnable_resource_share();
double fetchable_resource_share();
public:
double runnable_resource_share();
double runnable_resource_share(int);
/// Check if work fetch needed.
/// Called when:

View File

@ -332,8 +332,8 @@ public:
/// not suspended and not deferred and not no more work
bool can_request_work();
/// has a runnable result
bool runnable();
/// has a runnable result using the given resource type
bool runnable(int rsc_type);
/// has a result in downloading state
bool downloading();
/// runnable or contactable or downloading

View File

@ -519,7 +519,7 @@ void CLIENT_STATE::reset_debt_accounting() {
void CLIENT_STATE::adjust_debts() {
unsigned int i;
double total_short_term_debt = 0;
double rrs;
double rrs, rrs_cuda, rrs_ati;
int nprojects=0, nrprojects=0;
PROJECT *p;
double share_frac;
@ -566,20 +566,25 @@ void CLIENT_STATE::adjust_debts() {
// adjust short term debts
//
rrs = runnable_resource_share();
rrs = runnable_resource_share(RSC_TYPE_CPU);
if (coproc_cuda) {
rrs_cuda = runnable_resource_share(RSC_TYPE_CUDA);
}
if (coproc_ati) {
rrs_ati = runnable_resource_share(RSC_TYPE_ATI);
}
for (i=0; i<projects.size(); i++) {
double delta;
p = projects[i];
if (p->non_cpu_intensive) continue;
nprojects++;
if (p->runnable()) {
if (p->runnable(RSC_TYPE_ANY)) {
nrprojects++;
share_frac = p->resource_share/rrs;
delta = share_frac*cpu_work_fetch.secs_this_debt_interval
- p->cpu_pwf.secs_this_debt_interval;
p->short_term_debt += delta;
total_short_term_debt += p->short_term_debt;
if (log_flags.std_debug) {
msg_printf(p, MSG_INFO,
"[std_debug] std delta %.2f (%.2f * %.2f - %.2f)",
@ -589,6 +594,38 @@ void CLIENT_STATE::adjust_debts() {
p->cpu_pwf.secs_this_debt_interval
);
}
if (coproc_cuda) {
share_frac = p->resource_share/rrs_cuda;
delta += cuda_work_fetch.speed*
(share_frac*cuda_work_fetch.secs_this_debt_interval
- p->cuda_pwf.secs_this_debt_interval);
if (log_flags.std_debug) {
msg_printf(p, MSG_INFO,
"[std_debug] CUDA std delta %.2f (%.2f * %.2f - %.2f)",
delta,
share_frac,
cuda_work_fetch.secs_this_debt_interval,
p->cuda_pwf.secs_this_debt_interval
);
}
}
if (coproc_ati) {
share_frac = p->resource_share/rrs_ati;
delta += ati_work_fetch.speed*
(share_frac*ati_work_fetch.secs_this_debt_interval
- p->ati_pwf.secs_this_debt_interval);
if (log_flags.std_debug) {
msg_printf(p, MSG_INFO,
"[std_debug] ATI std delta %.2f (%.2f * %.2f - %.2f)",
delta,
share_frac,
ati_work_fetch.secs_this_debt_interval,
p->ati_pwf.secs_this_debt_interval
);
}
}
p->short_term_debt += delta;
total_short_term_debt += p->short_term_debt;
} else {
p->short_term_debt = 0;
p->anticipated_debt = 0;
@ -603,7 +640,7 @@ void CLIENT_STATE::adjust_debts() {
for (i=0; i<projects.size(); i++) {
p = projects[i];
if (p->non_cpu_intensive) continue;
if (p->runnable()) {
if (p->runnable(RSC_TYPE_ANY)) {
p->short_term_debt -= avg_short_term_debt;
if (p->short_term_debt > MAX_STD) {
p->short_term_debt = MAX_STD;
@ -719,7 +756,7 @@ void CLIENT_STATE::schedule_cpus() {
PROJECT* p;
double expected_payoff;
unsigned int i;
double rrs = runnable_resource_share();
double rrs = runnable_resource_share(RSC_TYPE_CPU);
PROC_RESOURCES proc_rsc;
ACTIVE_TASK* atp;
bool can_run;
@ -1586,12 +1623,12 @@ double CLIENT_STATE::total_resource_share() {
// same, but only runnable projects (can use CPU right now)
//
double CLIENT_STATE::runnable_resource_share() {
double CLIENT_STATE::runnable_resource_share(int rsc_type) {
double x = 0;
for (unsigned int i=0; i<projects.size(); i++) {
PROJECT* p = projects[i];
if (p->non_cpu_intensive) continue;
if (p->runnable()) {
if (p->runnable(rsc_type)) {
x += p->resource_share;
}
}

View File

@ -82,7 +82,7 @@ int CLIENT_STATE::make_scheduler_request(PROJECT* p) {
if (!f) return ERR_FOPEN;
double trs = total_resource_share();
double rrs = runnable_resource_share();
double rrs = runnable_resource_share(RSC_TYPE_ANY);
double prrs = potentially_runnable_resource_share();
double resource_share_fraction, rrs_fraction, prrs_fraction;
if (trs) {

View File

@ -983,11 +983,24 @@ void CLIENT_STATE::compute_nuploading_results() {
}
}
bool PROJECT::runnable() {
bool PROJECT::runnable(int rsc_type) {
if (suspended_via_gui) return false;
for (unsigned int i=0; i<gstate.results.size(); i++) {
RESULT* rp = gstate.results[i];
if (rp->project != this) continue;
switch (rsc_type) {
case RSC_TYPE_ANY:
break;
case RSC_TYPE_CPU:
if (rp->uses_coprocs()) continue;
break;
case RSC_TYPE_CUDA:
if (rp->avp->ncudas == 0) continue;
break;
case RSC_TYPE_ATI:
if (rp->avp->natis == 0) continue;
break;
}
if (rp->runnable()) return true;
}
return false;
@ -1023,14 +1036,14 @@ bool PROJECT::can_request_work() {
}
bool PROJECT::potentially_runnable() {
if (runnable()) return true;
if (runnable(RSC_TYPE_ANY)) return true;
if (can_request_work()) return true;
if (downloading()) return true;
return false;
}
bool PROJECT::nearly_runnable() {
if (runnable()) return true;
if (runnable(RSC_TYPE_ANY)) return true;
if (downloading()) return true;
return false;
}

View File

@ -23,9 +23,10 @@
#include <vector>
#define RSC_TYPE_CPU 0
#define RSC_TYPE_CUDA 1
#define RSC_TYPE_ATI 2
#define RSC_TYPE_ANY 0
#define RSC_TYPE_CPU 1
#define RSC_TYPE_CUDA 2
#define RSC_TYPE_ATI 3
class PROJECT;
struct RESULT;