|
Boost : |
Subject: Re: [boost] [task]
From: vicente.botet (vicente.botet_at_[hidden])
Date: 2009-10-03 09:13:05
Hi,
----- Original Message -----
From: <k-oli_at_[hidden]>
To: <boost_at_[hidden]>
Sent: Friday, October 02, 2009 8:50 PM
Subject: Re: [boost] [task]
>
> Am Freitag 02 Oktober 2009 19:33:32 schrieb vicente.botet:
>
>> > First - boost.task is the successor of boost.threadpool and uses the
>> > wait- notifications too (but doesn't wait infinit because some
>> > co-worker-thread could have produced additonal tasks which could be
>> > stolen).
>>
>> Could you explain why a single mutex/condition at the pool level is not
>> workable to wait/signal for all the task submitions?
>
> worker in boost.task use mutex/condition in queues and get notifed if new work
> was enqueued (queue::take() etc.)
My question was why this mutex/condition or another mutex/condition can not be used to track the number of pending tasks, enqueued in the external or internal queues, an idle task can wait until a task is available to process without sleeping. It is possible performances could degrade, but this needs to be proven, and maybe this could depend on the context, as Jeremy has explained.
The polling strategy has two drawbacks:
* the pool will spent time even when it has nothing to do.
* Even when there are idle worker threads on the pool, they can be sleeping, so the activation delay could be near the sleep time, that if I'm not wrong, it is of 10 microseconds by default.
The polling strategy has one advantage:
* there is no need to have a single lock for the external thread and the worker threads
As we need just to make thread safe the access to pending tasks counter the locking time will be quite short to not disturb the parallelism.
Have you an idea of the CPU spent when the pool has nothing to do?
What do you think about adding some instrumentation in the code (debug mode) to measure the activation delay (min, max, mean, ..)?
>> > Second - I'm finishing boost.task-0.4.0 which replaces
>> > this_task::reschedule_until() by this_task::block().
>> > block() suspends the current task without blocking the worker-thread. The
>> > blocked task gets rescheduled by the internal scheduler (returning from
>> > block()):
>> >
>> > while ( ! condition)
>> > this_task::block();
>>
>> Oliver, does it means that you will integrate your Boost.Fiber library on
>> version 0.4?
>
> boost.task-0.4.0 uses fibers and a user-mode-scheduler inside the threadpool
>
>> In order to avoid polling on the condition, it would be great if the user
>> can get a handle of the blocked task and reschedule it when the condition
>> could be true.
>
> htere is no need that the user does the scheduling - this_task::block() stops
> the execution of the current task and passes it to the internal user-mode-
> scheduler which reschedules the task (if the condition is not ready the task
> gets blocked again)
Of course this is not absolutely necesary, as polling works. The idea is that instead of polling on the condition, the user can know when the condition can change and only then will signal to the Task library that the blocked task should be re-scheduled. If we can avoid evaluating the predicate at each task execution, this 'could' improve the performances, again, this must to me proven ;-)
Anyway the polling strategy needs to remain available as the user could not be able to signal changes impacting the condition result.
Best,
Vicente
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk