Re: WIP: Barriers - Mailing list pgsql-hackers
From | Konstantin Knizhnik |
---|---|
Subject | Re: WIP: Barriers |
Date | |
Msg-id | [email protected] Whole thread Raw |
In response to | Re: WIP: Barriers (Thomas Munro <[email protected]>) |
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: