Per previous analysis, the most correct notion of SampleOverhead is that

it is just the total time to do INSTR_TIME_SET_CURRENT(), and not any of
the other code involved in InstrStartNode/InstrStopNode.  Even though I
fear we may end up reverting this patch altogether, we may as well have
the most correct version in our CVS archive.
This commit is contained in:
Tom Lane 2006-06-07 18:49:03 +00:00
parent e9f6679ce2
commit d8364f3f8f

View File

@ -7,7 +7,7 @@
* Copyright (c) 2001-2006, PostgreSQL Global Development Group * Copyright (c) 2001-2006, PostgreSQL Global Development Group
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/executor/instrument.c,v 1.16 2006/05/30 19:24:25 tgl Exp $ * $PostgreSQL: pgsql/src/backend/executor/instrument.c,v 1.17 2006/06/07 18:49:03 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -42,7 +42,7 @@
* *
* The actual sampling interval is randomized with the SampleFunc() value * The actual sampling interval is randomized with the SampleFunc() value
* as the mean; this hopefully will reduce any measurement bias due to * as the mean; this hopefully will reduce any measurement bias due to
* cyclic variation in the node execution time. * variation in the node execution time.
*/ */
#ifdef HAVE_CBRT #ifdef HAVE_CBRT
#define SampleFunc(niters) cbrt(niters) #define SampleFunc(niters) cbrt(niters)
@ -56,8 +56,7 @@
/* /*
* We sample at every node iteration until we've reached this threshold, * We sample at every node iteration until we've reached this threshold,
* so that nodes not called a large number of times are completely accurate. * so that nodes not called a large number of times are completely accurate.
* (Perhaps this should be a GUC variable? But beware of messing up * (Perhaps this should be a GUC variable?)
* CalculateSampleOverhead if value is too small.)
*/ */
#define SAMPLE_THRESHOLD 50 #define SAMPLE_THRESHOLD 50
@ -71,7 +70,6 @@ static bool SampleOverheadCalculated = false;
static void static void
CalculateSampleOverhead(void) CalculateSampleOverhead(void)
{ {
Instrumentation instr;
int i; int i;
/* /*
@ -82,20 +80,20 @@ CalculateSampleOverhead(void)
for (i = 0; i < 5; i++) for (i = 0; i < 5; i++)
{ {
Instrumentation timer;
instr_time tmptime;
int j; int j;
double overhead; double overhead;
memset(&instr, 0, sizeof(instr)); memset(&timer, 0, sizeof(timer));
/* InstrStartNode(&timer);
* We know that samples will actually be taken up to SAMPLE_THRESHOLD, #define TEST_COUNT 100
* so that's as far as we can test. for (j = 0; j < TEST_COUNT; j++)
*/
for (j=0; j < SAMPLE_THRESHOLD; j++)
{ {
InstrStartNode(&instr); INSTR_TIME_SET_CURRENT(tmptime);
InstrStopNode(&instr, 1);
} }
overhead = INSTR_TIME_GET_DOUBLE(instr.counter) / instr.samplecount; InstrStopNode(&timer, 1);
overhead = INSTR_TIME_GET_DOUBLE(timer.counter) / TEST_COUNT;
if (overhead < SampleOverhead) if (overhead < SampleOverhead)
SampleOverhead = overhead; SampleOverhead = overhead;
} }
@ -159,14 +157,20 @@ InstrStopNode(Instrumentation *instr, double nTuples)
{ {
instr_time endtime; instr_time endtime;
/*
* To be sure that SampleOverhead accurately reflects the extra
* overhead, we must do INSTR_TIME_SET_CURRENT() as the *first*
* action that is different between the sampling and non-sampling
* code paths.
*/
INSTR_TIME_SET_CURRENT(endtime);
if (INSTR_TIME_IS_ZERO(instr->starttime)) if (INSTR_TIME_IS_ZERO(instr->starttime))
{ {
elog(DEBUG2, "InstrStopNode called without start"); elog(DEBUG2, "InstrStopNode called without start");
return; return;
} }
INSTR_TIME_SET_CURRENT(endtime);
#ifndef WIN32 #ifndef WIN32
instr->counter.tv_sec += endtime.tv_sec - instr->starttime.tv_sec; instr->counter.tv_sec += endtime.tv_sec - instr->starttime.tv_sec;
instr->counter.tv_usec += endtime.tv_usec - instr->starttime.tv_usec; instr->counter.tv_usec += endtime.tv_usec - instr->starttime.tv_usec;