Skip to content

Commit ffd9b81

Browse files
committed
Fix SLRU bank selection code
The originally submitted code (using bit masking) was correct when the number of slots was restricted to be a power of two -- but that limitation was removed during development that led to commit 53c2a97, which made the bank selection code incorrect. This led to always using a smaller number of banks than available. Change said code to use integer modulo instead, which works correctly with an arbitrary number of banks. It's likely that we could improve on this to avoid runtime use of integer division. But with this change we're, at least, not wasting memory on unused banks, and more banks mean less contention, which is likely to have a much higher performance impact than a single instruction's latency. Author: Yura Sokolov <y.sokolov@postgrespro.ru> Reviewed-by: Andrey Borodin <x4mmm@yandex-team.ru> Discussion: https://postgr.es/m/9444dc46-ca47-43ed-9058-89c456316306@postgrespro.ru
1 parent faee318 commit ffd9b81

File tree

2 files changed

+6
-9
lines changed

2 files changed

+6
-9
lines changed

src/backend/access/transam/slru.c

+3-3
Original file line numberDiff line numberDiff line change
@@ -343,7 +343,7 @@ SimpleLruInit(SlruCtl ctl, const char *name, int nslots, int nlsns,
343343
ctl->shared = shared;
344344
ctl->sync_handler = sync_handler;
345345
ctl->long_segment_names = long_segment_names;
346-
ctl->bank_mask = (nslots / SLRU_BANK_SIZE) - 1;
346+
ctl->nbanks = nbanks;
347347
strlcpy(ctl->Dir, subdir, sizeof(ctl->Dir));
348348
}
349349

@@ -606,7 +606,7 @@ SimpleLruReadPage_ReadOnly(SlruCtl ctl, int64 pageno, TransactionId xid)
606606
{
607607
SlruShared shared = ctl->shared;
608608
LWLock *banklock = SimpleLruGetBankLock(ctl, pageno);
609-
int bankno = pageno & ctl->bank_mask;
609+
int bankno = pageno % ctl->nbanks;
610610
int bankstart = bankno * SLRU_BANK_SIZE;
611611
int bankend = bankstart + SLRU_BANK_SIZE;
612612

@@ -1177,7 +1177,7 @@ SlruSelectLRUPage(SlruCtl ctl, int64 pageno)
11771177
int bestinvalidslot = 0; /* keep compiler quiet */
11781178
int best_invalid_delta = -1;
11791179
int64 best_invalid_page_number = 0; /* keep compiler quiet */
1180-
int bankno = pageno & ctl->bank_mask;
1180+
int bankno = pageno % ctl->nbanks;
11811181
int bankstart = bankno * SLRU_BANK_SIZE;
11821182
int bankend = bankstart + SLRU_BANK_SIZE;
11831183

src/include/access/slru.h

+3-6
Original file line numberDiff line numberDiff line change
@@ -128,10 +128,8 @@ typedef struct SlruCtlData
128128
{
129129
SlruShared shared;
130130

131-
/*
132-
* Bitmask to determine bank number from page number.
133-
*/
134-
bits16 bank_mask;
131+
/* Number of banks in this SLRU. */
132+
uint16 nbanks;
135133

136134
/*
137135
* If true, use long segment file names. Otherwise, use short file names.
@@ -163,7 +161,6 @@ typedef struct SlruCtlData
163161
* it's always the same, it doesn't need to be in shared memory.
164162
*/
165163
char Dir[64];
166-
167164
} SlruCtlData;
168165

169166
typedef SlruCtlData *SlruCtl;
@@ -179,7 +176,7 @@ SimpleLruGetBankLock(SlruCtl ctl, int64 pageno)
179176
{
180177
int bankno;
181178

182-
bankno = pageno & ctl->bank_mask;
179+
bankno = pageno % ctl->nbanks;
183180
return &(ctl->shared->bank_locks[bankno].lock);
184181
}
185182

0 commit comments

Comments
 (0)