mirror of
https://github.com/postgres/postgres.git
synced 2025-07-30 11:03:19 +03:00
Optimize visibilitymap_count() with AVX-512 instructions.
Commit 792752af4e
added infrastructure for using AVX-512 intrinsic
functions, and this commit uses that infrastructure to optimize
visibilitymap_count(). Specificially, a new pg_popcount_masked()
function is introduced that applies a bitmask to every byte in the
buffer prior to calculating the population count, which is used to
filter out the all-visible or all-frozen bits as needed. Platforms
without AVX-512 support should also see a nice speedup due to the
reduced number of calls to a function pointer.
Co-authored-by: Ants Aasma
Discussion: https://postgr.es/m/BL1PR11MB5304097DF7EA81D04C33F3D1DCA6A%40BL1PR11MB5304.namprd11.prod.outlook.com
This commit is contained in:
@ -119,10 +119,8 @@
|
||||
#define HEAPBLK_TO_OFFSET(x) (((x) % HEAPBLOCKS_PER_BYTE) * BITS_PER_HEAPBLOCK)
|
||||
|
||||
/* Masks for counting subsets of bits in the visibility map. */
|
||||
#define VISIBLE_MASK64 UINT64CONST(0x5555555555555555) /* The lower bit of each
|
||||
* bit pair */
|
||||
#define FROZEN_MASK64 UINT64CONST(0xaaaaaaaaaaaaaaaa) /* The upper bit of each
|
||||
* bit pair */
|
||||
#define VISIBLE_MASK8 (0x55) /* The lower bit of each bit pair */
|
||||
#define FROZEN_MASK8 (0xaa) /* The upper bit of each bit pair */
|
||||
|
||||
/* prototypes for internal routines */
|
||||
static Buffer vm_readbuf(Relation rel, BlockNumber blkno, bool extend);
|
||||
@ -396,7 +394,6 @@ visibilitymap_count(Relation rel, BlockNumber *all_visible, BlockNumber *all_fro
|
||||
{
|
||||
Buffer mapBuffer;
|
||||
uint64 *map;
|
||||
int i;
|
||||
|
||||
/*
|
||||
* Read till we fall off the end of the map. We assume that any extra
|
||||
@ -414,21 +411,9 @@ visibilitymap_count(Relation rel, BlockNumber *all_visible, BlockNumber *all_fro
|
||||
*/
|
||||
map = (uint64 *) PageGetContents(BufferGetPage(mapBuffer));
|
||||
|
||||
StaticAssertStmt(MAPSIZE % sizeof(uint64) == 0,
|
||||
"unsupported MAPSIZE");
|
||||
if (all_frozen == NULL)
|
||||
{
|
||||
for (i = 0; i < MAPSIZE / sizeof(uint64); i++)
|
||||
nvisible += pg_popcount64(map[i] & VISIBLE_MASK64);
|
||||
}
|
||||
else
|
||||
{
|
||||
for (i = 0; i < MAPSIZE / sizeof(uint64); i++)
|
||||
{
|
||||
nvisible += pg_popcount64(map[i] & VISIBLE_MASK64);
|
||||
nfrozen += pg_popcount64(map[i] & FROZEN_MASK64);
|
||||
}
|
||||
}
|
||||
nvisible += pg_popcount_masked((const char *) map, MAPSIZE, VISIBLE_MASK8);
|
||||
if (all_frozen)
|
||||
nfrozen += pg_popcount_masked((const char *) map, MAPSIZE, FROZEN_MASK8);
|
||||
|
||||
ReleaseBuffer(mapBuffer);
|
||||
}
|
||||
|
Reference in New Issue
Block a user