| From: | David Rowley <dgrowleyml(at)gmail(dot)com> |
|---|---|
| To: | Zsolt Parragi <zsolt(dot)parragi(at)percona(dot)com> |
| Cc: | Andres Freund <andres(at)anarazel(dot)de>, John Naylor <johncnaylorls(at)gmail(dot)com>, Chao Li <li(dot)evan(dot)chao(at)gmail(dot)com>, PostgreSQL Developers <pgsql-hackers(at)lists(dot)postgresql(dot)org> |
| Subject: | Re: More speedups for tuple deformation |
| Date: | 2026-02-25 00:39:48 |
| Message-ID: | CAApHDvot9-P3790zcqVbaumyD2TqWg=_=PUe9OsN5+-wXQRPWw@mail.gmail.com |
| Views: | Whole Thread | Raw Message | Download mbox | Resend email |
| Thread: | |
| Lists: | pgsql-hackers |
Thanks for having a look at this.
On Wed, 25 Feb 2026 at 07:33, Zsolt Parragi <zsolt(dot)parragi(at)percona(dot)com> wrote:
> + * We expect that 'bits' contains at least one 0 bit somewhere in the mask,
> + * not necessarily < natts.
> + */
>
> Is this precondition really enough?
>
> Let's say we have 20 attributes, only attribute 20 is NULL
> Caller requests natts=8
>
> That sets lastByte = 1, loop only checks bits[0], which is 0xFF, exits
> with bytenum=1, bits[1] is also 0xFF
>
> Then we execute
>
> + res += pg_rightmost_one_pos32(~bits[bytenum]);
>
> where ~0xFF = 0
I think this works ok in v9, but in v10 I've added a cast so that line becomes:
res += pg_rightmost_one_pos32(~((uint32) bits[bytenum]));
For the case you describe, 0xFF becomes 0xFFFFFF00 and
pg_rightmost_one_pos32() returns 8, the lowest bit of the 2nd byte.
> + /* convert the lower 4 bits of null bitmap word into 32 bit int */
> + isnull_8 = (nullbyte & 0xf) * SPREAD_BITS_MULTIPLIER_32;
> +
> + /*
> + * convert the upper 4 bits of null bitmap word into 32 bit int, shift
> + * into the upper 32 bit
> + */
> + isnull_8 |= ((uint64) ((nullbyte >> 4) * SPREAD_BITS_MULTIPLIER_32)) << 32;
> +
> + /* mask out all other bits apart from the lowest bit of each byte */
> + isnull_8 &= UINT64CONST(0x0101010101010101);
> + memcpy(isnull, &isnull_8, sizeof(uint64));
>
>
> Won't this mix up column numbers on big-endian systems?
Yes, I believe you're right. I've added the following before the memcpy().
#ifdef WORDS_BIGENDIAN
/*
* Fix byte order on big-endian machines before copying to the array.
*/
isnull_8 = pg_bswap64(isnull_8);
#endif
>
> Subject: [PATCH v9 1/5] Introduce deform_bench test module
>
> For benchmaring tuple deformation.
> ---
>
> Typo: should be benchmarking
Fixed.
> + * firstNonGuaranteedAttr stores the index to info the compact_attrs array for
>
> to info should be "into"?
Also fixed.
I've attached a revised set of patches.
David
| Attachment | Content-Type | Size |
|---|---|---|
| v10-0001-Introduce-deform_bench-test-module.patch | text/plain | 7.3 KB |
| v10-0002-Add-empty-TupleDescFinalize-function.patch | text/plain | 29.0 KB |
| v10-0003-Optimize-tuple-deformation.patch | text/plain | 60.4 KB |
| v10-0004-Allow-sibling-call-optimization-in-slot_getsomea.patch | text/plain | 8.5 KB |
| v10-0005-Reduce-size-of-CompactAttribute-struct-to-8-byte.patch | text/plain | 5.5 KB |
| From | Date | Subject | |
|---|---|---|---|
| Next Message | David Rowley | 2026-02-25 00:59:53 | Re: More speedups for tuple deformation |
| Previous Message | Gyan Sreejith | 2026-02-24 23:55:08 | Re: [Proposal] Adding Log File Capability to pg_createsubscriber |