executor: Reduce overhead of instrumentation a bit by allowing more inlining.
authorAndres Freund <andres@anarazel.de>
Thu, 28 May 2020 21:49:45 +0000 (14:49 -0700)
committerAndres Freund <andres@anarazel.de>
Mon, 11 Jan 2021 23:09:14 +0000 (15:09 -0800)
Author:
Reviewed-By:
Discussion: https://postgr.es/m/
Backpatch:

src/backend/executor/execProcnode.c
src/backend/executor/instrument.c
src/include/executor/executor.h

index 414df50a0545e567726280f7e64041c8064616f8..25826bf4b4e20538374e7e514640c6adda534465 100644 (file)
 #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
  *
index 677b1c3a77d2d6bff8a0c7c6f95a8f068b4eb816..3849c12e969c87b0d6e5a48d0ba9752ddd7d4f8b 100644 (file)
@@ -15,6 +15,7 @@
 
 #include <unistd.h>
 
+#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 */
index 53f431e1ed79ffa9986bea2308666ad2e8d96ba1..3bf06cac1c7f3e32a8d6d453ad7efb4efdcf46c2 100644 (file)
@@ -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