Re: Make tuple deformation faster
David Rowley <dgrowleyml@gmail.com>
From: David Rowley <dgrowleyml@gmail.com>
To: Andres Freund <andres@anarazel.de>
Cc: Jeff Davis <pgsql@j-davis.com>, James Hunter <james.hunter.pg@gmail.com>, Matthias van de Meent <boekewurm+postgres@gmail.com>, PostgreSQL Developers <pgsql-hackers@lists.postgresql.org>
Date: 2025-03-10T03:24:14Z
Lists: pgsql-hackers
Attachments
- slot_deform_heap_tuple.zip (application/x-zip-compressed)
On Thu, 6 Mar 2025 at 10:17, Andres Freund <andres@anarazel.de> wrote: > FWIW, I am fairly certain that I looked at this at an earlier state of the > patch, and at least for me the issue wasn't that it was inherently slower to > use the bitmask, but that it was hard to convince the compiler not generate > worse code. > > IIRC the compiler generated more complicated address gathering instructions > which are slower on some older microarchitectures, but this is a vague memory. I've been reading GCC's assembly output with -fverbose-asm. I find it quite hard to follow as the changes between the 16-byte and 8-byte CompactAttribute versions are vast (see attached). A few interesting things jump out. e.g, in master: # execTuples.c:1080: thisatt->attcacheoff = *offp; .loc 1 1080 26 is_stmt 0 view .LVU1468 movl %ebp, (%rax) # off, MEM[(int *)_22] whereas with the 8-byte version, I see: # execTuples.c:1080: thisatt->attcacheoff = *offp; .loc 1 1080 26 is_stmt 0 view .LVU1484 movl %ebp, 24(%rax) # off, MEM[(int *)_358 + 24B] You can see the MOVL in the 8-byte version should amount to an additional micro op to add 24 to RAX before the dereference. One interesting thing to note about having CompactAttribute in its 8-byte form is that the compiler is tempted into sharing a register with the tts_values array before Datum is also 8-bytes. Note the difference in [1] between the two left compiler outputs and the right-hand one. You can see RCX is dedicated for addressing CompactAttribute in the right window, but RAX is used for both arrays in the left two. I don't 100% know for sure that's the reason for the slowness with the full version but it does seem from the fragment I posted just above that RAX does need 24 bytes added in the 8 bytes version but not in the 16 byte version, so RAX is certainly not dedicated and ready pointing to attcacheoff at that point. Jeff, I'm not sure if I understand this well enough to write a meaningful comment to explain why we don't use bitflags. With my current knowledge level on this, it's a bit hand-wavy at best. Are you content with this, or do you want to see something written into the header comment for CompactAttribute in the code? David [1] https://godbolt.org/z/7hWvqdW6E
Commits
Same data as JSON:
GET /api/v1/messages/:b64id/commits
the thread's linked commits as JSON, with link sources.
API reference →
-
Fix possible Assert failure in verify_compact_attribute()
- 33b06a20016d 18.0 landed
-
Speedup tuple deformation with additional function inlining
- 58a359e585d0 18.0 landed
-
Fix race condition in TupleDescCompactAttr assert code
- 6f3820f37aba 18.0 landed
-
Optimize alignment calculations in tuple form/deform
- db448ce5ad36 18.0 landed
-
Remove pg_attribute.attcacheoff column
- 02a8d0c45253 18.0 landed
-
Introduce CompactAttribute array in TupleDesc, take 2
- 5983a4cffc31 18.0 landed
-
Introduce CompactAttribute array in TupleDesc
- d28dff3f6cd6 18.0 landed
-
Use TupleDescAttr macro consistently
- 65b71dec2d57 18.0 landed