1
0
mirror of https://github.com/postgres/postgres.git synced 2025-12-07 12:02:30 +03:00

Make pgbench use erand48() rather than random().

glibc renders random() thread-safe by wrapping a futex lock around it;
testing reveals that this limits the performance of pgbench on machines
with many CPU cores.  Rather than switching to random_r(), which is
only available on GNU systems and crashes unless you use undocumented
alchemy to initialize the random state properly, switch to our built-in
implementation of erand48(), which is both thread-safe and concurrent.

Since the list of reasons not to use the operating system's erand48()
is getting rather long, rename ours to pg_erand48() (and similarly
for our implementations of lrand48() and srand48()) and just always
use those.  We were already doing this on Cygwin anyway, and the
glibc implementation is not quite thread-safe, so pgbench wouldn't
be able to use that either.

Per discussion with Tom Lane.
This commit is contained in:
Robert Haas
2011-08-03 16:26:40 -04:00
parent ac36e6f71f
commit 4af43ee3f1
12 changed files with 40 additions and 62 deletions

View File

@@ -30,8 +30,8 @@ include $(top_builddir)/src/Makefile.global
override CPPFLAGS := -I$(top_builddir)/src/port -DFRONTEND $(CPPFLAGS)
LIBS += $(PTHREAD_LIBS)
OBJS = $(LIBOBJS) chklocale.o dirmod.o exec.o inet_net_ntop.o noblock.o \
path.o pgcheckdir.o pgmkdirp.o pgsleep.o pgstrcasecmp.o \
OBJS = $(LIBOBJS) chklocale.o dirmod.o erand48.o exec.o inet_net_ntop.o \
noblock.o path.o pgcheckdir.o pgmkdirp.o pgsleep.o pgstrcasecmp.o \
qsort.o qsort_arg.o sprompt.o thread.o
# foo_srv.o and foo.o are both built from foo.c, but only foo.o has -DFRONTEND

View File

@@ -2,10 +2,14 @@
*
* erand48.c
*
* This file supplies versions of erand48(), lrand48(), and srand48()
* for machines that lack them. (These are all the members of the drand48
* family that Postgres currently requires. We name the file after erand48
* because that is the one that configure tests for.)
* This file supplies pg_erand48(), pg_lrand48(), and pg_srand48(), which
* are just like erand48(), lrand48(), and srand48() except that we use
* our own implementation rather than the one provided by the operating
* system. We used to test for an operating system version rather than
* unconditionally using our own, but (1) some versions of Cygwin have a
* buggy erand48() that always returns zero and (2) as of 2011, glibc's
* erand48() is strangely coded to be almost-but-not-quite thread-safe,
* which doesn't matter for the backend but is important for pgbench.
*
*
* Copyright (c) 1993 Martin Birgmeier
@@ -72,7 +76,7 @@ _dorand48(unsigned short xseed[3])
double
erand48(unsigned short xseed[3])
pg_erand48(unsigned short xseed[3])
{
_dorand48(xseed);
return ldexp((double) xseed[0], -48) +
@@ -81,14 +85,14 @@ erand48(unsigned short xseed[3])
}
long
lrand48(void)
pg_lrand48(void)
{
_dorand48(_rand48_seed);
return ((long) _rand48_seed[2] << 15) + ((long) _rand48_seed[1] >> 1);
}
void
srand48(long seed)
pg_srand48(long seed)
{
_rand48_seed[0] = RAND48_SEED_0;
_rand48_seed[1] = (unsigned short) seed;

View File

@@ -21,5 +21,5 @@
long
random()
{
return lrand48();
return pg_lrand48();
}

View File

@@ -21,5 +21,5 @@
void
srandom(unsigned int seed)
{
srand48((long int) seed);
pg_srand48((long int) seed);
}