summaryrefslogtreecommitdiff
path: root/src/include/access
diff options
context:
space:
mode:
authorDavid Rowley2024-12-20 20:43:26 +0000
committerDavid Rowley2024-12-20 20:43:26 +0000
commitdb448ce5ad36a2754e4e75900b180260143aacf8 (patch)
tree54753cad82035c6a3cdf7edaa897291b09622d6b /src/include/access
parent1f81b48a9d567ae9074ab1f3233eae9997b3d7bd (diff)
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/include/access')
-rw-r--r--src/include/access/tupdesc.h2
-rw-r--r--src/include/access/tupmacs.h27
2 files changed, 28 insertions, 1 deletions
diff --git a/src/include/access/tupdesc.h b/src/include/access/tupdesc.h
index 4406617fea6..e61a4affa46 100644
--- a/src/include/access/tupdesc.h
+++ b/src/include/access/tupdesc.h
@@ -75,7 +75,7 @@ typedef struct CompactAttribute
bool attisdropped; /* as FormData_pg_attribute.attisdropped */
bool attgenerated; /* FormData_pg_attribute.attgenerated != '\0' */
bool attnotnull; /* as FormData_pg_attribute.attnotnull */
- char attalign; /* alignment requirement */
+ uint8 attalignby; /* alignment requirement in bytes */
} CompactAttribute;
/*
diff --git a/src/include/access/tupmacs.h b/src/include/access/tupmacs.h
index fcf09ed95f4..0de67e3602a 100644
--- a/src/include/access/tupmacs.h
+++ b/src/include/access/tupmacs.h
@@ -92,6 +92,16 @@ fetch_att(const void *T, bool attbyval, int attlen)
)
/*
+ * Similar to att_align_datum, but accepts a number of bytes, typically from
+ * CompactAttribute.attalignby to align the Datum by.
+ */
+#define att_datum_alignby(cur_offset, attalignby, attlen, attdatum) \
+ ( \
+ ((attlen) == -1 && VARATT_IS_SHORT(DatumGetPointer(attdatum))) ? \
+ (uintptr_t) (cur_offset) : \
+ TYPEALIGN(attalignby, cur_offset))
+
+/*
* att_align_pointer performs the same calculation as att_align_datum,
* but is used when walking a tuple. attptr is the current actual data
* pointer; when accessing a varlena field we have to "peek" to see if we
@@ -113,6 +123,16 @@ fetch_att(const void *T, bool attbyval, int attlen)
)
/*
+ * Similar to att_align_pointer, but accepts a number of bytes, typically from
+ * CompactAttribute.attalignby to align the pointer by.
+ */
+#define att_pointer_alignby(cur_offset, attalignby, attlen, attptr) \
+ ( \
+ ((attlen) == -1 && VARATT_NOT_PAD_BYTE(attptr)) ? \
+ (uintptr_t) (cur_offset) : \
+ TYPEALIGN(attalignby, cur_offset))
+
+/*
* att_align_nominal aligns the given offset as needed for a datum of alignment
* requirement attalign, ignoring any consideration of packed varlena datums.
* There are three main use cases for using this macro directly:
@@ -139,6 +159,13 @@ fetch_att(const void *T, bool attbyval, int attlen)
)
/*
+ * Similar to att_align_nominal, but accepts a number of bytes, typically from
+ * CompactAttribute.attalignby to align the offset by.
+ */
+#define att_nominal_alignby(cur_offset, attalignby) \
+ TYPEALIGN(attalignby, cur_offset)
+
+/*
* att_addlength_datum increments the given offset by the space needed for
* the given Datum variable. attdatum is only accessed if we are dealing
* with a variable-length attribute.