From: Andres Freund Date: Thu, 28 May 2020 21:49:45 +0000 (-0700) Subject: executor: Reduce overhead of instrumentation a bit by allowing more inlining. X-Git-Url: http://git.postgresql.org/gitweb/static/gitweb.js?a=commitdiff_plain;h=1cdd7ce26f0ccb1f521b129d68d01ef015d97aa6;p=users%2Fandresfreund%2Fpostgres.git executor: Reduce overhead of instrumentation a bit by allowing more inlining. Author: Reviewed-By: Discussion: https://postgr.es/m/ Backpatch: --- diff --git a/src/backend/executor/execProcnode.c b/src/backend/executor/execProcnode.c index 414df50a05..25826bf4b4 100644 --- a/src/backend/executor/execProcnode.c +++ b/src/backend/executor/execProcnode.c @@ -118,7 +118,6 @@ #include "nodes/nodeFuncs.h" static TupleTableSlot *ExecProcNodeFirst(PlanState *node); -static TupleTableSlot *ExecProcNodeInstr(PlanState *node); /* ------------------------------------------------------------------------ @@ -451,26 +450,6 @@ ExecProcNodeFirst(PlanState *node) } -/* - * ExecProcNode wrapper that performs instrumentation calls. By keeping - * this a separate function, we avoid overhead in the normal case where - * no instrumentation is wanted. - */ -static TupleTableSlot * -ExecProcNodeInstr(PlanState *node) -{ - TupleTableSlot *result; - - InstrStartNode(node->instrument); - - result = node->ExecProcNodeReal(node); - - InstrStopNode(node->instrument, TupIsNull(result) ? 0.0 : 1.0); - - return result; -} - - /* ---------------------------------------------------------------- * MultiExecProcNode * diff --git a/src/backend/executor/instrument.c b/src/backend/executor/instrument.c index 677b1c3a77..3849c12e96 100644 --- a/src/backend/executor/instrument.c +++ b/src/backend/executor/instrument.c @@ -15,6 +15,7 @@ #include +#include "executor/executor.h" #include "executor/instrument.h" BufferUsage pgBufferUsage; @@ -26,6 +27,26 @@ static void BufferUsageAdd(BufferUsage *dst, const BufferUsage *add); static void WalUsageAdd(WalUsage *dst, WalUsage *add); +/* + * ExecProcNode wrapper that performs instrumentation calls. By keeping + * this a separate function, we avoid overhead in the normal case where + * no instrumentation is wanted. + */ +TupleTableSlot * +ExecProcNodeInstr(PlanState *node) +{ + TupleTableSlot *result; + + InstrStartNode(node->instrument); + + result = node->ExecProcNodeReal(node); + + InstrStopNode(node->instrument, TupIsNull(result) ? 0.0 : 1.0); + + return result; +} + + /* Allocate new instrumentation structure(s) */ Instrumentation * InstrAlloc(int n, int instrument_options) @@ -64,10 +85,10 @@ InstrInit(Instrumentation *instr, int instrument_options) /* Entry to a plan node */ void -InstrStartNode(Instrumentation *instr) + InstrStartNode(Instrumentation *instr) { if (instr->need_timer && - !INSTR_TIME_SET_CURRENT_LAZY(instr->starttime)) + unlikely(!INSTR_TIME_SET_CURRENT_LAZY(instr->starttime))) elog(ERROR, "InstrStartNode called twice in a row"); /* save buffer usage totals at node entry, if needed */ @@ -90,7 +111,7 @@ InstrStopNode(Instrumentation *instr, double nTuples) /* let's update the time only if the timer was requested */ if (instr->need_timer) { - if (INSTR_TIME_IS_ZERO(instr->starttime)) + if (unlikely(INSTR_TIME_IS_ZERO(instr->starttime))) elog(ERROR, "InstrStopNode called without start"); INSTR_TIME_SET_CURRENT(endtime); @@ -126,7 +147,7 @@ InstrEndLoop(Instrumentation *instr) if (!instr->running) return; - if (!INSTR_TIME_IS_ZERO(instr->starttime)) + if (unlikely(!INSTR_TIME_IS_ZERO(instr->starttime))) elog(ERROR, "InstrEndLoop called on running node"); /* Accumulate per-cycle statistics into totals */ diff --git a/src/include/executor/executor.h b/src/include/executor/executor.h index 53f431e1ed..3bf06cac1c 100644 --- a/src/include/executor/executor.h +++ b/src/include/executor/executor.h @@ -230,6 +230,9 @@ extern void ExecEndNode(PlanState *node); extern bool ExecShutdownNode(PlanState *node); extern void ExecSetTupleBound(int64 tuples_needed, PlanState *child_node); +/* implemented in instrument.c */ +extern TupleTableSlot *ExecProcNodeInstr(PlanState *node); + /* ---------------------------------------------------------------- * ExecProcNode