On Mon, 1 Jul 2024 at 12:49, David Rowley <dgrowle...@gmail.com> wrote: > > On Mon, 1 Jul 2024 at 22:07, Matthias van de Meent > <boekewurm+postg...@gmail.com> wrote: > > One thing I'm slightly concerned about is that this allocates another > > 8 bytes for each attribute in the tuple descriptor. While that's not a > > lot when compared with the ->attrs array, it's still quite a lot when > > we might not care at all about this data; e.g. in temporary tuple > > descriptors during execution, in intermediate planner nodes. > > I've not done it in the patch, but one way to get some of that back is > to ditch pg_attribute.attcacheoff. There's no need for it after this > patch. That's only 4 out of 8 bytes, however.
FormData_pg_attribute as a C struct has 4-byte alignment; AFAIK it doesn't have any fields that require 8-byte alignment? Only on 64-bit systems we align the tuples on pages with 8-byte alignment, but in-memory arrays of the struct wouldn't have to deal with that, AFAIK. > I think in most cases > due to FormData_pg_attribute being so huge, the aset.c power-of-2 > roundup behaviour will be unlikely to cross a power-of-2 boundary. ASet isn't the only allocator, but default enough for this to make sense, yes. > The following demonstrates which column counts that actually makes a > difference with: > > select c as n_cols,old_bytes, new_bytes from (select c,24+104*c as > old_bytes, 32+100*c+8*c as new_bytes from generate_series(1,1024) c) > where position('1' in old_bytes::bit(32)::text) != position('1' in > new_bytes::bit(32)::text); > > That returns just 46 column counts out of 1024 where we cross a power > of 2 boundaries with the patched code that we didn't cross in master. > Of course, larger pallocs will result in a malloc() directly, so > perhaps that's not a good measure. At least for smaller column counts > it should be mainly the same amount of memory used. There are only 6 > rows in there for column counts below 100. I think if we were worried > about memory there are likely 100 other things we could do to reclaim > some. It would only take some shuffling of fields in RelationData. I > count 50 bytes of holes in that struct out of the 488 bytes. There are > probably a few that could be moved without upsetting the > struct-field-order-lords too much. I'd love for RelationData to be split into IndexRelation, TableRelation, ForeignTableRelation, etc., as there's a lot of wastage caused by exclusive fields, too. > > > 0004: Adjusts the attalign to change it from char to uint8. See below. > > > > > > The 0004 patch changes the TupleDescDeformAttr.attalign to a uint8 > > > rather than a char containing 'c', 's', 'i' or 'd'. This allows much > > > more simple code in the att_align_nominal() macro. What's in master is > > > quite a complex expression to evaluate every time we deform a column > > > as it much translate: 'c' -> 1, 's' -> 2, 'i' -> 4, 'd' -> 8. If we > > > just store that numeric value in the struct that macro can become a > > > simple TYPEALIGN() so the operation becomes simple bit masking rather > > > than a poorly branch predictable series of compare and jump. > > > > +1, that's something I'd missed in my patches, and is probably the > > largest contributor to the speedup. > > I think so too and I did consider if we should try and do that to > pg_attribute, renaming the column to attalignby. I started but didn't > finish a patch for that. I'm not sure we have a pg_type entry that that supports numeric attalign values without increasing the size of the field, as the one single-byte integer-like type (char) is always used as a printable character, and implied to always be printable through its usage in e.g. nodeToString infrastructure. I'd love to have a better option, but we don't seem to have one yet. Kind regards, Matthias van de Meent Neon (https://neon.tech)