Joined: 16 Jul 14
Looking at the BOINC wiki at http://boinc.berkeley.edu/wiki/computation_credit, I think the RAC description must be incomplete. It tells you only that RAC decreases by a factor of two every week - but it doesn't tell you how it's calculated to start with. I can _guess_ that it might be a daily moving average with an exponentially decaying weight - perhaps a weight that changes daily such that it halves over 7 days.
But that's a guess, and one which would imply that RAC could never be zero.
It'd be nice if the wiki said exactly how RAC was calculated.
Joined: 20 Nov 13
I realise this thread is a little old now but I was looking for the same information and thought I'd share what I found.
Apologies for the fairly long winded explanation you can skip to the bottom for some example graphs.
Credit is awarded by the code in this file sched/credit.cpp
Specifically were interested in the grant_credit function (starts on line 52). The users RAC is updated on line 79 with the following command
update_average( now, start_time, credit, CREDIT_HALF_LIFE, user.expavg_credit, user.expavg_time );
The CREDIT_HALF_LIFE is defined in sched/sched_util_basic.h on line 32.
#define SECONDS_IN_DAY (3600*24) #define CREDIT_HALF_LIFE (SECONDS_IN_DAY*7)
We can find the definition for this function in the lib/util.cpp file on line 238.
// Update an estimate of "units per day" of something (credit or CPU time). // The estimate is exponentially averaged with a given half-life // (i.e. if no new work is done, the average will decline by 50% in this time). // This function can be called either with new work, // or with zero work to decay an existing average. // // NOTE: if you change this, also change update_average in // html/inc/credit.inc // void update_average( double now, double work_start_time, // when new work was started // (or zero if no new work) double work, // amount of new work double half_life, double& avg, // average work per day (in and out) double& avg_time // when average was last computed )
Which, if you don't like the complex math in the source code, can be summarised as:
#First calculate the weight value weight = 2^[ -1 * days_since_last_update/7days ] #then determine which function to use if weight is approx 1 (this occurs as days_since_last_update approaches 0.0) new_avg = old_avg * weight + ln(2)*new_credit/7days #the math here is a little more complex else #this is the main function and will be used most of the time new_avg = (old_avg - new_credit_per_day) * weight + new_credit_per_day
To help visualise the weight function I've graphed it here http://www.wolframalpha.com/input/?i=plot+2%5e(-x%2f7)+from+x%3d0+to+10 where x is the number of days since last updated.
If new_credit_per_day == 0 the above simply becomes
new_avg = old_avg * weight
Which gives your standard exponential decay.
If new_credit_per_day less than old_avg you get exponential decay to the new_credit_per_day value.
Finally if new_credit_per_day is greater than old_avg you get exponential growth towards the new_credit_per_day value.
for example: (where x is number of days)
Graph starting at 1000 RAC with no new credit
Graph starting at 1000 RAC with 500 new credit each day
Graph starting at 1000 RAC with 1500 new credit each day
This process is performed every time a user is granted new credit for any reason otherwise it is updated at least daily by the update_stats background task.
Hope this helps someone else :)
Web developer for theSkyNet.org