public inbox for [email protected]  
help / color / mirror / Atom feed
[PATCH v7 1/1] pg_lfind32(): add "overlap" code for remaining elements
4+ messages / 2 participants
[nested] [flat]

* [PATCH v7 1/1] pg_lfind32(): add "overlap" code for remaining elements
@ 2024-03-20 19:20 Nathan Bossart <[email protected]>
  0 siblings, 0 replies; 4+ messages in thread

From: Nathan Bossart @ 2024-03-20 19:20 UTC (permalink / raw)

---
 src/include/port/pg_lfind.h | 105 ++++++++++++++++++++++++------------
 1 file changed, 72 insertions(+), 33 deletions(-)

diff --git a/src/include/port/pg_lfind.h b/src/include/port/pg_lfind.h
index b8dfa66eef..5830cc7cb3 100644
--- a/src/include/port/pg_lfind.h
+++ b/src/include/port/pg_lfind.h
@@ -80,6 +80,51 @@ pg_lfind8_le(uint8 key, uint8 *base, uint32 nelem)
 	return false;
 }
 
+#ifndef USE_NO_SIMD
+/*
+ * pg_lfind32_helper
+ *
+ * Searches one 4-register-block of integers.  The caller is responsible for
+ * ensuring that there are at least 4-registers-worth of integers remaining.
+ */
+static inline bool
+pg_lfind32_helper(const Vector32 keys, uint32 *base)
+{
+	const uint32 nelem_per_vector = sizeof(Vector32) / sizeof(uint32);
+	Vector32	vals1,
+				vals2,
+				vals3,
+				vals4,
+				result1,
+				result2,
+				result3,
+				result4,
+				tmp1,
+				tmp2,
+				result;
+
+	/* load the next block into 4 registers */
+	vector32_load(&vals1, base);
+	vector32_load(&vals2, &base[nelem_per_vector]);
+	vector32_load(&vals3, &base[nelem_per_vector * 2]);
+	vector32_load(&vals4, &base[nelem_per_vector * 3]);
+
+	/* compare each value to the key */
+	result1 = vector32_eq(keys, vals1);
+	result2 = vector32_eq(keys, vals2);
+	result3 = vector32_eq(keys, vals3);
+	result4 = vector32_eq(keys, vals4);
+
+	/* combine the results into a single variable */
+	tmp1 = vector32_or(result1, result2);
+	tmp2 = vector32_or(result3, result4);
+	result = vector32_or(tmp1, tmp2);
+
+	/* return whether there was a match */
+	return vector32_is_highbit_set(result);
+}
+#endif							/* ! USE_NO_SIMD */
+
 /*
  * pg_lfind32
  *
@@ -119,46 +164,40 @@ pg_lfind32(uint32 key, uint32 *base, uint32 nelem)
 	}
 #endif
 
-	for (i = 0; i < tail_idx; i += nelem_per_iteration)
+	/*
+	 * If there aren't enough elements for the SIMD code, jump to the standard
+	 * one-by-one linear search code.
+	 */
+	if (nelem <= nelem_per_iteration)
+		goto one_by_one;
+
+	/*
+	 * Process as many elements as possible with a block of 4 registers.
+	 */
+	do
 	{
-		Vector32	vals1,
-					vals2,
-					vals3,
-					vals4,
-					result1,
-					result2,
-					result3,
-					result4,
-					tmp1,
-					tmp2,
-					result;
-
-		/* load the next block into 4 registers */
-		vector32_load(&vals1, &base[i]);
-		vector32_load(&vals2, &base[i + nelem_per_vector]);
-		vector32_load(&vals3, &base[i + nelem_per_vector * 2]);
-		vector32_load(&vals4, &base[i + nelem_per_vector * 3]);
-
-		/* compare each value to the key */
-		result1 = vector32_eq(keys, vals1);
-		result2 = vector32_eq(keys, vals2);
-		result3 = vector32_eq(keys, vals3);
-		result4 = vector32_eq(keys, vals4);
-
-		/* combine the results into a single variable */
-		tmp1 = vector32_or(result1, result2);
-		tmp2 = vector32_or(result3, result4);
-		result = vector32_or(tmp1, tmp2);
-
-		/* see if there was a match */
-		if (vector32_is_highbit_set(result))
+		if (pg_lfind32_helper(keys, &base[i]))
 		{
 			Assert(assert_result == true);
 			return true;
 		}
-	}
+
+		i += nelem_per_iteration;
+
+	} while (i < tail_idx);
+
+	/*
+	 * Process the last 'nelem_per_iteration' elements in the array with a
+	 * 4-register block.  This will cause us to check some of the elements
+	 * more than once, but that won't affect correctness, and testing has
+	 * demonstrated that this helps more cases than it harms.
+	 */
+	Assert(assert_result == pg_lfind32_helper(keys, &base[nelem - nelem_per_iteration]));
+	return pg_lfind32_helper(keys, &base[nelem - nelem_per_iteration]);
+
 #endif							/* ! USE_NO_SIMD */
 
+one_by_one:
 	/* Process the remaining elements one at a time. */
 	for (; i < nelem; i++)
 	{
-- 
2.25.1


--sm4nu43k4a2Rpi4c--





^ permalink  raw  reply  [nested|flat] 4+ messages in thread

* Re: Fix port/pg_iovec.h building extensions on x86_64-darwin
@ 2024-11-08 20:00 Nathan Bossart <[email protected]>
  2024-11-08 21:20 ` Re: Fix port/pg_iovec.h building extensions on x86_64-darwin Nathan Bossart <[email protected]>
  0 siblings, 1 reply; 4+ messages in thread

From: Nathan Bossart @ 2024-11-08 20:00 UTC (permalink / raw)
  To: Wolfgang Walther <[email protected]>; +Cc: [email protected]

On Fri, Nov 08, 2024 at 08:08:06PM +0100, Wolfgang Walther wrote:
> @@ -68,7 +68,7 @@ pg_preadv(int fd, const struct iovec *iov, int iovcnt, off_t offset)
>  		}
>  		sum += part;
>  		offset += part;
> -		if (part < iov[i].iov_len)
> +		if ((size_t) part < iov[i].iov_len)
>  			return sum;
>  	}
>  	return sum;
> @@ -107,7 +107,7 @@ pg_pwritev(int fd, const struct iovec *iov, int iovcnt, off_t offset)
>  		}
>  		sum += part;
>  		offset += part;
> -		if (part < iov[i].iov_len)
> +		if ((size_t) part < iov[i].iov_len)
>  			return sum;
>  	}
>  	return sum;

This looks correct to me.  At this point in the code, we know that part >=
0, so casting it to an unsigned long ought to be okay.

-- 
nathan






^ permalink  raw  reply  [nested|flat] 4+ messages in thread

* Re: Fix port/pg_iovec.h building extensions on x86_64-darwin
  2024-11-08 20:00 Re: Fix port/pg_iovec.h building extensions on x86_64-darwin Nathan Bossart <[email protected]>
@ 2024-11-08 21:20 ` Nathan Bossart <[email protected]>
  2024-11-08 22:15   ` Re: Fix port/pg_iovec.h building extensions on x86_64-darwin Nathan Bossart <[email protected]>
  0 siblings, 1 reply; 4+ messages in thread

From: Nathan Bossart @ 2024-11-08 21:20 UTC (permalink / raw)
  To: Wolfgang Walther <[email protected]>; +Cc: [email protected]

Here is a new version of the patch with an updated commit message.  The
cfbot results [0] look good, so I plan to commit this one shortly unless
someone objects.

[0] https://cirrus-ci.com/build/6599760059039744

-- 
nathan

From 5e7156defd3a169323e2bc354c3a3c4cb232fa67 Mon Sep 17 00:00:00 2001
From: Nathan Bossart <[email protected]>
Date: Fri, 8 Nov 2024 15:16:41 -0600
Subject: [PATCH v2 1/1] Fix sign-compare warnings in pg_iovec.h.

The code in question (pg_preadv() and pg_pwritev()) has been around
for a while, but commit 15c9ac3629 moved it to a header file.  If
third-party code that includes this header file is built with
-Wsign-compare on a system without preadv() or pwritev(), warnings
ensue.  This commit fixes said warnings by casting the result of
pg_pread()/pg_pwrite() to size_t, which should be safe because we
have already checked for a negative value.

Author: Wolfgang Walther
Discussion: https://postgr.es/m/16989737-1aa8-48fd-8dfe-b7ada06509ab%40technowledgy.de
Backpatch-through: 17
---
 src/include/port/pg_iovec.h | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/src/include/port/pg_iovec.h b/src/include/port/pg_iovec.h
index 7255c1bd91..e5fe677b37 100644
--- a/src/include/port/pg_iovec.h
+++ b/src/include/port/pg_iovec.h
@@ -68,7 +68,7 @@ pg_preadv(int fd, const struct iovec *iov, int iovcnt, off_t offset)
 		}
 		sum += part;
 		offset += part;
-		if (part < iov[i].iov_len)
+		if ((size_t) part < iov[i].iov_len)
 			return sum;
 	}
 	return sum;
@@ -107,7 +107,7 @@ pg_pwritev(int fd, const struct iovec *iov, int iovcnt, off_t offset)
 		}
 		sum += part;
 		offset += part;
-		if (part < iov[i].iov_len)
+		if ((size_t) part < iov[i].iov_len)
 			return sum;
 	}
 	return sum;
-- 
2.39.5 (Apple Git-154)



Attachments:

  [text/plain] v2-0001-Fix-sign-compare-warnings-in-pg_iovec.h.patch (1.5K, ../../Zy6AgDqqZTlTD3e_@nathan/2-v2-0001-Fix-sign-compare-warnings-in-pg_iovec.h.patch)
  download | inline diff:
From 5e7156defd3a169323e2bc354c3a3c4cb232fa67 Mon Sep 17 00:00:00 2001
From: Nathan Bossart <[email protected]>
Date: Fri, 8 Nov 2024 15:16:41 -0600
Subject: [PATCH v2 1/1] Fix sign-compare warnings in pg_iovec.h.

The code in question (pg_preadv() and pg_pwritev()) has been around
for a while, but commit 15c9ac3629 moved it to a header file.  If
third-party code that includes this header file is built with
-Wsign-compare on a system without preadv() or pwritev(), warnings
ensue.  This commit fixes said warnings by casting the result of
pg_pread()/pg_pwrite() to size_t, which should be safe because we
have already checked for a negative value.

Author: Wolfgang Walther
Discussion: https://postgr.es/m/16989737-1aa8-48fd-8dfe-b7ada06509ab%40technowledgy.de
Backpatch-through: 17
---
 src/include/port/pg_iovec.h | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/src/include/port/pg_iovec.h b/src/include/port/pg_iovec.h
index 7255c1bd91..e5fe677b37 100644
--- a/src/include/port/pg_iovec.h
+++ b/src/include/port/pg_iovec.h
@@ -68,7 +68,7 @@ pg_preadv(int fd, const struct iovec *iov, int iovcnt, off_t offset)
 		}
 		sum += part;
 		offset += part;
-		if (part < iov[i].iov_len)
+		if ((size_t) part < iov[i].iov_len)
 			return sum;
 	}
 	return sum;
@@ -107,7 +107,7 @@ pg_pwritev(int fd, const struct iovec *iov, int iovcnt, off_t offset)
 		}
 		sum += part;
 		offset += part;
-		if (part < iov[i].iov_len)
+		if ((size_t) part < iov[i].iov_len)
 			return sum;
 	}
 	return sum;
-- 
2.39.5 (Apple Git-154)



^ permalink  raw  reply  [nested|flat] 4+ messages in thread

* Re: Fix port/pg_iovec.h building extensions on x86_64-darwin
  2024-11-08 20:00 Re: Fix port/pg_iovec.h building extensions on x86_64-darwin Nathan Bossart <[email protected]>
  2024-11-08 21:20 ` Re: Fix port/pg_iovec.h building extensions on x86_64-darwin Nathan Bossart <[email protected]>
@ 2024-11-08 22:15   ` Nathan Bossart <[email protected]>
  0 siblings, 0 replies; 4+ messages in thread

From: Nathan Bossart @ 2024-11-08 22:15 UTC (permalink / raw)
  To: Wolfgang Walther <[email protected]>; +Cc: [email protected]

On Fri, Nov 08, 2024 at 03:20:00PM -0600, Nathan Bossart wrote:
> Here is a new version of the patch with an updated commit message.  The
> cfbot results [0] look good, so I plan to commit this one shortly unless
> someone objects.

Committed.

-- 
nathan






^ permalink  raw  reply  [nested|flat] 4+ messages in thread


end of thread, other threads:[~2024-11-08 22:15 UTC | newest]

Thread overview: 4+ messages (download: mbox mbox.gz follow: Atom feed)
-- links below jump to the message on this page --
2024-03-20 19:20 [PATCH v7 1/1] pg_lfind32(): add "overlap" code for remaining elements Nathan Bossart <[email protected]>
2024-11-08 20:00 Re: Fix port/pg_iovec.h building extensions on x86_64-darwin Nathan Bossart <[email protected]>
2024-11-08 21:20 ` Re: Fix port/pg_iovec.h building extensions on x86_64-darwin Nathan Bossart <[email protected]>
2024-11-08 22:15   ` Re: Fix port/pg_iovec.h building extensions on x86_64-darwin Nathan Bossart <[email protected]>

This inbox is served by agora; see mirroring instructions
for how to clone and mirror all data and code used for this inbox