diff options
author | David Rowley <drowley@postgresql.org> | 2024-12-21 09:43:26 +1300 |
---|---|---|
committer | David Rowley <drowley@postgresql.org> | 2024-12-21 09:43:26 +1300 |
commit | db448ce5ad36a2754e4e75900b180260143aacf8 (patch) | |
tree | 54753cad82035c6a3cdf7edaa897291b09622d6b /src/backend/executor | |
parent | 1f81b48a9d567ae9074ab1f3233eae9997b3d7bd (diff) | |
download | postgresql-db448ce5ad36a2754e4e75900b180260143aacf8.tar.gz postgresql-db448ce5ad36a2754e4e75900b180260143aacf8.zip |
Optimize alignment calculations in tuple form/deform
Here we convert CompactAttribute.attalign from a char, which is directly
derived from pg_attribute.attalign into a uint8, which stores the number
of bytes to align the column's value by in the tuple.
This allows tuple deformation and tuple size calculations to move away
from using the inefficient att_align_nominal() macro, which manually
checks each TYPALIGN_* char to translate that into the alignment bytes
for the given type. Effectively, this commit changes those to TYPEALIGN
calls, which are branchless and only perform some simple arithmetic with
some bit-twiddling.
The removed branches were often mispredicted by CPUs, especially so in
real-world tables which often contain a mishmash of different types
with different alignment requirements.
Author: David Rowley
Reviewed-by: Andres Freund, Victor Yegorov
Discussion: https://postgr.es/m/CAApHDvrBztXP3yx=NKNmo3xwFAFhEdyPnvrDg3=M0RhDs+4vYw@mail.gmail.com
Diffstat (limited to 'src/backend/executor')
-rw-r--r-- | src/backend/executor/execExprInterp.c | 2 | ||||
-rw-r--r-- | src/backend/executor/execTuples.c | 20 |
2 files changed, 11 insertions, 11 deletions
diff --git a/src/backend/executor/execExprInterp.c b/src/backend/executor/execExprInterp.c index 56e13d20a87..d2987663e63 100644 --- a/src/backend/executor/execExprInterp.c +++ b/src/backend/executor/execExprInterp.c @@ -5304,7 +5304,7 @@ ExecEvalWholeRowVar(ExprState *state, ExprEvalStep *op, ExprContext *econtext) if (slot->tts_isnull[i]) continue; /* null is always okay */ if (vattr->attlen != sattr->attlen || - vattr->attalign != sattr->attalign) + vattr->attalignby != sattr->attalignby) ereport(ERROR, (errcode(ERRCODE_DATATYPE_MISMATCH), errmsg("table row type and query-specified row type do not match"), diff --git a/src/backend/executor/execTuples.c b/src/backend/executor/execTuples.c index 875515777b6..5d81c812673 100644 --- a/src/backend/executor/execTuples.c +++ b/src/backend/executor/execTuples.c @@ -202,12 +202,12 @@ tts_virtual_materialize(TupleTableSlot *slot) * We want to flatten the expanded value so that the materialized * slot doesn't depend on it. */ - sz = att_align_nominal(sz, att->attalign); + sz = att_nominal_alignby(sz, att->attalignby); sz += EOH_get_flat_size(DatumGetEOHP(val)); } else { - sz = att_align_nominal(sz, att->attalign); + sz = att_nominal_alignby(sz, att->attalignby); sz = att_addlength_datum(sz, att->attlen, val); } } @@ -242,8 +242,8 @@ tts_virtual_materialize(TupleTableSlot *slot) */ ExpandedObjectHeader *eoh = DatumGetEOHP(val); - data = (char *) att_align_nominal(data, - att->attalign); + data = (char *) att_nominal_alignby(data, + att->attalignby); data_length = EOH_get_flat_size(eoh); EOH_flatten_into(eoh, data, data_length); @@ -254,7 +254,7 @@ tts_virtual_materialize(TupleTableSlot *slot) { Size data_length = 0; - data = (char *) att_align_nominal(data, att->attalign); + data = (char *) att_nominal_alignby(data, att->attalignby); data_length = att_addlength_datum(data_length, att->attlen, val); memcpy(data, DatumGetPointer(val), data_length); @@ -1067,19 +1067,19 @@ slot_deform_heap_tuple(TupleTableSlot *slot, HeapTuple tuple, uint32 *offp, * an aligned or unaligned value. */ if (!slow && - off == att_align_nominal(off, thisatt->attalign)) + off == att_nominal_alignby(off, thisatt->attalignby)) thisatt->attcacheoff = off; else { - off = att_align_pointer(off, thisatt->attalign, -1, - tp + off); + off = att_pointer_alignby(off, thisatt->attalignby, -1, + tp + off); slow = true; } } else { - /* not varlena, so safe to use att_align_nominal */ - off = att_align_nominal(off, thisatt->attalign); + /* not varlena, so safe to use att_nominal_alignby */ + off = att_nominal_alignby(off, thisatt->attalignby); if (!slow) thisatt->attcacheoff = off; |