Re: WIP: Barriers

From: Konstantin Knizhnik <k(dot)knizhnik(at)postgrespro(dot)ru>
To: Thomas Munro <thomas(dot)munro(at)enterprisedb(dot)com>
Cc: Pg Hackers <pgsql-hackers(at)postgresql(dot)org>
Subject: Re: WIP: Barriers
Date: 2016-08-15 16:32:07
Message-ID: 57B1EE87.9010405@postgrespro.ru
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-hackers


On 15.08.2016 15:42, Thomas Munro wrote:
> This implementation is using a spinlock for the arrival counter, and
> signals (via Robert's condition variables and latches) for waking up
> peer processes when the counter reaches the target. I realise that
> using signals for this sort of thing is a bit unusual outside the
> Postgres universe, but won't a semaphore-based implementation require
> just as many system calls, context switches and scheduling operations?

Yes, you are right.
I never expected that this combination of signal+local socket+select can
provide performance comparable with pthread_cond_t.
I have implemented simple test where two background workers are
emulating request-response round-trip using latches and pthread primitives.
Result (average round-trip time) was 7.49 microseconds for Postgres
latches vs. 4.59 microseconds for pthread_cond_timedwait.

#define N_ROUNDTRIPS 1000000
#define WAIT_LATCH_TIMEOUT 60000

static void PongLatch(Datum arg)
{
int i;
timestamp_t start;
int result;

BackgroundWorkerUnblockSignals();

Mtm->pong = MyProc->pgprocno;
ResetLatch(&MyProc->procLatch);
MtmSleep(1000000);
Assert(Mtm->ping);

for (i = 0; i <= N_ROUNDTRIPS; i++) {
result = WaitLatch(&MyProc->procLatch, WL_LATCH_SET|WL_TIMEOUT,
WAIT_LATCH_TIMEOUT);
Assert(result & WL_LATCH_SET);
ResetLatch(&MyProc->procLatch);
SetLatch(&ProcGlobal->allProcs[Mtm->ping].procLatch);
if (i == 0) {
start = MtmGetSystemTime();
}
}
fprintf(stderr, "Average roundrip time: %f microsconds\n",
(double)(MtmGetSystemTime() - start) / N_ROUNDTRIPS);
}

static void PingLatch(Datum arg)
{
int i;
timestamp_t start;
int result;

BackgroundWorkerUnblockSignals();

Mtm->ping = MyProc->pgprocno;
ResetLatch(&MyProc->procLatch);
MtmSleep(1000000);
Assert(Mtm->pong);

for (i = 0; i <= N_ROUNDTRIPS; i++) {
SetLatch(&ProcGlobal->allProcs[Mtm->pong].procLatch);
result = WaitLatch(&MyProc->procLatch, WL_LATCH_SET|WL_TIMEOUT,
WAIT_LATCH_TIMEOUT);
Assert(result & WL_LATCH_SET);
ResetLatch(&MyProc->procLatch);
if (i == 0) {
start = MtmGetSystemTime();
}
}
fprintf(stderr, "Average roundrip time: %f microseconds\n",
(double)(MtmGetSystemTime() - start) / N_ROUNDTRIPS);
}

static BackgroundWorker Pinger = {
"ping",
BGWORKER_SHMEM_ACCESS,// | BGWORKER_BACKEND_DATABASE_CONNECTION,
BgWorkerStart_ConsistentState,
BGW_NEVER_RESTART,
PingLatch
};

static BackgroundWorker Ponger = {
"pong",
BGWORKER_SHMEM_ACCESS,// | BGWORKER_BACKEND_DATABASE_CONNECTION,
BgWorkerStart_ConsistentState,
BGW_NEVER_RESTART,
PongLatch
};

static void PingPong()
{
RegisterBackgroundWorker(&Pinger);
RegisterBackgroundWorker(&Ponger);
}

--
Konstantin Knizhnik
Postgres Professional: http://www.postgrespro.com
The Russian Postgres Company

In response to

Browse pgsql-hackers by date

  From Date Subject
Next Message David Steele 2016-08-15 16:50:53 Re: patch proposal
Previous Message Jeff Janes 2016-08-15 16:31:14 Re: Undiagnosed bug in Bloom index