Re: WIP: Barriers - Mailing list pgsql-hackers

From Konstantin Knizhnik
Subject Re: WIP: Barriers
Date
Msg-id 57B1EE87.9010405@postgrespro.ru
Whole thread Raw
In response to Re: WIP: Barriers  (Thomas Munro <thomas.munro@enterprisedb.com>)
List 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




pgsql-hackers by date:

Previous
From: Jeff Janes
Date:
Subject: Re: Undiagnosed bug in Bloom index
Next
From: David Steele
Date:
Subject: Re: patch proposal