tsc

package module
v1.3.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: May 3, 2025 License: MIT Imports: 8 Imported by: 23

README

TSC - High-Performance Unix Time in Go

TSC is a Go library that provides extremely low-latency, high-precision Unix timestamps using the processor's Time Stamp Counter register. It's 6-10x faster than and can significantly improve performance for time-sensitive applications. time.Now().UnixNano()

Table of Contents

Overview

TSC leverages the processor's Time Stamp Counter (TSC) register to provide extremely fast timestamp generation. With Invariant TSC support, the library offers reliable frequency measurements across multiple cores/CPUs, delivering timestamps with sub-10ns overhead. Unlike the system clock, TSC provides stable invocation costs and higher precision, while still maintaining calibration with the wall clock to minimize drift.

( abs(system_clock - tsc_clock) for each second min: 0.00us, max: 10.75us, mean: 1.18us within 82,800 seconds)

Key Features

  • Blazing fast: 6-10x faster than standard time.Now().UnixNano()
  • High precision: Better precision than kernel implementations
  • Stable overhead: Consistent cost for each invocation (under 10ns)
  • Auto-calibration: Periodically aligns with the system clock
  • Cross-platform compatibility: Falls back to standard time functions when TSC isn't supported

Getting Started

Basic Usage
package main

import (
	"fmt"
	"github.com/templexxx/tsc"
)

func main() {
	ts := tsc.UnixNano()   // Getting unix nano timestamp
	fmt.Println(ts, tsc.Supported())  // Print result & whether TSC is supported
}
With Calibration

Here is an example of using TSC with calibration

Use Cases

TSC is ideal for applications where timestamp performance matters:

  1. High-performance logging systems (timestamp field generation)
  2. Benchmarking and performance measurement
  3. Low-latency applications with frequent timestamp needs
  4. Cloud-native applications with performance constraints

Performance Comparison

OS CPU time.Now().UnixNano() ns/op tsc.UnixNano() ns/op Improvement
macOS Catalina Intel Core i7-7700HQ 72.8 7.65 89.49%
Ubuntu 18.04 Intel Core i5-8250U 47.7 8.41 82.36%
Ubuntu 20.04 Intel Core i9-9920X 36.5 6.19 83.04%
Fedora 40 Intel Core i7-12700K 22.34 5.81 73.99%
Fedora 41 AMD Ryzen 9 7950X3D 29.81 6.27 78.97%

Clock Drift Analysis

TSC provides tools to analyze the stability and drift characteristics in your environment:

  • Linux testing: Demonstrates how the library handles frequency variations on different hardware qualities. For modern hardware, drift is about 1μs for long-term running.
  • macOS testing: Shows excellent stability with minimal drift within 1μs
  • Windows testing: Have not been tested yet. May need High-resolution timer support for calibration
  • Calibration effects: Visualizations showing how periodic calibration minimizes long-term drift

Detailed drift analysis charts are available in the tools/longdrift directory.

Best Practices

  1. Periodic calibration: Call every 5 minutes to align with system clock (NTP adjustments typically occur every 11 minutes) tsc.Calibrate()
  2. Verify stability: Use provided tools to verify TSC stability in your environment
  3. Ordered execution: Use when measuring execution time of short code segments tsc.ForbidOutOfOrder()
  4. Fallback awareness: Check to know if the hardware TSC is being used or if standard time functions are the fallback tsc.Supported()

Virtual Machine Support

When running in virtualized environments:

  • Some cloud providers handle TSC clock source correctly (like AWS EC2)
  • Feature detection may be limited by CPUID restrictions in VMs
  • TSC will be used as clock source when detected as the system clock source
  • Verify with your VM provider before deploying in production

Limitations

  1. Platform support: Best results on Linux with Intel Enterprise CPUs
  2. Hardware quality: Consumer-grade crystals may show higher drift
  3. VM uncertainty: Behavior in virtualized environments depends on provider implementation

References

  1. Linux gettimeofday implementation details
  2. TSC frequency variations with temperature
  3. Further analysis of TSC temperature effects
  4. Pitfalls of TSC Usage

Documentation

Index

Constants

This section is empty.

Variables

View Source
var (
	// OffsetCoeff is offset & coefficient pair.
	// Coefficient is in [0,64) bits.
	// Offset is in [64, 128) bits.
	// Using false sharing range as aligned size & total size for avoiding cache pollution.
	OffsetCoeff     = xbytes.MakeAlignedBlock(cpu.X86FalseSharingRange, cpu.X86FalseSharingRange)
	OffsetCoeffAddr = &OffsetCoeff[0]
)

unix_nano_timestamp = tsc_register_value * Coeff + Offset. Coeff = 1 / (tsc_frequency / 1e9). We could regard coeff as the inverse of TSCFrequency(GHz) (actually it just has mathematics property) for avoiding future dividing. MUL gets much better performance than DIV.

View Source
var (
	// OffsetCoeffF using float64 as offset.
	OffsetCoeffF     = xbytes.MakeAlignedBlock(cpu.X86FalseSharingRange, cpu.X86FalseSharingRange)
	OffsetCoeffFAddr = &OffsetCoeffF[0]
)
View Source
var UnixNano = sysClock

UnixNano returns time as a Unix time, the number of nanoseconds elapsed since January 1, 1970 UTC.

Warn: DO NOT use it for measuring single function performance unless ForbidOutOfOrder has been invoked.

e.g. ```

start := tsc.UnixNano()
foo()
end := tsc.UnixNano()
cost := end - start

``` The value of cost is unpredictable, because all instructions for getting tsc are not serializing, we need to be careful to deal with the order (use barrier).

See GetInOrder in tsc_amd64.s for more details.

Functions

func AllowOutOfOrder added in v1.0.1

func AllowOutOfOrder()

AllowOutOfOrder sets allowOutOfOrder true.

Not threads safe.

func Calibrate

func Calibrate()

Calibrate calibrates tsc clock.

It's a good practice that runs Calibrate periodically (e.g., 5 min is a good start).

func CalibrateWithCoeff added in v1.0.1

func CalibrateWithCoeff(c float64)

CalibrateWithCoeff calibrates coefficient to wall_clock by variables.

Not thread safe, only for testing.

func ForbidOutOfOrder added in v1.0.1

func ForbidOutOfOrder()

ForbidOutOfOrder sets allowOutOfOrder false.

Not threads safe.

func GetCurrentClockSource added in v1.2.1

func GetCurrentClockSource() string

GetCurrentClockSource gets clock source on Linux.

func GetInOrder added in v0.0.3

func GetInOrder() int64

GetInOrder gets tsc value in strict order. It's used to help calibrating to avoid out-of-order issues.

func IsOutOfOrder added in v1.0.1

func IsOutOfOrder() bool

IsOutOfOrder returns allow out-of-order or not.

Not threads safe.

func LoadOffsetCoeff added in v1.1.1

func LoadOffsetCoeff(src *byte) (offset int64, coeff float64)

Same logic as unixNanoTSC16B for checking getting offset & coeff correctly.

func RDTSC added in v0.0.3

func RDTSC() int64

RDTSC gets tsc value out-of-order.

func Supported added in v0.0.3

func Supported() bool

Supported indicates Invariant TSC supported.

Types

This section is empty.

Directories

Path Synopsis
internal
tools
calibrate command
longdrift command

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL