Re: BUG #15923: Prepared statements take way too much memory.

From: Thomas Munro <thomas(dot)munro(at)gmail(dot)com>
To: Daniel Migowski <dmigowski(at)ikoffice(dot)de>
Cc: Tom Lane <tgl(at)sss(dot)pgh(dot)pa(dot)us>, Andres Freund <andres(at)anarazel(dot)de>, "pgsql-bugs(at)lists(dot)postgresql(dot)org" <pgsql-bugs(at)lists(dot)postgresql(dot)org>
Subject: Re: BUG #15923: Prepared statements take way too much memory.
Date: 2019-07-29 06:11:04
Message-ID: CA+hUKGLfa6ANa0vs7Lf0op0XBH05HE8SyX8NFhDyT7k2CHYLXw@mail.gmail.com
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-bugs

On Sun, Jul 28, 2019 at 11:14 PM Daniel Migowski <dmigowski(at)ikoffice(dot)de> wrote:
> * Why are MemoryContextAllocZeroAligned and MemoryContextAllocZero the same function?

It's not really relevant to the discussion about memory usage, but since
you asked about MemoryContextAllocZeroAligned:

I noticed that stuff a while back when another project I follow was
tweaking related stuff. The idea behind those functions is that we
have our own specialised memset()-like macros.
MemoryContextAllocZeroAligned() uses MemSetLoop(), while
MemoryContextAllocZero() uses MemSetAligned(). Those date back nearly
two decades and were apparently based on experiments done at the time.
The comments talk about avoiding function call overhead and
specialising for constant lengths, so I suppose we assumed that
compilers at the time didn't automatically know how to inline plain
old memset() calls.

These days, you'd think you could add "assume aligned" attributes to
all memory-allocation-like functions and then change a few key things
to be static inline so that the constants can be seen in the right
places, and get all of the same benefits (and probably more) for free
from the compiler's alignment analysis and inlining powers.

As for what benefits might actually be available, for constants it's
clear but for alignment, I'm doubtful. When Clang 8 on amd64 inlines
a memset() with a known aligned destination (for various alignment
sizes) and constant size, it generates a bunch of movups instructions,
or with -march set to a modern arch, maybe vmovups, and some
variations depending on size. Note 'u' (unaligned) instructions, not
'a' (aligned): that is, it doesn't even care that I said it the
destination was aligned! I found claims from a couple of Intel
sources that this sort of thing stopped making any difference to
performance in the Nehalem microarchitecture (2008). It still matters
whether the data actually is aligned, but not whether you use the
instructions that tolerate misalignment, so there is apparently no
point in generating different code, and therefore, as far as memset()
goes, apparently no gain from annotating allocation functions as
returning aligned pointers. As for other architectures or compilers,
I don't know.

For curiosity, here's an experimental patch that gets rid of the
MemSetXXX() stuff, adds some (useless?) annotations about alignment
and makes palloc0() and MemoryContextAllocZero() inline so that they
can benefit from inlining with a visible constant size in eg
newNode(). It didn't seem to do anything very interesting apart from
remove a few hundred lines of code, so I didn't get around to digging
further or sharing it earlier. Or maybe I was just doing it wrong.
(In this patch it's using sizeof(long) which isn't enough to be
considered aligned for the wider move instructions, but I tried
various sizes when trying to trigger different codegen, without
success).

--
Thomas Munro
https://enterprisedb.com

Attachment Content-Type Size
0001-Use-compiler-alignment-hints-for-palloc-and-memset.patch application/x-patch 15.2 KB

In response to

Responses

Browse pgsql-bugs by date

  From Date Subject
Next Message Manuel Rigger 2019-07-29 07:22:44 Re: REINDEX CONCURRENTLY causes ALTER TABLE to fail
Previous Message Murali Krishna 2019-07-29 05:15:31 GoldenGate to PostgreSQL connectivity