mdbx: защита от нуля только общей задержки в метриках транзакции.

Ранее, при конвертации очень коротких интервалов в формат фиксированной
точки 16-точка-16, всегда выполнялось замещение нуля единицей. Т.е. если
интервал был не нулевым, но меньше 15.259 микросекунд (1/65536 секунды),
то вместо 0 возвращалось 1.

Это приводило к тому, что сумма длительности отдельных стадий нередко
была больше чем общее время фиксации транзакции. Проблема усугублялась,
если получаемые значения аккумулировались по серии транзакций.

Теперь такая защита от нуля выполняется только для общего времени,
но не для отдельных стадий.

Было:
	latency(ms): preparation=72.69 gc=72.69 write=73.04 sync=141.40 ending=72.69 whole=142.14
	Аккумулированная сумма длительности этапов ВТРОЕ(!) больше общей длительности.

Стало:
	latency(ms): preparation=0.00 gc=0.02 write=0.79 sync=67.98 ending=0.00 whole=140.81
	Аккумулированная сумма длительности этапов меньше общей длительности,
	так как для каждой транзакции общая длительность возвращается не менее 15.259 микросекунд.
This commit is contained in:
Леонид Юрьев (Leonid Yuriev) 2022-10-07 14:53:35 +03:00
parent 92dabe1ad1
commit f6eec7195b
3 changed files with 12 additions and 8 deletions

View File

@ -10714,7 +10714,7 @@ provide_latency:
latency->sync = (ts_4 && ts_5) ? osal_monotime_to_16dot16(ts_5 - ts_4) : 0;
const uint64_t ts_6 = osal_monotime();
latency->ending = ts_5 ? osal_monotime_to_16dot16(ts_6 - ts_5) : 0;
latency->whole = osal_monotime_to_16dot16(ts_6 - ts_0);
latency->whole = osal_monotime_to_16dot16_noUnderflow(ts_6 - ts_0);
}
return rc;
@ -20775,14 +20775,15 @@ __cold static int fetch_envinfo_ex(const MDBX_env *env, const MDBX_txn *txn,
const uint64_t monotime_now = osal_monotime();
uint64_t ts = atomic_load64(&lck->mti_sync_timestamp, mo_Relaxed);
arg->mi_since_sync_seconds16dot16 =
ts ? osal_monotime_to_16dot16(monotime_now - ts) : 0;
ts ? osal_monotime_to_16dot16_noUnderflow(monotime_now - ts) : 0;
ts = atomic_load64(&lck->mti_reader_check_timestamp, mo_Relaxed);
arg->mi_since_reader_check_seconds16dot16 =
ts ? osal_monotime_to_16dot16(monotime_now - ts) : 0;
ts ? osal_monotime_to_16dot16_noUnderflow(monotime_now - ts) : 0;
arg->mi_autosync_threshold = pgno2bytes(
env, atomic_load32(&lck->mti_autosync_threshold, mo_Relaxed));
arg->mi_autosync_period_seconds16dot16 = osal_monotime_to_16dot16(
atomic_load64(&lck->mti_autosync_period, mo_Relaxed));
arg->mi_autosync_period_seconds16dot16 =
osal_monotime_to_16dot16_noUnderflow(
atomic_load64(&lck->mti_autosync_period, mo_Relaxed));
arg->mi_bootid.current.x = bootid.x;
arg->mi_bootid.current.y = bootid.y;
arg->mi_mode = env->me_lck_mmap.lck ? lck->mti_envmode.weak : env->me_flags;

View File

@ -2655,9 +2655,7 @@ MDBX_INTERNAL_FUNC uint32_t osal_monotime_to_16dot16(uint64_t monotime) {
#else
(uint32_t)(monotime * 128 / 1953125);
#endif
if (likely(ret > 0))
return ret;
return monotime > 0 /* fix underflow */;
return ret;
}
MDBX_INTERNAL_FUNC uint64_t osal_monotime(void) {

View File

@ -585,6 +585,11 @@ MDBX_INTERNAL_FUNC uint64_t osal_monotime(void);
MDBX_INTERNAL_FUNC uint64_t osal_16dot16_to_monotime(uint32_t seconds_16dot16);
MDBX_INTERNAL_FUNC uint32_t osal_monotime_to_16dot16(uint64_t monotime);
static inline uint32_t osal_monotime_to_16dot16_noUnderflow(uint64_t monotime) {
uint32_t seconds_16dot16 = osal_monotime_to_16dot16(monotime);
return seconds_16dot16 ? seconds_16dot16 : /* fix underflow */ (monotime > 0);
}
MDBX_INTERNAL_FUNC bin128_t osal_bootid(void);
/*----------------------------------------------------------------------------*/
/* lck stuff */