Fine-grained locking for POSIX local sockets (UNIX domain sockets )

Jin Guojun jinmtb at sbcglobal.net
Fri May 12 18:19:55 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-performance mailing list