Boost logo

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