|
Boost : |
Subject: Re: [boost] [threadpool] version 22 with default pool
From: vicente.botet (vicente.botet_at_[hidden])
Date: 2009-03-09 13:35:32
----- Original Message -----
From: "Edouard A." <edouard_at_[hidden]>
To: <boost_at_[hidden]>
Sent: Monday, March 09, 2009 9:42 AM
Subject: Re: [boost] [threadpool] version 22 with default pool
>
> On Sun, 8 Mar 2009 23:35:00 +0100, "vicente.botet"
> <vicente.botet_at_[hidden]> wrote:
>
>>> Alternatively you can embed in your task some sort of synchronization
>>> mechanism... But I think it's best to have the client write as little
>>> synchronization code as possible.
>>
>> Could you elaborate on this?
>
>
> If you add a barrier in your task. The problem is to avoid having one
> thread waiting for n threads. If you have threads waiting for each other, I
> would say it's better.
>
> If you are using a kernel object to wait, you pay the cost of a transition
> even if you don't have to wait.
Sorry, I'm a little bit lost.
>>> The problem is that you can have lots of tasks when sorting a container,
>>> and
>>> that means a lot of overhead with this approach. If I'm correct, if you
>>> have
>>> many tasks the wait_all starts to be slow. Maybe it's just a problem on
>>> my
>>> platform. I would need to investigate this further.
>>
>> Why there is overhead? Why wait_for_all is slow?
>
> I don't know. Maybe for the reason stated above.
Do you mean that wait_for_all will block the current thread? What about my proposition to specialize wait_for_all when we are in a worker thread?
template<typename T1,typename T2,typename T3>
void wait_for_all(task<T1>& t1,task<T2>& t2,task<T2>& t3)
{
boost::this_task::reschedule_until(t1.result());
boost::this_task::reschedule_until(t2.result());
boost::this_task::reschedule_until(t3.result());
}
or even better add an indirection, instead of act.wait() use wait(act):
template<typename CF1,typename CF2,typename CF3>
void wait_for_all(F1& f1,F2& f2,F3& f3) {
wait(f1);
wait(f2);
wait(f3);
}
and define wait as
template <typename ACT>
void wait(ACT& act) {
if (boost::this_task::is_worker()) {
boost::this_task::reschedule_until(predicate::is_ready(act));
} else {
act.wait();
}
}
template <typename R>
void wait(tp::task<R>& t) {
t.result().wait();
}
Boost.Interthreads has already this kind of free functions (wait()). Now that Boost.ThreadPool allows to check if the tread is a worker of a pool we can add a layer doing exactly that.
What do you think?
Vicente
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk