Fine grain select locking.
Kris Kennaway
kris at obsecurity.org
Sun Jul 29 18:07:23 UTC 2007
On Wed, Jul 04, 2007 at 11:47:35AM -0700, Jeff Roberson wrote:
> >>http://people.freebsd.org/~jeff/select2.diff
> >
> >Jeff, I understand you're trying to speed up mysql micro benchmarks,
> >but have you done any benchmarking on large select operations?
>
> I don't know that I'd call mysql a micro-benchmark. This patch also
> didn't help there as much as I had hoped and I'm still trying to
> understand why.
Here is a graph of the performance effects to sysbench with this
patch:
http://obsecurity.dyndns.org/select.png
mysql
=====
It appears that at higher loads most of the contention is now in
userland, no longer within the kernel. There is also significant
contention on the proc lock.
Peak load (8 clients):
31 1137 169 1280 0 0 126 56 kern/kern_umtx.c:325 (sleep mutex:umtxql)
7 5688 554 4750 1 0 722 294 kern/subr_sleepqueue.c:388 (sleep mutex:process lock)
3 2335 1155 8732 0 0 669 571 kern/sys_generic.c:955 (sleep mutex:process lock)
Higher load (20 clients):
88 6714 807 4763 1 0 754 276 kern/subr_sleepqueue.c:388 (sleep mutex:process lock)
3 2342 1228 7656 0 0 650 550 kern/sys_generic.c:955 (sleep mutex:process lock)
2 431 1299 1023 0 1 53 77 kern/kern_sig.c:996 (sleep mutex:process lock)
7 371 3545 635 0 5 58 131 kern/kern_mutex.c:141 (sleep mutex:umtxql)
70 5085 7433 3184 1 2 507 377 kern/kern_umtx.c:325 (sleep mutex:umtxql)
I looked in the past at replacing the proc mutex with a rwlock and
looking for places where shared locking could be used, but at least as
the code is written currently I dont think any of those apply here.
With the select locking patch overall mysql performance does not
change much, but the total amount of time spent waiting for locks is
greatly reduced (by about an order of magnitude), so system time
should be lower with these changes (unless it's counterbalanced by
greater time spent doing other things than lock waits). I have not
measured this though.
We might be able to obtain some further improvement at higher loads by
improving the contention behaviour of umtx objects (the kernel part of
the libthr pthread mutex). I suspect most of the problem is in mysql
itself. What we need is a userland counterpart of lock profiling, for
profiling contention on pthread mutexes.
pgsql
=====
Clear performance benefit from select locking, on the order of 5-10%.
Reduction in lock wait time is about *two* orders of magnitude.
Peak load:
5 2942 1437 2607 1 0 818 446 kern/subr_turnstile.c:546 (spin mutex:turnstile chain)
13 9250 1474 9572 0 0 1405 585 kern/subr_sleepqueue.c:388 (sleep mutex:process lock)
39 3019 2856 9458 0 0 1613 1131 kern/sys_generic.c:955 (sleep mutex:process lock)
120 5540 5494 16954 0 0 3536 2017 kern/kern_sig.c:996 (sleep mutex:process lock)
20 clients:
8 5336 3506 4338 1 0 1610 910 kern/subr_turnstile.c:546 (spin mutex:turnstile chain)
2 2828 4261 8787 0 0 1749 1298 kern/sys_generic.c:955 (sleep mutex:process lock)
56 10717 4568 8968 1 0 3092 1382 kern/subr_sleepqueue.c:388 (sleep mutex:process lock)
4 5390 7646 15766 0 0 3325 2568 kern/kern_sig.c:996 (sleep mutex:process lock)
79 9423 70619 33525 0 2 154 92 kern/uipc_syscalls.c:135 (sleep mutex:sleep mtxpool)
i.e. much the same lock workload as mysql except for no umtx
contention (pgsql is not threaded), and huge wait time (but not much
contention) on the following:
static int
getsock(struct filedesc *fdp, int fd, struct file **fpp, u_int *fflagp)
{
...
if (fdp == NULL)
error = EBADF;
else {
FILEDESC_SLOCK(fdp);
fp = fget_locked(fdp, fd);
if (fp == NULL)
error = EBADF;
else if (fp->f_type != DTYPE_SOCKET) {
fp = NULL;
error = ENOTSOCK;
} else {
fhold(fp);
...
}
I think this is mostly because it's called so often, with small
incremental but large total cost.
Kris
More information about the freebsd-arch
mailing list