Some programs inspired from tasks that could be a part of an operating system.
Fig. 6.1 Pool of tasks
Method Features
General Algorithm
for each worker
while (true) {
get a task from the pool;
if (no more tasks)
break;
execute task, possibly generating new ones;
}
The master generates one task at a time and assigns it to the first available worker.
The workers wait for a task and execute it while they are not told to stop.
Master()
{
do {
task = Generate_task();
if (task != done) {
Recv(worker, any_process);
Send(task, worker);
}
} while (task != done);
Finish_all();
}
Finish_all()
{
for(i=1, i<=nb_workers; i++) { // nb_workers = nb_proc-1
Recv(worker, any_process);
Send(done, worker);
}
}
Worker()
{
do {
Send(proc_id, master);
Recv(task, master);
if (task != done)
Execute_task(task);
} while (task != done);
}
Example: Chess
A second model with a queue of tasks
Master()
{
Queue q;
while (tasks not finished) {
choose randomly between Generate_store_task(q);
Assign_task(q);
}
while (!q.is_empty())
Assign_task(q);
Finish_all();
}
Generate_store_task(q)
{
task = Generate_task();
q.enqueue(task);
}
Assign_task(q)
{
Recv(result, any_process);
worker = which; // status.MPI_Source
if (q.is_empty())
Generate_store_task(q);
task = q.dequeue();
Send(task, worker);
}
Worker()
{
result = none;
do {
Send(result, master);
Recv(task, master);
if (task != done)
result = Execute_task(task);
} while (task != done);
}
The complete model
Fig 6.2
Pool of tasks, complete model
Master()
{
Queue task_q, worker_q;
while (tasks not finished) {
choose randomly between Generate_store_task(task_q); Get_free_worker(task_q, worker_q);
Assign_task(task_q, worker_q);
}
while (!task_q.is_empty()) {
choose randomly between
Assign_task(q);
Get_free_worker(task_q, worker_q);
} while (worker_q.size() != nb_proc-1)
Get_free_worker(task_q, worker_q);
Finish_all();
}
Assign_task(task_q, worker_q)
{
if (!task_q.is_empty() and !worker_q.is_empty()) {
task = task_q.dequeue();
worker = worker_q.dequeue();
Send(task, worker);
}
}
Get_free_worker(task_q, worker_q)
{
Recv(task, any_process);
worker = which; // status.MPI_Source
worker_q.enqueue(worker);
if (To_be_assigned(task))
task_q.enqueue(task);
}
Note. The implementation of this model can be a project.