From b418d7eafacfd9aa6d44951deda9690752732197 Mon Sep 17 00:00:00 2001 From: Andrey Borodin Date: Sun, 11 Apr 2021 21:18:10 +0300 Subject: [PATCH v17 2/2] Divide SLRU buffers into n-associative banks --- src/backend/access/transam/slru.c | 36 +++++++++++++++++++++++++++---- src/include/access/slru.h | 2 ++ 2 files changed, 34 insertions(+), 4 deletions(-) diff --git a/src/backend/access/transam/slru.c b/src/backend/access/transam/slru.c index 82149ad782..84321b7509 100644 --- a/src/backend/access/transam/slru.c +++ b/src/backend/access/transam/slru.c @@ -133,7 +133,7 @@ typedef enum static SlruErrorCause slru_errcause; static int slru_errno; - +static void SlruAdjustNSlots(int* nslots, int* banksize, int* bankoffset); static void SimpleLruZeroLSNs(SlruCtl ctl, int slotno); static void SimpleLruWaitIO(SlruCtl ctl, int slotno); static void SlruInternalWritePage(SlruCtl ctl, int slotno, SlruWriteAll fdata); @@ -147,6 +147,23 @@ static bool SlruScanDirCbDeleteCutoff(SlruCtl ctl, char *filename, int segpage, void *data); static void SlruInternalDeleteSegment(SlruCtl ctl, int segno); +static void SlruAdjustNSlots(int* nslots, int* banksize, int* bankoffset) +{ + *banksize = *nslots; + int nbanks = 1; + *bankoffset = 0; + while (*banksize > 15) + { + if ((*banksize & 1) != 0) + *banksize +=1; + *banksize /= 2; + nbanks *= 2; + *bankoffset += 1; + } + elog(DEBUG5, "nslots %d banksize %d nbanks %d ", *nslots, *banksize, nbanks); + *nslots = *banksize * nbanks; +} + /* * Initialization of shared memory */ @@ -155,6 +172,8 @@ Size SimpleLruShmemSize(int nslots, int nlsns) { Size sz; + int bankoffset, banksize; + SlruAdjustNSlots(&nslots, &banksize, &bankoffset); /* we assume nslots isn't so large as to risk overflow */ sz = MAXALIGN(sizeof(SlruSharedData)); @@ -189,6 +208,8 @@ SimpleLruInit(SlruCtl ctl, const char *name, int nslots, int nlsns, { SlruShared shared; bool found; + int bankoffset, banksize; + SlruAdjustNSlots(&nslots, &banksize, &bankoffset); shared = (SlruShared) ShmemInitStruct(name, SimpleLruShmemSize(nslots, nlsns), @@ -208,6 +229,9 @@ SimpleLruInit(SlruCtl ctl, const char *name, int nslots, int nlsns, shared->ControlLock = ctllock; shared->num_slots = nslots; + shared->bank_mask = (1 << bankoffset) - 1; + shared->bank_size = banksize; + shared->lsn_groups_per_page = nlsns; shared->cur_lru_count = 0; @@ -500,7 +524,9 @@ SimpleLruReadPage_ReadOnly(SlruCtl ctl, int pageno, TransactionId xid) LWLockAcquire(shared->ControlLock, LW_SHARED); /* See if page is already in a buffer */ - for (slotno = 0; slotno < shared->num_slots; slotno++) + int bankstart = (pageno & shared->bank_mask) * shared->bank_size; + int bankend = bankstart + shared->bank_size; + for (slotno = bankstart; slotno < bankend; slotno++) { if (shared->page_number[slotno] == pageno && shared->page_status[slotno] != SLRU_PAGE_EMPTY && @@ -1029,7 +1055,9 @@ SlruSelectLRUPage(SlruCtl ctl, int pageno) int best_invalid_page_number = 0; /* keep compiler quiet */ /* See if page already has a buffer assigned */ - for (slotno = 0; slotno < shared->num_slots; slotno++) + int bankstart = (pageno & shared->bank_mask) * shared->bank_size; + int bankend = bankstart + shared->bank_size; + for (slotno = bankstart; slotno < bankend; slotno++) { if (shared->page_number[slotno] == pageno && shared->page_status[slotno] != SLRU_PAGE_EMPTY) @@ -1064,7 +1092,7 @@ SlruSelectLRUPage(SlruCtl ctl, int pageno) * multiple pages with the same lru_count. */ cur_count = (shared->cur_lru_count)++; - for (slotno = 0; slotno < shared->num_slots; slotno++) + for (slotno = bankstart; slotno < bankend; slotno++) { int this_delta; int this_page_number; diff --git a/src/include/access/slru.h b/src/include/access/slru.h index 793c045f16..f4df54d3c1 100644 --- a/src/include/access/slru.h +++ b/src/include/access/slru.h @@ -61,6 +61,8 @@ typedef struct SlruSharedData /* Number of buffers managed by this SLRU structure */ int num_slots; + int bank_size; + int bank_mask; /* * Arrays holding info for each buffer slot. Page number is undefined -- 2.24.3 (Apple Git-128)