Improve conditional compilation for direct I/O alignment checks

Started by Junwang Zhaoover 1 year ago3 messages
#1Junwang Zhao
zhjwpku@gmail.com
1 attachment(s)

This patch refactors the alignment checks for direct I/O to preprocess phase,
thereby reducing some CPU cycles.

--
Regards
Junwang Zhao

Attachments:

0001-Improve-conditional-compilation-for-direct-I-O-align.patchapplication/octet-stream; name=0001-Improve-conditional-compilation-for-direct-I-O-align.patchDownload
From 0d5b5264f0730c168b40934a1a721dc848fe0da0 Mon Sep 17 00:00:00 2001
From: Zhao Junwang <zhjwpku@gmail.com>
Date: Sun, 26 May 2024 15:06:58 +0800
Subject: [PATCH] Improve conditional compilation for direct I/O alignment
 checks

Signed-off-by: Zhao Junwang <zhjwpku@gmail.com>
---
 src/backend/storage/smgr/md.c | 13 +++++++------
 1 file changed, 7 insertions(+), 6 deletions(-)

diff --git a/src/backend/storage/smgr/md.c b/src/backend/storage/smgr/md.c
index bf0f3ca76d..fa789045a1 100644
--- a/src/backend/storage/smgr/md.c
+++ b/src/backend/storage/smgr/md.c
@@ -465,9 +465,9 @@ mdextend(SMgrRelation reln, ForkNumber forknum, BlockNumber blocknum,
 	MdfdVec    *v;
 
 	/* If this build supports direct I/O, the buffer must be I/O aligned. */
-	if (PG_O_DIRECT != 0 && PG_IO_ALIGN_SIZE <= BLCKSZ)
-		Assert((uintptr_t) buffer == TYPEALIGN(PG_IO_ALIGN_SIZE, buffer));
-
+#if PG_O_DIRECT != 0 && PG_IO_ALIGN_SIZE <= BLCKSZ
+	Assert((uintptr_t) buffer == TYPEALIGN(PG_IO_ALIGN_SIZE, buffer));
+#endif
 	/* This assert is too expensive to have on normally ... */
 #ifdef CHECK_WRITE_VS_EXTEND
 	Assert(blocknum >= mdnblocks(reln, forknum));
@@ -767,12 +767,13 @@ buffers_to_iovec(struct iovec *iov, void **buffers, int nblocks)
 	Assert(nblocks >= 1);
 
 	/* If this build supports direct I/O, buffers must be I/O aligned. */
+#if PG_O_DIRECT != 0 && PG_IO_ALIGN_SIZE <= BLCKSZ
 	for (int i = 0; i < nblocks; ++i)
 	{
-		if (PG_O_DIRECT != 0 && PG_IO_ALIGN_SIZE <= BLCKSZ)
-			Assert((uintptr_t) buffers[i] ==
-				   TYPEALIGN(PG_IO_ALIGN_SIZE, buffers[i]));
+		Assert((uintptr_t) buffers[i] ==
+			   TYPEALIGN(PG_IO_ALIGN_SIZE, buffers[i]));
 	}
+#endif
 
 	/* Start the first iovec off with the first buffer. */
 	iovp = &iov[0];
-- 
2.41.0

#2Junwang Zhao
zhjwpku@gmail.com
In reply to: Junwang Zhao (#1)
1 attachment(s)
Re: Improve conditional compilation for direct I/O alignment checks

On Sun, May 26, 2024 at 3:16 PM Junwang Zhao <zhjwpku@gmail.com> wrote:

This patch refactors the alignment checks for direct I/O to preprocess phase,
thereby reducing some CPU cycles.

--
Regards
Junwang Zhao

Patch v2 with some additional minor polishment of the comments in `mdwriteback`.

--
Regards
Junwang Zhao

Attachments:

v2-0001-Improve-conditional-compilation-for-direct-I-O-al.patchapplication/octet-stream; name=v2-0001-Improve-conditional-compilation-for-direct-I-O-al.patchDownload
From dcad88240c3b4c7a922f013b6b384962594296ea Mon Sep 17 00:00:00 2001
From: Zhao Junwang <zhjwpku@gmail.com>
Date: Sun, 26 May 2024 15:06:58 +0800
Subject: [PATCH v2] Improve conditional compilation for direct I/O alignment
 checks

Signed-off-by: Zhao Junwang <zhjwpku@gmail.com>
---
 src/backend/storage/smgr/md.c | 18 +++++++++---------
 1 file changed, 9 insertions(+), 9 deletions(-)

diff --git a/src/backend/storage/smgr/md.c b/src/backend/storage/smgr/md.c
index bf0f3ca76d..70637d47c1 100644
--- a/src/backend/storage/smgr/md.c
+++ b/src/backend/storage/smgr/md.c
@@ -465,9 +465,9 @@ mdextend(SMgrRelation reln, ForkNumber forknum, BlockNumber blocknum,
 	MdfdVec    *v;
 
 	/* If this build supports direct I/O, the buffer must be I/O aligned. */
-	if (PG_O_DIRECT != 0 && PG_IO_ALIGN_SIZE <= BLCKSZ)
-		Assert((uintptr_t) buffer == TYPEALIGN(PG_IO_ALIGN_SIZE, buffer));
-
+#if PG_O_DIRECT != 0 && PG_IO_ALIGN_SIZE <= BLCKSZ
+	Assert((uintptr_t) buffer == TYPEALIGN(PG_IO_ALIGN_SIZE, buffer));
+#endif
 	/* This assert is too expensive to have on normally ... */
 #ifdef CHECK_WRITE_VS_EXTEND
 	Assert(blocknum >= mdnblocks(reln, forknum));
@@ -767,12 +767,13 @@ buffers_to_iovec(struct iovec *iov, void **buffers, int nblocks)
 	Assert(nblocks >= 1);
 
 	/* If this build supports direct I/O, buffers must be I/O aligned. */
+#if PG_O_DIRECT != 0 && PG_IO_ALIGN_SIZE <= BLCKSZ
 	for (int i = 0; i < nblocks; ++i)
 	{
-		if (PG_O_DIRECT != 0 && PG_IO_ALIGN_SIZE <= BLCKSZ)
-			Assert((uintptr_t) buffers[i] ==
-				   TYPEALIGN(PG_IO_ALIGN_SIZE, buffers[i]));
+		Assert((uintptr_t) buffers[i] ==
+			   TYPEALIGN(PG_IO_ALIGN_SIZE, buffers[i]));
 	}
+#endif
 
 	/* Start the first iovec off with the first buffer. */
 	iovp = &iov[0];
@@ -1057,10 +1058,8 @@ mdwriteback(SMgrRelation reln, ForkNumber forknum,
 		if (!v)
 			return;
 
-		/* compute offset inside the current segment */
-		segnum_start = blocknum / RELSEG_SIZE;
-
 		/* compute number of desired writes within the current segment */
+		segnum_start = blocknum / RELSEG_SIZE;
 		segnum_end = (blocknum + nblocks - 1) / RELSEG_SIZE;
 		if (segnum_start != segnum_end)
 			nflush = RELSEG_SIZE - (blocknum % ((BlockNumber) RELSEG_SIZE));
@@ -1068,6 +1067,7 @@ mdwriteback(SMgrRelation reln, ForkNumber forknum,
 		Assert(nflush >= 1);
 		Assert(nflush <= nblocks);
 
+		/* compute offset inside the current segment */
 		seekpos = (off_t) BLCKSZ * (blocknum % ((BlockNumber) RELSEG_SIZE));
 
 		FileWriteback(v->mdfd_vfd, seekpos, (off_t) BLCKSZ * nflush, WAIT_EVENT_DATA_FILE_FLUSH);
-- 
2.41.0

#3Peter Eisentraut
peter@eisentraut.org
In reply to: Junwang Zhao (#1)
Re: Improve conditional compilation for direct I/O alignment checks

On 26.05.24 09:16, Junwang Zhao wrote:

This patch refactors the alignment checks for direct I/O to preprocess phase,
thereby reducing some CPU cycles.

This patch replaces for example

if (PG_O_DIRECT != 0 && PG_IO_ALIGN_SIZE <= BLCKSZ)
Assert((uintptr_t) buffer == TYPEALIGN(PG_IO_ALIGN_SIZE, buffer));

with

#if PG_O_DIRECT != 0 && PG_IO_ALIGN_SIZE <= BLCKSZ
Assert((uintptr_t) buffer == TYPEALIGN(PG_IO_ALIGN_SIZE, buffer));
#endif

You appear to be assuming that this saves some CPU cycles. But this is
not the case. The compiler will remove the unused code in the first
case because all the constants in the if expression are known at
compile-time.