mirror of https://github.com/BOINC/boinc.git
*** empty log message ***
svn path=/trunk/boinc/; revision=3704
This commit is contained in:
parent
79faad1fb0
commit
02ed8c7415
|
@ -14172,3 +14172,11 @@ Karl 2004-06-27
|
|||
sched/
|
||||
main.C
|
||||
|
||||
David 27 June 2004
|
||||
- add a -mod N I option to the transitioner;
|
||||
causes the transitioner to handle only WUs for which ID % N == I.
|
||||
Can use this to parallelize the transitioner,
|
||||
either on a single multi-CPU machine or across multiple machines
|
||||
|
||||
sched/
|
||||
transitioner.C
|
||||
|
|
|
@ -42,7 +42,7 @@ Here's how it works:
|
|||
|
||||
<ul>
|
||||
<li>
|
||||
Download the source code for the BOINC core client
|
||||
<a href=community.php>Download</a> the source code for the BOINC core client
|
||||
and the project's applications, and compile them on your computer
|
||||
(instructions for compiling the core client are
|
||||
<a href=build_client.php>here</a>).
|
||||
|
|
|
@ -24,7 +24,7 @@ before getting into the source code.
|
|||
<li> <a href=client_fsm.php>FSM structure</a>
|
||||
<li> <a href=client_data.php>Data structures</a>
|
||||
<li> <a href=client_logic.php>Main loop logic</a>
|
||||
<li> <a href=client_sched.php>Result scheduling</a>
|
||||
<li> <a href=client_sched.php>Client scheduling policies</a>
|
||||
<li> <a href=client_debug.php>Debugging</a>
|
||||
<li> <a href=host_measure.php>Host measurements</a>
|
||||
<li> <a href=host_id.php>Host identification</a>
|
||||
|
|
|
@ -1,67 +1,58 @@
|
|||
<?php
|
||||
require_once("docutil.php");
|
||||
page_head("Result scheduling");
|
||||
page_head("Client scheduling policies");
|
||||
echo "
|
||||
|
||||
This document describes BOINC's policies for the following:
|
||||
This document describes two interrelated scheduling policies
|
||||
in the BOINC client:
|
||||
|
||||
<ul>
|
||||
<li> CPU scheduling policy: what result to run when.
|
||||
<li> Work fetch policy: when to contact scheduling servers,
|
||||
and which one(s) to contact.
|
||||
<li> <b>CPU scheduling policy</b>: what result to run when.
|
||||
<li> <b>Work fetch policy</b>: when to contact scheduling servers,
|
||||
which projects to contact, and how much work to task for.
|
||||
</ul>
|
||||
|
||||
<h2>CPU scheduling</h2>
|
||||
|
||||
<p>CPU scheduling aims to achieve the following goals
|
||||
(decreasing priority):</p>
|
||||
<p>The CPU scheduling policy aims to achieve the following goals
|
||||
(in decreasing priority):</p>
|
||||
|
||||
<ol>
|
||||
|
||||
<li>
|
||||
<b>Maximize CPU utilization</b>
|
||||
<b>Maximize CPU utilization</b>.
|
||||
|
||||
<li>
|
||||
<b>Respect the resource share allocation for each project.</b>
|
||||
A project's resource share represents how much computing resources
|
||||
(CPU time, network bandwith, storage space) a user wants to allocate
|
||||
to the project relative to the resources allocated to all of the other
|
||||
projects in which he is participating. The client should respect this
|
||||
allocation to be faithful to the user. In the case of CPU time, the
|
||||
result computation scheduling should achieve the expected time shares
|
||||
over a reasonable time period.
|
||||
<b>Enforce resource shares.</b>
|
||||
The ratio of CPU time allocated to projects that have work,
|
||||
in a typical period of a day or two,
|
||||
should be approximately the same as the ratio of
|
||||
the user-specified resource shares.
|
||||
If a process has no work for some period,
|
||||
it does no accumulate a 'debt' of work.
|
||||
|
||||
<li>
|
||||
<b>Satisfy result deadlines if possible.</b>
|
||||
|
||||
<li>
|
||||
<b>Given a 'minimum variety' parameter MV (seconds),
|
||||
reschedule CPUs at least once every MV seconds.</b>
|
||||
The motivation for this goal stems from the potential
|
||||
orders-of-magnitude differences in expected completion time for
|
||||
results from different projects. Some projects will have results that
|
||||
complete in hours, while other projects may have results that take
|
||||
months to complete. A scheduler that runs result computations to
|
||||
completion before starting a new computation will keep projects with
|
||||
short-running result computations stuck behind projects with
|
||||
long-running result computations. A participant in multiple projects
|
||||
will expect to see his computer work on each of these projects in a
|
||||
reasonable time period, not just the project with the long-running
|
||||
result computations.
|
||||
<b>Reschedule CPUs periodically.</b>
|
||||
This goal stems from the large differences in duration of
|
||||
results from different projects.
|
||||
Participant in multiple projects
|
||||
will expect to see their computers do work on each of these projects in a
|
||||
reasonable time period.
|
||||
|
||||
<li>
|
||||
<b>Minimize mean time to completion for results.</b>
|
||||
This means that the number of active result computations for a project should be minimized.
|
||||
<b>Minimize mean time to completion.</b>
|
||||
For example, it's better to have one result from
|
||||
project P complete in time T than to have two results from project P
|
||||
a project complete in time T than to have two results
|
||||
simultaneously complete in time 2T.
|
||||
|
||||
</ol>
|
||||
|
||||
<p>
|
||||
A result is 'active' if there is a slot directory for it.
|
||||
A consequence of result preemption is that there can
|
||||
be more active results than CPUs.
|
||||
There can be more active results than CPUs.
|
||||
|
||||
|
||||
<h3>Debt</h3>
|
||||
|
@ -145,7 +136,7 @@ ready-to-compute result.
|
|||
<pre>
|
||||
data structures:
|
||||
ACTIVE_TASK:
|
||||
double cpu_at_last_schedule_point
|
||||
double period_start_cpu_time
|
||||
double current_cpu_time
|
||||
scheduler_state:
|
||||
PREEMPTED
|
||||
|
@ -155,7 +146,7 @@ PROJECT:
|
|||
double work_done_this_period // temp
|
||||
double debt
|
||||
double anticipated_debt // temp
|
||||
bool has_runnable_result
|
||||
RESULT next_runnable_result
|
||||
|
||||
schedule_cpus():
|
||||
|
||||
|
@ -164,7 +155,7 @@ foreach project P
|
|||
|
||||
total_work_done_this_period = 0
|
||||
foreach task T that is RUNNING:
|
||||
x = current_cpu_time - T.cpu_at_last_schedule_point
|
||||
x = T.current_cpu_time - T.period_start_cpu_time
|
||||
T.project.work_done_this_period += x
|
||||
total_work_done_this_period += x
|
||||
|
||||
|
@ -186,7 +177,7 @@ do num_cpus times:
|
|||
if none:
|
||||
break
|
||||
if (some T in P is RUNNING):
|
||||
t.next_scheduler_state = RUNNING
|
||||
T.next_scheduler_state = RUNNING
|
||||
P.anticipated_debt -= expected_pay_off
|
||||
continue
|
||||
if (some T in P is PREEMPTED):
|
||||
|
@ -194,6 +185,7 @@ do num_cpus times:
|
|||
P.anticipated_debt -= expected_pay_off
|
||||
continue
|
||||
if (some R in results is for P, not active, and ready to run):
|
||||
Choose R with the earliest deadline
|
||||
T = new ACTIVE_TASK for R
|
||||
T.next_scheduler_state = RUNNING
|
||||
P.anticipated_debt -= expected_pay_off
|
||||
|
@ -205,7 +197,7 @@ foreach task T
|
|||
suspend (or kill)
|
||||
|
||||
foreach task T
|
||||
T.cpu_at_last_schedule_point = current_cpu_time
|
||||
T.period_start_cpu_time = T.current_cpu_time
|
||||
</pre>
|
||||
|
||||
<h2>Work fetch policy</h2>
|
||||
|
@ -215,11 +207,19 @@ The work fetch policy has the following goal:
|
|||
|
||||
<ul>
|
||||
<li>
|
||||
<b>Given a 'connection frequency' parameter 1/T (1/days), have enough
|
||||
work for each project to meet CPU scheduling needs for T days.</b>
|
||||
The client should expect to contact scheduling servers only every T
|
||||
days.
|
||||
So, it should try to maintain between T and 2T days worth of work.
|
||||
Maintain sufficient work so that the CPU scheduler
|
||||
is never 'starved' (i.e. a result is available for
|
||||
a particular project when one is needed).
|
||||
<li>
|
||||
More specifically:
|
||||
given a 'connection period' parameter T (days),
|
||||
always maintain sufficient work so that the CPU scheduler will
|
||||
not be starved for T days,
|
||||
given average work processing.
|
||||
The client should contact scheduling servers only about every T days.
|
||||
<li>
|
||||
Don't fetch more work than necessary, given the above goals.
|
||||
Thus, try to maintain between T and 2T days worth of work.
|
||||
</ul>
|
||||
|
||||
<h3>When to get work</h3>
|
||||
|
|
|
@ -59,6 +59,7 @@ Help debug and enhance BOINC software.
|
|||
<img align=left src=nsf.gif>
|
||||
BOINC is supported by the
|
||||
<a href=http://nsf.gov>National Science Foundation</a>
|
||||
through award SCI/0221529.
|
||||
</td>
|
||||
<td valign=top bgcolor=c8c8ff>
|
||||
<center>
|
||||
|
|
|
@ -30,11 +30,12 @@ list_item("French",
|
|||
<br><a href=http://boinc-quebec.org>boinc-quebec.org</a> (Canadian)"
|
||||
);
|
||||
list_item("German",
|
||||
"<a href=http://www.boinc.de/>www.boinc.de</a>"
|
||||
);
|
||||
list_item("Italian",
|
||||
"<a href=http://boinc.homeunix.org/>boinc.homeunix.org</a>"
|
||||
"<a href=http://www.boinc.de/>www.boinc.de</a>
|
||||
<br><a href=http://www.boinc-forum.de/>www.boinc-forum.de</a>"
|
||||
);
|
||||
//list_item("Italian",
|
||||
// "<a href=http://boinc.homeunix.org/>boinc.homeunix.org</a>"
|
||||
//);
|
||||
list_item("Japanese",
|
||||
"<a href=http://boinc.oocp.org/>translation by Komori Hitoshi</a>"
|
||||
);
|
||||
|
|
|
@ -2,16 +2,32 @@
|
|||
require_once("docutil.php");
|
||||
page_head("Proxy servers");
|
||||
echo "
|
||||
The original SETI@home benefited from the development
|
||||
of 'Proxy servers' such as SETIQueue.
|
||||
SETI@home Classic benefited from 'proxy servers' such as SETIQueue.
|
||||
These proxy servers buffer work units and results
|
||||
between participant computers and the main SETI@home server.
|
||||
They provide a smooth supply of work even when the main server is down,
|
||||
and they make it possible to run SETI@home on computers
|
||||
and they make it possible to run SETI@home Classic on computers
|
||||
not connected directly to the Internet.
|
||||
<p>
|
||||
Things are trickier in BOINC.
|
||||
Unlike SETI@home, with its 'one size fits all' work units,
|
||||
These programs won't work with BOINC (see below),
|
||||
but some of their functions can be performed by other means:
|
||||
<ul>
|
||||
<li>
|
||||
The buffering of multiple work units is provided by the BOINC client itself -
|
||||
you can specify how much work your computer should get
|
||||
each time it contacts the server.
|
||||
<li>
|
||||
Hosts that are not directly connected to the Internet,
|
||||
but share a LAN with one that is,
|
||||
can participate in BOINC using an HTTP 1.0 proxy
|
||||
such as <a href=http://www.squid-cache.org/>Squid</a> for Unix or
|
||||
<a href=http://download.com.com/3000-2381-10226247.html?tag=lst-0-21>FreeProxy</a> for Windows.
|
||||
|
||||
</ul>
|
||||
|
||||
<h3>Why won't SETIQueue work with BOINC?</h3>
|
||||
<p>
|
||||
Unlike SETI@home Classic, with its 'one size fits all' work units,
|
||||
BOINC allows work units that have extreme requirements
|
||||
(memory, disk, CPU) and makes sure they're sent only
|
||||
to hosts that can handle them.
|
||||
|
@ -19,7 +35,7 @@ In BOINC, a client communicates directly with the server,
|
|||
telling the server about its hardware (memory size, CPU speed etc.)
|
||||
and the server chooses work for it accordingly.
|
||||
Furthermore, BOINC has separate scheduling and data servers
|
||||
(in SETI@home, a single server played both roles).
|
||||
(in SETI@home Classic, a single server played both roles).
|
||||
<p>
|
||||
So a BOINC proxy would have to replicate much
|
||||
of the functionality of the BOINC core client
|
||||
|
@ -27,10 +43,6 @@ of the functionality of the BOINC core client
|
|||
and the BOINC scheduling server
|
||||
(since it would have to implement the work-distribution policy).
|
||||
This is possible but it would be a lot of work.
|
||||
<p>
|
||||
BOINC has mechanisms - such as work buffering
|
||||
and the ability to participate in multiple projects -
|
||||
that reduce the importance of proxy servers.
|
||||
";
|
||||
page_tail();
|
||||
?>
|
||||
|
|
|
@ -26,6 +26,7 @@
|
|||
// [ -asynch ] be asynchronous
|
||||
// [ -one_pass ] do one pass, then exit
|
||||
// [ -d x ] debug level x
|
||||
// [ -mod n i ] process only WUs with (id mod n) == i
|
||||
|
||||
using namespace std;
|
||||
|
||||
|
@ -44,9 +45,13 @@ using namespace std;
|
|||
#define LOCKFILE "transitioner.out"
|
||||
#define PIDFILE "transitioner.pid"
|
||||
|
||||
#define SELECT_LIMIT 100
|
||||
|
||||
int startup_time;
|
||||
SCHED_CONFIG config;
|
||||
R_RSA_PRIVATE_KEY key;
|
||||
int mod_n, mod_i;
|
||||
bool do_mod = false;
|
||||
|
||||
void handle_wu(DB_WORKUNIT& wu) {
|
||||
vector<DB_RESULT> results;
|
||||
|
@ -355,7 +360,11 @@ bool do_pass() {
|
|||
check_stop_daemons();
|
||||
// loop over WUs that are due to be checked
|
||||
//
|
||||
sprintf(buf, "where transition_time<%d order by transition_time limit 5000", (int)time(0));
|
||||
if (do_mod) {
|
||||
sprintf(buf, "where transition_time<%d and (mod(id, %d)==%d) order by transition_time limit %d", (int)time(0), mod_n, mod_i, SELECT_LIMIT);
|
||||
} else {
|
||||
sprintf(buf, "where transition_time<%d order by transition_time limit %d", (int)time(0), SELECT_LIMIT);
|
||||
}
|
||||
while (!wu.enumerate(buf)) {
|
||||
did_something = true;
|
||||
handle_wu(wu);
|
||||
|
@ -396,6 +405,10 @@ int main(int argc, char** argv) {
|
|||
one_pass = true;
|
||||
} else if (!strcmp(argv[i], "-d")) {
|
||||
log_messages.set_debug_level(atoi(argv[++i]));
|
||||
} else if (!strcmp(argv[i], "-mod")) {
|
||||
mod_n = atoi(argv[++i]);
|
||||
mod_i = atoi(argv[++i]);
|
||||
do_mod = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue