Make tuple deformation faster
От | David Rowley |
---|---|
Тема | Make tuple deformation faster |
Дата | |
Msg-id | CAApHDvrBztXP3yx=NKNmo3xwFAFhEdyPnvrDg3=M0RhDs+4vYw@mail.gmail.com обсуждение исходный текст |
Ответы |
Re: Make tuple deformation faster
|
Список | pgsql-hackers |
Currently, TupleDescData contains the descriptor's attributes in a variable length array of FormData_pg_attribute allocated within the same allocation as the TupleDescData. According to my IDE, sizeof(FormData_pg_attribute) == 104 bytes. It's that large mainly due to attname being 64 bytes. The TupleDescData.attrs[] array could end up quite large on tables with many columns and that could result in poor CPU cache hit ratios when deforming tuples. Instead, we could make TupleDescData contain an out-of-line pointer to the array of FormData_pg_attribute and have a much more compact inlined array of some other struct that much more densely contains the fields required for tuple deformation. attname and many of the other fields are not required to deform a tuple. I've attached a patch series which does this. 0001: Just fixes up some missing usages of TupleDescAttr(). (mostly missed by me, apparently :-( ) 0002: Adjusts the TupleDescData.attrs array to make it out of line. I wanted to make sure nothing weird happened by doing this before doing the bulk of the other changes to add the new struct. 0003: Adds a very compact 8-byte struct named TupleDescDeformAttr, which can be used for tuple deformation. 8 columns fits on a 64-byte cacheline rather than 13 cachelines. 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. The state of this patch series is "proof of concept". I think the current state should be enough to get an idea of the rough amount of code churn this change would cause and also an idea of the expected performance of the change. It certainly isn't in a finished state. I've not put much effort into updating comments or looking at READMEs to see what's now outdated. I also went with trying to patch a bunch of additional boolean columns from pg_attribute so they just take up 1 bit of space in the attflags field in the new struct. I've not tested the performance of expanding this out so these use 1 bool field each. That would make the struct bigger than 8 bytes. Having the struct be a power-of-2 size is also beneficial as it allows fast bit-shifting to be used to get the array element address rather than a more complex (and slower) LEA instruction. I could try making the struct 16 bytes and see if there are any further wins by avoiding the bitwise AND on the TupleDescDeformAttr.attflags field. To test the performance of this, I tried using the attached script which creates a table where the first column is a variable length column and the final column is an int. The query I ran to test the performance inserted 1 million rows into this table and performed a sum() on the final column. The attached graph shows that the query is 30% faster than master with 15 columns between the first and last column. For fewer columns, the speedup is less. This is quite a deform-heavy query so it's not like it speeds up every table with that column arrangement by 30%, but certainly, some queries could see that much gain and even more seems possible. I didn't go to a great deal of trouble to find the most deform-heavy workload. I'll stick this in the July CF. It would be good to get some feedback on the idea and feedback on whether more work on this is worthwhile. As mentioned, the 0001 patch just fixes up the missing usages of the TupleDescAttr() macro. I see no reason not to commit this now. Thanks David
Вложения
В списке pgsql-hackers по дате отправления: