Improve conditional compilation for direct I/O alignment checks
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
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
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.