Hi Eric,
On Fri, May 8, 2009 at 3:27 AM, Eric Day <[email protected]> wrote:

> Hi Biping,
>
> (including the Drizzle mailing list for more feedback)
>
> On Thu, May 07, 2009 at 07:36:04PM +0800, Biping MENG wrote:
> >    I've got some questions about the pool of threads scheduler here.
> >    As far as I know, libevent uses Level Trigger epoll on READ/WRITE
> event on
> >    the Linux platform. Epoll don't perform so excellent in this mode,
> >    especially when watching on too many FDs. So may it be a possible
> reason
> >    of low performance?
>
> I don't think libevent is the performance culprit here. The usage of
> libevent in the current pool of threads is not optimal, but it's not
> a significant overhead (at least I think).
>
> I think the bigger problem is that libevent is only being used when
> waiting for a new command (not for reading if the command is big or
> when writing the command out). This means the threads in the pool
> may be stuck blocking on socket I/O and/or disk I/O, which is bad
> when you have a fixed pool size. You may have new commands ready to
> run but there are no free threads because they are all blocking on
> something else.

Quite agreed. Threads that got blocked are doing nothing, while new commands
are waiting for a thread to run it. It's such a bad situation.

>
>
> Unfortunately this is not easily fixed, since the I/O code is spread
> throughout the query processing. We would need to make much of it
> stateful so it could yield the threads when it knows it will be
> blocking. This will be a big task, but ultimately, will be a big
> win. :)

This answered another question of mine. :)  I thought the scheduler must do
something with the I/O control. But I looked here and there and never saw
send nor recv in the scheduler plugin. Finally I try to believe that socket
I/O must be done during session->authenticate() , s
ession->prepareForQueries() and session->executeStatement() . So it seems
that I got it right:). As you say, we will never know when or where these
invocation got blocked, and thus, these threads just goldbrick:), unless we
have more detailed control on I/Os so as to let the idle session to yield
when necessary which would be quite a hard work.


>
>
> Stewart has also been looking at using fibers here (usserland
> threads) where Drizzle would essentially have it's own userland
> threading library. This would allow a scheduler to switch between
> "threads" when they are blocking, allowing us to avoid making the
> query execution code stateful. I'll let him comment more on this. :)


That is a smart way of doing that. :) But I have a question. So we will do
the threads switches other than drop it to OS? Is that means we need to make
the switch more efficient than OS does? Otherwise it seems this way of
implementation of pool of threads is quite the same with multi-thread
scheduling with the only difference lying on WHO does the context switch?
Not sure if I got your meaning right.

>
>
> >    How do we set size? I mean, size of the pool that containing working
> >    threads. Do we try to know the number of cores on the machine through
> some
> >    API, and set the size accordingly? I thought the most great advantage
> of
> >    pool of threads scheduling over multi-threads scheduling should be
> pool of
> >    threads has a definitely control over the number of concurrent working
> >    threads, and thus, could avoid some CPU consumption spent on context
> >    switch. So we have to set the size of pool equal to the core number to
> >    take good advantage of this saving. Do I take it right?
>
> Well, this entirely depends on the load. If we are CPU bound and
> the threads never block for any reason (disk, network, ...) having
> the same number of threads as we have cores is what we probably
> the correct answer. As soon as the threads can block for any reason
> (introduce idle CPU time), we need to start adding more threads into
> the pool to make sure there is always something to run. This is where
> some benchmarking would come in handy to see what the optimal balance
> is between thread count, CPU usage, and the context-switching overhead.
>
> Like I said above though, I think the "correct" solution is to never
> allow these threads to block and work towards an execution engine that
> can be stateful to yield the threads they are running on when possible.
> Some blocking factors, like disk I/O, are not always possible to
> yield on so we may want to look at using an async queue and a pool
> of threads dedicated to disk I/O. This allows operations that are
> normally blocking to be non-blocking for threads (allowing them to
> yield). I realize these may be high-hopes, but we can get there. :)

Can't agree more!

>
>
> -Eric
>



-- 
Cheers.

Biping MENG

Natural Language Processing(NLP) Lab
Dept. of Computer Science and Technology
Nanjing University
_______________________________________________
Mailing list: https://launchpad.net/~drizzle-discuss
Post to     : [email protected]
Unsubscribe : https://launchpad.net/~drizzle-discuss
More help   : https://help.launchpad.net/ListHelp

Reply via email to