Fine-grained locking for POSIX local sockets
(UNIX domain sockets )
Jin Guojun
jinmtb at sbcglobal.net
Fri May 12 18:20:04 UTC 2006
Scott Long wrote:
> Sven Petai wrote:
>
>> On Tuesday 09 May 2006 20:35, Julian Elischer wrote:
>>
>>> Sven Petai wrote:
>>>
>>> are there any patches that take the gettimeofday() calls and replace
>>> them with something that is cheap
>>> such as only doing every 10th one and just returning the last value
>>> ++ 1
>>> uSec for the other ones..
>>>
>>> a ktrace of Mysql shows a LOT of gettimeofday() calls.
>>>
>>
>>
>> well I have actually done that although in a very hackish way that
>> is suitable *only* for benchmarking, but my goal really was
>> just to find out if gettimeofday really is the bottleneck.
>>
>> Basically I just preloaded my version of "buffering" time() over libc's.
>> That function asked kernel for time only after every 5000 invocations.
>> I could get away with that for benchmarking since
>> about 99,99% of gettimeofday() calls from mysqld really come through
>> time() which has anyway only 1 second resolution and mysqld seems to use
>> the value for purposes that are not really all that critical, like
>> stats and safeguard timers.
>> It's also called far more than 5000 times in a second while benchmark is
>> running so it should return correct values too.
>>
>> Anyway, the results really astonished me, what I got for reducing
>> gettimeofday() calls by ~96% was performance *decrease* of about 4-5%.
>> I thought something was wrong with my measurement techniques, so I
>> wrote the buffering time() function that used TSC directly into mysqld,
>> replaced all the time() calls with that, so that number of
>> gettimeofday()
>> syscalls ktrace reported was down to only the initial one, but still
>> got the same 5% decrease.
>>
>> I just can't explain it, but can't find any mistakes in methods too.
>
>> The library I used is available @
>> http://bsd.ee/~hadara/debug/mysql4/time_lib_hack.c
>
>
> Were you testing on SMP, and if so, was Hyperthreading enabled?
>
> Scott
I think that depends on the type of testing, not hardware. I simply
replaced
gettimeofday() syscall with a super simple user space code, for testing
with no time
accuracy, in libc (libc.so.6.test, which is mapped for mysqld and mysql
via libmap --
see details at the end),
and found that code has no effect on "select-only" super-smack test, and has
some impact (7-8%) for super-smack "update-select" test.
The code itself is about 80~90 times faster than gettimeofday syscall.
So, the slow is not mainly caused by timestamp, but I/O and other syscalls.
129 /tmp: ldd /usr/local/libexec/mysqld
/usr/local/libexec/mysqld:
... skipped
libpthread.so.2 => /usr/lib/libthr.so.2 (0x884fc000)
libc.so.6 => /lib/libc.so.6 (0x8850e000)
130 /tmp: super-smack -d mysql
/usr/local/share/super-smack/update-select.smack 10 7000
Query Barrel Report for client smacker
connect: max=4ms min=4ms avg= 4ms from 10 clients
Query_type num_queries max_time min_time q_per_s
select_index 70000 1 0 3125.63
update_index 70000 1 0 3125.63
2.742u 4.058s 0:22.52 30.1% 119+519k 0+0io 0pf+0w
----- edit /etc/libmap.conf and restart mysqld ----------
131 /tmp: ldd /usr/local/libexec/mysqld
/usr/local/libexec/mysqld:
... skiipped
libpthread.so.2 => /usr/lib/libthr.so.2 (0x884fc000)
libc.so.6 => /lib/libc.so.6.test (0x8850e000)
132 /tmp: super-smack -d mysql
/usr/local/share/super-smack/update-select.smack 10 7000
Query Barrel Report for client smacker
connect: max=5ms min=2ms avg= 3ms from 10 clients
Query_type num_queries max_time min_time q_per_s
select_index 70000 1 0 3356.99
update_index 70000 1 0 3356.99
2.634u 4.198s 0:20.97 32.5% 116+506k 0+0io 0pf+0w
133 /tmp: super-smack -d mysql
/usr/local/share/super-smack/update-select.smack 10 7000
Query Barrel Report for client smacker
connect: max=248ms min=1ms avg= 132ms from 10 clients
Query_type num_queries max_time min_time q_per_s
select_index 70000 1 0 3334.93
update_index 70000 1 0 3334.93
2.604u 4.247s 0:21.11 32.4% 115+503k 0+0io 0pf+0w
------------- original gettimeofday code ----------
< #include "SYS.h"
< RSYSCALL(gettimeofday)
--------- replacement code ---
#include <sys/time.h>
static struct timeval tmv_base={$COMPILING_TIME};
#ifndef FAKE_INC
#define FAKE_INC 700 /* 100-times longer as per gettimeofday
cost */
#endif
#define ONE_MEGA 1000000
int
gettimeofday(struct timeval *tp, struct timezone *nouse)
{
tmv_base.tv_usec += FAKE_INC;
if (tmv_base.tv_usec >= ONE_MEGA)
tmv_base.tv_usec -= ONE_MEGA,
++tmv_base.tv_sec;
if (tp) {
*tp = tmv_base;
return 0;
}
return -1;
}
More information about the freebsd-current
mailing list