aboutsummaryrefslogtreecommitdiff
path: root/src/backend/storage/buffer/bufmgr.c
diff options
context:
space:
mode:
authorThomas Munro <tmunro@postgresql.org>2021-03-12 23:56:02 +1300
committerThomas Munro <tmunro@postgresql.org>2021-03-12 23:56:02 +1300
commit1b88b8908e751271933c076234fa085cda251421 (patch)
tree1c915dc03ca34d4e91c3bc88a1161eb5e820b33e /src/backend/storage/buffer/bufmgr.c
parent519e4c9ee21a656879123f4843f1d8d60cb71536 (diff)
downloadpostgresql-1b88b8908e751271933c076234fa085cda251421.tar.gz
postgresql-1b88b8908e751271933c076234fa085cda251421.zip
Specialize checkpointer sort functions.
When sorting a potentially large number of dirty buffers, the checkpointer can benefit from a faster sort routine. One reported improvement on a large buffer pool system was 1.4s -> 0.6s. Reviewed-by: Andres Freund <andres@anarazel.de> Discussion: https://postgr.es/m/CA%2BhUKGJ2-eaDqAum5bxhpMNhvuJmRDZxB_Tow0n-gse%2BHG0Yig%40mail.gmail.com
Diffstat (limited to 'src/backend/storage/buffer/bufmgr.c')
-rw-r--r--src/backend/storage/buffer/bufmgr.c37
1 files changed, 22 insertions, 15 deletions
diff --git a/src/backend/storage/buffer/bufmgr.c b/src/backend/storage/buffer/bufmgr.c
index e4d257e1c52..852138f9c93 100644
--- a/src/backend/storage/buffer/bufmgr.c
+++ b/src/backend/storage/buffer/bufmgr.c
@@ -488,8 +488,8 @@ static void FindAndDropRelFileNodeBuffers(RelFileNode rnode,
static void AtProcExit_Buffers(int code, Datum arg);
static void CheckForBufferLeaks(void);
static int rnode_comparator(const void *p1, const void *p2);
-static int buffertag_comparator(const void *p1, const void *p2);
-static int ckpt_buforder_comparator(const void *pa, const void *pb);
+static inline int buffertag_comparator(const BufferTag *a, const BufferTag *b);
+static inline int ckpt_buforder_comparator(const CkptSortItem *a, const CkptSortItem *b);
static int ts_ckpt_progress_comparator(Datum a, Datum b, void *arg);
@@ -1831,6 +1831,13 @@ UnpinBuffer(BufferDesc *buf, bool fixOwner)
}
}
+#define ST_SORT sort_checkpoint_bufferids
+#define ST_ELEMENT_TYPE CkptSortItem
+#define ST_COMPARE(a, b) ckpt_buforder_comparator(a, b)
+#define ST_SCOPE static
+#define ST_DEFINE
+#include <lib/sort_template.h>
+
/*
* BufferSync -- Write out all dirty buffers in the pool.
*
@@ -1931,8 +1938,7 @@ BufferSync(int flags)
* end up writing to the tablespaces one-by-one; possibly overloading the
* underlying system.
*/
- qsort(CkptBufferIds, num_to_scan, sizeof(CkptSortItem),
- ckpt_buforder_comparator);
+ sort_checkpoint_bufferids(CkptBufferIds, num_to_scan);
num_spaces = 0;
@@ -4567,11 +4573,9 @@ WaitBufHdrUnlocked(BufferDesc *buf)
/*
* BufferTag comparator.
*/
-static int
-buffertag_comparator(const void *a, const void *b)
+static inline int
+buffertag_comparator(const BufferTag *ba, const BufferTag *bb)
{
- const BufferTag *ba = (const BufferTag *) a;
- const BufferTag *bb = (const BufferTag *) b;
int ret;
ret = rnode_comparator(&ba->rnode, &bb->rnode);
@@ -4598,12 +4602,9 @@ buffertag_comparator(const void *a, const void *b)
* It is important that tablespaces are compared first, the logic balancing
* writes between tablespaces relies on it.
*/
-static int
-ckpt_buforder_comparator(const void *pa, const void *pb)
+static inline int
+ckpt_buforder_comparator(const CkptSortItem *a, const CkptSortItem *b)
{
- const CkptSortItem *a = (const CkptSortItem *) pa;
- const CkptSortItem *b = (const CkptSortItem *) pb;
-
/* compare tablespace */
if (a->tsId < b->tsId)
return -1;
@@ -4694,6 +4695,13 @@ ScheduleBufferTagForWriteback(WritebackContext *context, BufferTag *tag)
IssuePendingWritebacks(context);
}
+#define ST_SORT sort_pending_writebacks
+#define ST_ELEMENT_TYPE PendingWriteback
+#define ST_COMPARE(a, b) buffertag_comparator(&a->tag, &b->tag)
+#define ST_SCOPE static
+#define ST_DEFINE
+#include <lib/sort_template.h>
+
/*
* Issue all pending writeback requests, previously scheduled with
* ScheduleBufferTagForWriteback, to the OS.
@@ -4713,8 +4721,7 @@ IssuePendingWritebacks(WritebackContext *context)
* Executing the writes in-order can make them a lot faster, and allows to
* merge writeback requests to consecutive blocks into larger writebacks.
*/
- qsort(&context->pending_writebacks, context->nr_pending,
- sizeof(PendingWriteback), buffertag_comparator);
+ sort_pending_writebacks(context->pending_writebacks, context->nr_pending);
/*
* Coalesce neighbouring writes, but nothing else. For that we iterate