From f1b183123befc1a3f096ba36b1c3834b4c67d3ec Mon Sep 17 00:00:00 2001 From: David Rowley Date: Thu, 17 Nov 2022 13:24:40 +1300 Subject: [PATCH v2 3/5] Unroll loop in heapgetpage --- src/backend/access/heap/heapam.c | 48 ++++++++++++++++++++++++++++---- 1 file changed, 42 insertions(+), 6 deletions(-) diff --git a/src/backend/access/heap/heapam.c b/src/backend/access/heap/heapam.c index 81c7f69644..8fe4f4c837 100644 --- a/src/backend/access/heap/heapam.c +++ b/src/backend/access/heap/heapam.c @@ -484,15 +484,51 @@ heapgetpage(TableScanDesc sscan, BlockNumber block) loctup.t_tableOid = RelationGetRelid(scan->rs_base.rs_rd); /* - * Iterate forward over line items, they're laid out in increasing - * order in memory. Doing this separately allows to benefit from - * out-of-order capabilities of the CPU and simplifies the next loop. + * Iterate forward over line items processing 16 at a time (this + * assumes there will be 16 ItemIds per CPU cacheline. */ for (lineoff = FirstOffsetNumber, lpp = PageGetItemId(page, lineoff); - lineoff <= lines; - lineoff++, lpp++) + lineoff <= lines - 15; + lineoff += 16, lpp += 16) + { + pg_prefetch_mem(PageGetItemId(page, lineoff + 16)); + if (ItemIdIsNormal(lpp)) + normoffsets[normcount++] = lineoff; + if (ItemIdIsNormal(lpp + 1)) + normoffsets[normcount++] = lineoff + 1; + if (ItemIdIsNormal(lpp + 2)) + normoffsets[normcount++] = lineoff + 2; + if (ItemIdIsNormal(lpp + 3)) + normoffsets[normcount++] = lineoff + 3; + if (ItemIdIsNormal(lpp + 4)) + normoffsets[normcount++] = lineoff + 4; + if (ItemIdIsNormal(lpp + 5)) + normoffsets[normcount++] = lineoff + 5; + if (ItemIdIsNormal(lpp + 6)) + normoffsets[normcount++] = lineoff + 6; + if (ItemIdIsNormal(lpp + 7)) + normoffsets[normcount++] = lineoff + 7; + if (ItemIdIsNormal(lpp + 8)) + normoffsets[normcount++] = lineoff + 8; + if (ItemIdIsNormal(lpp + 9)) + normoffsets[normcount++] = lineoff + 9; + if (ItemIdIsNormal(lpp + 10)) + normoffsets[normcount++] = lineoff + 10; + if (ItemIdIsNormal(lpp + 11)) + normoffsets[normcount++] = lineoff + 11; + if (ItemIdIsNormal(lpp + 12)) + normoffsets[normcount++] = lineoff + 12; + if (ItemIdIsNormal(lpp + 13)) + normoffsets[normcount++] = lineoff + 13; + if (ItemIdIsNormal(lpp + 14)) + normoffsets[normcount++] = lineoff + 14; + if (ItemIdIsNormal(lpp + 15)) + normoffsets[normcount++] = lineoff + 15; + } + + /* get remainder */ + for (; lineoff <= lines; lineoff++, lpp++) { - pg_prefetch_mem(PageGetItemId(page, lineoff+5)); if (ItemIdIsNormal(lpp)) normoffsets[normcount++] = lineoff; } -- 2.35.1.windows.2