From cba515bd4d23e0b860f8b17a92932a3d7b3ab675 Mon Sep 17 00:00:00 2001 From: "imai.yoshikazu" Date: Tue, 25 Feb 2020 07:25:26 +0000 Subject: [PATCH v6 2/2] [POC] Change measuring method of wait event time from INSTR_TIME to rdtsc. This patch changes measuring method of wait event time from INSTR_TIME (which uses gettimeofday or clock_gettime) to rdtsc. This might reduce the overhead of measuring overhead. Any supports like changing clock cycle to actual time or error handling are not currently implemented. --- src/backend/postmaster/pgstat.c | 8 ++++---- src/backend/utils/adt/pgstatfuncs.c | 2 +- src/include/pgstat.h | 14 +++++++------- src/include/portability/instr_time.h | 21 +++++++++++++++++++++ 4 files changed, 33 insertions(+), 12 deletions(-) diff --git a/src/backend/postmaster/pgstat.c b/src/backend/postmaster/pgstat.c index 5c2f125..19c0017 100644 --- a/src/backend/postmaster/pgstat.c +++ b/src/backend/postmaster/pgstat.c @@ -156,7 +156,7 @@ static bool pgStatRunningInCollector = false; WAHash *wa_hash; -instr_time waitStart; +uint64 waitStart; /* * Structures in which backends store per-table info that's waiting to be @@ -4574,7 +4574,7 @@ pgstat_send_waitaccum() /* Clear wait events information. */ entry->calls = 0; - INSTR_TIME_SET_ZERO(entry->times); + entry->times = 0; } if (msg.m_nentries > 0) @@ -6414,7 +6414,7 @@ pgstat_recv_resetsharedcounter(PgStat_MsgResetsharedcounter *msg, int len) entry = hash->entries[i].entry; entry->calls = 0; - INSTR_TIME_SET_ZERO(entry->times); + entry->times = 0; } } /* @@ -6627,7 +6627,7 @@ pgstat_recv_waitaccum(PgStat_MsgWaitAccum *msg, int len) * Otherwise add the values to the existing entry. */ entry->calls += m_entry->calls; - INSTR_TIME_ADD(entry->times, m_entry->times); + entry->times += m_entry->times; } } } diff --git a/src/backend/utils/adt/pgstatfuncs.c b/src/backend/utils/adt/pgstatfuncs.c index de0e1bf..9408c4b 100644 --- a/src/backend/utils/adt/pgstatfuncs.c +++ b/src/backend/utils/adt/pgstatfuncs.c @@ -2052,7 +2052,7 @@ pg_stat_get_waitaccum(PG_FUNCTION_ARGS) values[2] = Int64GetDatum(entry->calls); - values[3] = UInt64GetDatum(INSTR_TIME_GET_MICROSEC(entry->times)); + values[3] = UInt64GetDatum(entry->times); tuplestore_putvalues(tupstore, tupdesc, values, nulls); } diff --git a/src/include/pgstat.h b/src/include/pgstat.h index e5dbcb4..962144d 100644 --- a/src/include/pgstat.h +++ b/src/include/pgstat.h @@ -432,7 +432,7 @@ typedef struct PgStat_WaitAccumEntry { uint32 wait_event_info; PgStat_Counter calls; - instr_time times; + uint64 times; } PgStat_WaitAccumEntry; /* ---------- @@ -1270,7 +1270,7 @@ typedef struct PgStat_FunctionCallUsage } PgStat_FunctionCallUsage; extern WAHash *wa_hash; -extern instr_time waitStart; +extern uint64 waitStart; /* ---------- * GUC parameters @@ -1393,7 +1393,7 @@ pgstat_report_waitaccum_start() if (pgstat_track_wait_timing) { - INSTR_TIME_SET_CURRENT(waitStart); + waitStart = rdtsc(); } } @@ -1401,15 +1401,15 @@ static inline void pgstat_report_waitaccum_end(uint32 wait_event_info) { PgStat_WaitAccumEntry *entry; - instr_time diff; + uint64 diff = 0; if (wa_hash == NULL) return; if (pgstat_track_wait_timing) { - INSTR_TIME_SET_CURRENT(diff); - INSTR_TIME_SUBTRACT(diff, waitStart); + diff = rdtsc(); + diff -= waitStart; } entry = pgstat_get_wa_entry(wa_hash, wait_event_info); @@ -1424,7 +1424,7 @@ pgstat_report_waitaccum_end(uint32 wait_event_info) entry->calls++; if (pgstat_track_wait_timing) { - INSTR_TIME_ADD(entry->times, diff); + entry->times += diff; } } diff --git a/src/include/portability/instr_time.h b/src/include/portability/instr_time.h index d645932..e3929c3 100644 --- a/src/include/portability/instr_time.h +++ b/src/include/portability/instr_time.h @@ -57,6 +57,10 @@ #ifndef WIN32 +#if defined(__x86_64__) || defined(__i386__) +#include +#endif + #ifdef HAVE_CLOCK_GETTIME /* Use clock_gettime() */ @@ -209,6 +213,8 @@ typedef struct timeval instr_time; #else /* WIN32 */ +#include + /* Use QueryPerformanceCounter() */ typedef LARGE_INTEGER instr_time; @@ -254,3 +260,18 @@ GetTimerFrequency(void) (INSTR_TIME_IS_ZERO(t) ? INSTR_TIME_SET_CURRENT(t), true : false) #endif /* INSTR_TIME_H */ + +#ifndef RDTSC_H_ +#define RDTSC_H_ + +static inline uint64 rdtsc() { + uint64 result; +#if defined(__x86_64__) || defined(__i386__) || defined(WIN32) + result = __rdtsc(); +#else + result = 0; +#endif + return result; +} + +#endif -- 1.8.3.1