On 2013-01-10 10:31:04 +0100, Andres Freund wrote:
> On 2013-01-10 00:05:07 +0100, Andres Freund wrote:
> > On 2013-01-09 17:28:35 -0500, Tom Lane wrote:
> > > (We know this doesn't
> > > matter, but gcc doesn't; this version of gcc apparently isn't doing much
> > > with the knowledge that elog won't return.)
> >
> > Afaics one reason for that is that we don't have any such annotation for
> > elog(), just for ereport. And I don't immediately see how it could be
> > added to elog without relying on variadic macros. Bit of a shame, there
> > probably a good number of callsites that could actually benefit from
> > that knowledge.
> > Is it worth making that annotation conditional on variadic macro
> > support?
>
> A quick test confirms that. With:
>
> diff --git a/src/include/utils/elog.h b/src/include/utils/elog.h
> index cbbda04..39cd809 100644
> --- a/src/include/utils/elog.h
> +++ b/src/include/utils/elog.h
> @@ -212,7 +212,13 @@ extern int       getinternalerrposition(void);
>   *           elog(ERROR, "portal \"%s\" not found", stmt->portalname);
>   *----------
>   */
> +#ifdef __GNUC__
> +#define elog(elevel, ...) elog_start(__FILE__, __LINE__, PG_FUNCNAME_MACRO), 
> \
> +             elog_finish(elevel, __VA_ARGS__),                               
>                                 \
> +             ((elevel) >= ERROR ? __builtin_unreachable() : (void) 0)
> +#else
>  #define elog elog_start(__FILE__, __LINE__, PG_FUNCNAME_MACRO), elog_finish
> +#endif
>
>  extern void elog_start(const char *filename, int lineno, const char 
> *funcname);
>  extern void
>
> nearly the same code is generated for both variants (this is no
> additionally saved registers and such).
>
> Two unfinished things:
> * the above only checks for gcc although all C99 compilers should
>   support varargs macros
> * It uses __builtin_unreachable() instead of abort() as that creates
>   a smaller executable. That's gcc 4.5 only. Saves about 30kb in a
>   both a stripped and unstripped binary.
> * elog(ERROR) i.e. no args would require more macro ugliness, but that
>   seems unneccesary
>
> Doing the __builtin_unreachable() for ereport as well saves about 50kb.
>
> Given that some of those elog/ereports are in performance critical code
> paths it seems like a good idea to remove code from the
> callsites. Adding configure check for __VA_ARGS__ and
> __builtin_unreachable() should be simple enough?

For whatever its worth - I am not sure its much - after relying on
variadic macros we can make elog into one function call instead of
two. That saves another 100kb.

[tinker]

The builtin_unreachable and combined elog thing bring a measurable
performance benefit of a rather surprising 7% when running Pavel's
testcase ontop of yesterdays HEAD. So it seems worth investigating.
About 3% of that is the __builtin_unreachable() and about 4% the
combining of elog_start/finish.

Now that testcase sure isn't a very representative one for this, but I
don't really see why it should benefit much more than other cases. Seems
to be quite the benefit for relatively minor cost.
Although I am pretty sure just copying the whole of
elog_start/elog_finish into one elog_all() isn't the best way to go at
this...

Greetings,

Andres Freund

--
 Andres Freund                     http://www.2ndQuadrant.com/
 PostgreSQL Development, 24x7 Support, Training & Services


-- 
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

Reply via email to