>Marc Colosimo wrote:
>
>> Oops, I used the same setting as in the old hacking message (-O2, gcc 
>> 3.3). If I understand what you are saying, then it turns out yes, PG's 
>> MemSet is faster for smaller blocksizes (see below, between 32 and 
>> 64). I just replaced the whole MemSet with memset and it is not very 
>> low when I profile.
>
>Could you check what the OS-X memset function does internally?
>One trick to speed up memset it to bypass the cache and bulk-write 
>directly from write buffers to main memory. i386 cpus support that and 
>in microbenchmarks it's 3 times faster (or something like that). 
>Unfortunately it's a loss in real-world tests: Typically a structure is 
>initialized with memset and then immediately accessed. If the memset 
>bypasses the cache then the following access will cause a cache line 
>miss, which can be so slow that using the faster memset can result in a 
>net performance loss.
>

Could you suggest some structs to test? If I get your meaning, I would make a loop that sets then reads from the structure. 

>> I could squeeze more out of it if I spent more time trying to 
>> understand it (change MEMSET_LOOP_LIMIT to 32 and then add memset 
>> after that?). I'm now working one understanding  Spin Locks and 
>> friends. Putting in a sync call (in s_lock.h) is really a time killer 
>> and bad for performance (it takes up 35 cycles).
>>
>That's the price you pay for weakly ordered memory access.
>Linux on ppc uses eieio, on ppc64 lwsync is used. Could you check if 
>they are faster?
>

I found the reason why "sync" was put in <http://archives.postgresql.org/pgsql-bugs/2002-09/msg00239.php>, but it is odd why it works. Why syncing one processor prevents the other from doing something is interesting. What type of shared memory is being used on OS X? I'm confused about the two types of semaphores, sysV or POSIX. <http://archives.postgresql.org/pgsql-patches/2001-01/msg00052.php>It seems the POSIX is the way to go on OS X.

Marc




Mon, 20 Sep 2004 18:20:12 -0400 (EDT)
mcolosimo@mitre.org
Re: tweaking MemSet() performance - 7.4.5
mcolosimo@mitre.org wrote:

>>If the memset 
>>bypasses the cache then the following access will cause a cache line 
>>miss, which can be so slow that using the faster memset can result in a 
>>net performance loss.
>>
>>    
>>
>
>Could you suggest some structs to test? If I get your meaning, I would make a loop that sets then reads from the structure. 
>
>  
>
Read the sources and the cpu specs. Benchmarking such problems is 
virtually impossible.
I don't have OS-X, thus I checked the Linux-kernel sources: It seems 
that the power architecture doesn't have the same problem as x86.
There is a special clear cacheline instruction for large memsets and the 
rest is done through carefully optimized store byte/halfword/word/double 
word sequences.

Thus I'd check what happens if you memset not perfectly aligned buffers. 
That's another point where over-optimized functions sometimes break 
down. If there is no slowdown, then I'd replace the postgres function 
with the OS provided function.

I'd add some __builtin_constant_p() optimizations, but I guess Tom won't 
like gcc hacks ;-)
--
    Manfred

Sat, 25 Sep 2004 23:23:13 +0200
Manfred Spraul <manfred@colorfullife.com>
Re: tweaking MemSet() performance - 7.4.5
On Sat, 2004-09-25 at 23:23 +0200, Manfred Spraul wrote:
> mcolosimo@mitre.org wrote:
> 
> >>If the memset 
> >>bypasses the cache then the following access will cause a cache line 
> >>miss, which can be so slow that using the faster memset can result in a 
> >>net performance loss.
> >>
> >>    
> >>
> >
> >Could you suggest some structs to test? If I get your meaning, I would make a loop that sets then reads from the structure. 
> >
> >  
> >
> Read the sources and the cpu specs. Benchmarking such problems is 
> virtually impossible.
> I don't have OS-X, thus I checked the Linux-kernel sources: It seems 
> that the power architecture doesn't have the same problem as x86.
> There is a special clear cacheline instruction for large memsets and the 
> rest is done through carefully optimized store byte/halfword/word/double 
> word sequences.
> 
> Thus I'd check what happens if you memset not perfectly aligned buffers. 
> That's another point where over-optimized functions sometimes break 
> down. If there is no slowdown, then I'd replace the postgres function 
> with the OS provided function.
> 
> I'd add some __builtin_constant_p() optimizations, but I guess Tom won't 
> like gcc hacks ;-)

I think it cannot be problem if you write it to some .h file (in port
directory?) as macro with "#ifdef GCC". The other thing is real
advantage of hacks like this in practical PG usage :-)

	Karel

-- 
Karel Zak
http://home.zf.jcu.cz/~zakkr


Wed, 29 Sep 2004 10:46:18 +0200
Karel Zak <zakkr@zf.jcu.cz>
Re: tweaking MemSet() performance - 7.4.5
Karel Zak wrote:
> On Sat, 2004-09-25 at 23:23 +0200, Manfred Spraul wrote:
> > mcolosimo@mitre.org wrote:
> > 
> > >>If the memset 
> > >>bypasses the cache then the following access will cause a cache line 
> > >>miss, which can be so slow that using the faster memset can result in a 
> > >>net performance loss.
> > >>
> > >>    
> > >>
> > >
> > >Could you suggest some structs to test? If I get your meaning, I would make a loop that sets then reads from the structure. 
> > >
> > >  
> > >
> > Read the sources and the cpu specs. Benchmarking such problems is 
> > virtually impossible.
> > I don't have OS-X, thus I checked the Linux-kernel sources: It seems 
> > that the power architecture doesn't have the same problem as x86.
> > There is a special clear cacheline instruction for large memsets and the 
> > rest is done through carefully optimized store byte/halfword/word/double 
> > word sequences.
> > 
> > Thus I'd check what happens if you memset not perfectly aligned buffers. 
> > That's another point where over-optimized functions sometimes break 
> > down. If there is no slowdown, then I'd replace the postgres function 
> > with the OS provided function.
> > 
> > I'd add some __builtin_constant_p() optimizations, but I guess Tom won't 
> > like gcc hacks ;-)
> 
> I think it cannot be problem if you write it to some .h file (in port
> directory?) as macro with "#ifdef GCC". The other thing is real
> advantage of hacks like this in practical PG usage :-)

The reason MemSet is a win is not that the C code is great but because
it eliminates a function call.

-- 
  Bruce Momjian                        |  http://candle.pha.pa.us
  pgman@candle.pha.pa.us               |  (610) 359-1001
  +  If your life is a hard drive,     |  13 Roberts Road
  +  Christ can be your backup.        |  Newtown Square, Pennsylvania 19073

Wed, 29 Sep 2004 07:37:00 -0400 (EDT)
Bruce Momjian <pgman@candle.pha.pa.us>
Re: tweaking MemSet() performance - 7.4.5
On Sep 29, 2004, at 7:37 AM, Bruce Momjian wrote:

> Karel Zak wrote:
>> On Sat, 2004-09-25 at 23:23 +0200, Manfred Spraul wrote:
>>> mcolosimo@mitre.org wrote:
>>>
>>>>> If the memset
>>>>> bypasses the cache then the following access will cause a cache 
>>>>> line
>>>>> miss, which can be so slow that using the faster memset can result 
>>>>> in a
>>>>> net performance loss.
>>>>
>>>> Could you suggest some structs to test? If I get your meaning, I 
>>>> would make a loop that sets then reads from the structure.
>>>>
>>> Read the sources and the cpu specs. Benchmarking such problems is
>>> virtually impossible.
>>> I don't have OS-X, thus I checked the Linux-kernel sources: It seems
>>> that the power architecture doesn't have the same problem as x86.
>>> There is a special clear cacheline instruction for large memsets and 
>>> the
>>> rest is done through carefully optimized store 
>>> byte/halfword/word/double
>>> word sequences.
>>>
>>> Thus I'd check what happens if you memset not perfectly aligned 
>>> buffers.
>>> That's another point where over-optimized functions sometimes break
>>> down. If there is no slowdown, then I'd replace the postgres function
>>> with the OS provided function.
>>>

all memory (via malloc and friends) will be aligned on OS X, unless you 
remove padding (which I don't think you do)

>>> I'd add some __builtin_constant_p() optimizations, but I guess Tom 
>>> won't
>>> like gcc hacks ;-)
>>
>> I think it cannot be problem if you write it to some .h file (in port
>> directory?) as macro with "#ifdef GCC". The other thing is real
>> advantage of hacks like this in practical PG usage :-)
>
> The reason MemSet is a win is not that the C code is great but because
> it eliminates a function call.
>

Using MemSet really did speed things up. I think the function overhead 
is okay. As for real world usage, the function ExecMakeFunctionResult 
dropped from the top of the list when profiling (now < 1% vs 16% 
before)!  This was doing a big nasty delete (w/ cascading), insert in a 
cursor.

Here are results for a Mac G4 (single processor) OS 10.3, using -O2. 
This time the mac memset wins all around. Someone posted that this 
wasn't the case.

PG MemSet:
pgmemset_test 32
0.670u 0.020s 0:00.70 98.5%     0+0k 0+0io 0pf+0w
pgmemset_test 64
1.060u 0.000s 0:01.05 100.9%    0+0k 0+0io 0pf+0w
pgmemset_test 128
1.750u 0.010s 0:01.76 100.0%    0+0k 0+0io 0pf+0w
pgmemset_test 512
6.010u 0.030s 0:06.04 100.0%    0+0k 0+0io 0pf+0w

Mac memset:
memset_test 32
0.660u 0.020s 0:00.67 101.4%    0+0k 0+0io 0pf+0w
memset_test 64
0.720u 0.000s 0:00.72 100.0%    0+0k 0+0io 0pf+0w
memset_test 128
0.800u 0.010s 0:00.81 100.0%    0+0k 0+0io 0pf+0w
memset_test 512
1.470u 0.010s 0:01.48 100.0%    0+0k 0+0io 0pf+0w

Now I check about setting a byte after I memset, and it does slow down 
a tiny bit. But it is the same for both MemSet and memset for under 64.



Wed, 29 Sep 2004 09:38:39 -0400
Marc Colosimo <mcolosimo@mitre.org>
Re: tweaking MemSet() performance - 7.4.5
On Wed, 2004-09-29 at 21:37, Bruce Momjian wrote:
> The reason MemSet is a win is not that the C code is great but because
> it eliminates a function call.

A reasonable compiler ought to be able to implement memset() as a
compiler intrinsic where it makes sense to do so. MSVC++ can certainly
do this; per the GCC 3.4 docs, it seems GCC can/does as well:

The ISO C90 functions abort, abs, acos, asin, atan2, atan, calloc, ceil,
cosh, cos, exit, exp, fabs, floor, fmod, fprintf, fputs, frexp, fscanf,
labs, ldexp, log10, log, malloc, memcmp, memcpy, memset, modf, pow,
printf, putchar, puts, scanf, sinh, sin, snprintf, sprintf, sqrt,
sscanf, strcat, strchr, strcmp, strcpy, strcspn, strlen, strncat,
strncmp, strncpy, strpbrk, strrchr, strspn, strstr, tanh, tan, vfprintf,
vprintf and vsprintf are all recognized as built-in functions unless
-fno-builtin is specified (or -fno-builtin-function is specified for an
individual function). All of these functions have corresponding versions
prefixed with __builtin_.

(http://gcc.gnu.org/onlinedocs/gcc-3.4.2/gcc/Other-Builtins.html#Other-Builtins)

-Neil



Thu, 30 Sep 2004 10:40:48 +1000
Neil Conway <neilc@samurai.com>
Re: tweaking MemSet() performance - 7.4.5
Neil Conway wrote:
> On Wed, 2004-09-29 at 21:37, Bruce Momjian wrote:
> > The reason MemSet is a win is not that the C code is great but because
> > it eliminates a function call.
> 
> A reasonable compiler ought to be able to implement memset() as a
> compiler intrinsic where it makes sense to do so. MSVC++ can certainly
> do this; per the GCC 3.4 docs, it seems GCC can/does as well:
> 
> The ISO C90 functions abort, abs, acos, asin, atan2, atan, calloc, ceil,
> cosh, cos, exit, exp, fabs, floor, fmod, fprintf, fputs, frexp, fscanf,
> labs, ldexp, log10, log, malloc, memcmp, memcpy, memset, modf, pow,
> printf, putchar, puts, scanf, sinh, sin, snprintf, sprintf, sqrt,
> sscanf, strcat, strchr, strcmp, strcpy, strcspn, strlen, strncat,
> strncmp, strncpy, strpbrk, strrchr, strspn, strstr, tanh, tan, vfprintf,
> vprintf and vsprintf are all recognized as built-in functions unless
> -fno-builtin is specified (or -fno-builtin-function is specified for an
> individual function). All of these functions have corresponding versions
> prefixed with __builtin_.
> 
> (http://gcc.gnu.org/onlinedocs/gcc-3.4.2/gcc/Other-Builtins.html#Other-Builtins)

MemSet was written when gcc 2.X wasn't even stable yet.  Have you run
any tests on 3.4 to see if MemSet is still a win with that compiler?

-- 
  Bruce Momjian                        |  http://candle.pha.pa.us
  pgman@candle.pha.pa.us               |  (610) 359-1001
  +  If your life is a hard drive,     |  13 Roberts Road
  +  Christ can be your backup.        |  Newtown Square, Pennsylvania 19073

Wed, 29 Sep 2004 21:47:06 -0400 (EDT)
Bruce Momjian <pgman@candle.pha.pa.us>
Re: tweaking MemSet() performance - 7.4.5
Bruce Momjian wrote:
> MemSet was written when gcc 2.X wasn't even stable yet.  Have you run
> any tests on 3.4 to see if MemSet is still a win with that compiler?

I've done a test years ago that showed that memset is usually at least 
as good as MemSet:

http://archives.postgresql.org/pgsql-patches/2002-10/msg00085.php

-- 
Peter Eisentraut
http://developer.postgresql.org/~petere/


Fri, 1 Oct 2004 22:40:03 +0200
Peter Eisentraut <peter_e@gmx.net>
Re: tweaking MemSet() performance - 7.4.5