Boost logo

Boost :

Subject: Re: [boost] [context review] Several Questions
From: Oliver Kowalke (oliver.kowalke_at_[hidden])
Date: 2011-03-21 10:13:18


-------- Original-Nachricht --------
> Datum: Mon, 21 Mar 2011 06:38:58 -0700 (PDT)
> Von: Artyom <artyomtnk_at_[hidden]>
> An: boost_at_[hidden]
> Betreff: Re: [boost] [context review] Several Questions

> > From: Oliver Kowalke <oliver.kowalke_at_[hidden]>
> >
> > > > sched_yield(): 2108 cycles
> > > > ucontext_t: 1795 cycles
> > > > fcontext_t: 156 cycles
> > > >
> >
> > > Actually it is quite consistent with what you had show,
> > > the Boost.Context is better (but not significantly) then
> > > real OS (kernel) context switch.
> >
> > factor 13x ?
> >
>
> I was talking about _default_ build which uses ucontext.

OK - ucontext does system calls which are time consuming.

Anyway with sched_yield() you do not achive the same as with ucontext.

The idea is not to block your current process/thread if some conditions are not met but to proceed with other work an return if the the conditions are met.

void my_action_1()
{
   // compute something
   ...
   // some condtions are not met
   // don not block thread;
   // jump out and do other stuff (for instance my_action-2()
   // in the meantime
   yield();
   // conditions now met and we can proceed with our computation
}

void my_action_2() {...}

the code has choosen to return execution control and let the thread do other things (like process my_action_2()). If, for instance an external event happend and the conditions are met for my_action_1() the execution control is given back to my_action_1() with all its local state (variables, stackframe, etc.).

Using event-loops you can achive similiar things (not fully equivalent) but you have to be always aware of the event loop - and at least I don't feel this paradigm straigth forward.

If you take a look into boos.tasklet you could see that this lib has some classes like mutex,condition- and event-variables etc. whic hhide the yield() call. You can programm like for boost.thread.

boost.context and boost.tasklet are derivative work from boost.task. boost.task implements a thread-pool and my aim was that the tasks I push to the poll don't block the worker-thread if the current computation can not be fullfilled because some criteria are not met.
For instance a task creates certain amount of subtasks and has to wait for the result of its sub-tasks. Until all sub-tasks are finished the parent-task blocks its worker-thread inside the pool.
If you create more sub-tasks than worker-threads than your thead-pool is blocked.
In order to solve this problem I've developed boost.tasklet (fromaly boost.fiber) and boost.context.
As Phil Endecott requested I should move the cotnext switching code into a library (== boost.context) so other libs could probably benefit from it (boost.coroutine).

several other languages provide such context switching facilities:

Lua : http://lua-users.org/wiki/CoroutinesTutorial
Go : http://sites.google.com/site/gopatterns/concurrency/coroutines
Scheme : http://en.wikipedia.org/wiki/Scheme_%28programming_language%29#First-class_continuations
Stackless Python : http://www.stackless.com/

why shouldn't C++ not provide such a facility (at least this is my motivation)

best regards,
Oliver

-- 
NEU: FreePhone - kostenlos mobil telefonieren und surfen!			
Jetzt informieren: http://www.gmx.net/de/go/freephone

Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk