Skip to content

Commit

Permalink
GetCurrentClockSource if CPUID detection failed
Browse files Browse the repository at this point in the history
  • Loading branch information
templexxx committed Feb 14, 2022
1 parent 14bc2b8 commit fc01e48
Show file tree
Hide file tree
Showing 3 changed files with 46 additions and 5 deletions.
18 changes: 14 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -146,9 +146,18 @@ If `tsc.Supported() == true`, it'll use tsc register. If not, it'll wrap `time.N

1. Using tools provided by this repo to learn how it works: [calibrate](tools/calibrate/README.md), [longdrift](tools/longdrift/README.md).
And these tools could help you to detect how stable the tsc register & this lib is in your environment.
2. If your application doesn't care the accuracy of clock too much, you could invoke `tsc.ForceTSC()` for allowing unstable frequency.
3. Invoke `tsc.Calibrate()` periodically if you need to catch up system clock. 5 mins is a good start because the auto NTP adjust is always every 11 mins.
4. Set in-order execution by `tsc.ForbidOutOfOrder()` when you need to measure time cost for short statements.
2. Invoke `tsc.Calibrate()` periodically if you need to catch up system clock. 5 mins is a good start because the auto NTP adjust is always every 11 mins.
3. Set in-order execution by `tsc.ForbidOutOfOrder()` when you need to measure time cost for short statements.

#### Virtual Machine

On vm, the CPU feature detection may cannot work as expect because the CPUID limitation, the Invariant TSC feature cannot be detected if so.

But if the tsc is the system clock source which means this cloud provider could handle tsc clock source well enough, in that situation this lib will enable TSC as clock source too.

Some cloud vm could support tsc as clock source, e.g., [AWS EC2](https://aws.amazon.com/premiumsupport/knowledge-center/manage-ec2-linux-clock-source/?nc1=h_ls)

Please contact your vm supports team to make sure the tsc clock source is reliable before using it.

## Limitation

Expand All @@ -160,4 +169,5 @@ And these tools could help you to detect how stable the tsc register & this lib

1. [Question of linux gettimeofday on StackOverflow](https://stackoverflow.com/questions/13230719/how-is-the-microsecond-time-of-linux-gettimeofday-obtained-and-what-is-its-acc)
2. [Question of TSC frequency variations with temperature on Intel community](https://community.intel.com/t5/Software-Tuning-Performance/TSC-frequency-variations-with-temperature/td-p/1098982)
3. [Question of TSC frequency variations with temperature on Intel community(2)](https://community.intel.com/t5/Software-Tuning-Performance/TSC-frequency-variations-with-temperature/m-p/1126518)
3. [Question of TSC frequency variations with temperature on Intel community(2)](https://community.intel.com/t5/Software-Tuning-Performance/TSC-frequency-variations-with-temperature/m-p/1126518)
4. [Pitfalls of TSC Usage](http://oliveryang.net/2015/09/pitfalls-of-TSC-usage)
27 changes: 27 additions & 0 deletions tsc.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
package tsc

import (
"io/ioutil"
"os"
"runtime"
"sync"
"time"

Expand Down Expand Up @@ -104,3 +107,27 @@ func IsOutOfOrder() bool {
func isEven(n int) bool {
return n&1 == 0
}

var (
linuxClockSourcePath = "/sys/devices/system/clocksource/clocksource0/current_clocksource"
)

// GetCurrentClockSource gets clock source on Linux.
func GetCurrentClockSource() string {

if runtime.GOOS != "linux" {
return ""
}

f, err := os.Open(linuxClockSourcePath)
if err != nil {
return ""
}
defer f.Close()

d, err := ioutil.ReadAll(f)
if err != nil {
return ""
}
return string(d)
}
6 changes: 5 additions & 1 deletion tsc_amd64.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,12 @@ func isHardwareSupported() bool {

// Invariant TSC could make sure TSC got synced among multi CPUs.
// They will be reset at same time, and run in same frequency.
// But in some VM, the max Extended Function in CPUID is < 0x80000007,
// we should enable TSC if the system clock source is TSC.
if !cpu.X86.HasInvariantTSC {
return false
if GetCurrentClockSource() != "tsc" {
return false // Cannot detect invariant tsc by CPUID or linux clock source, return false.
}
}

// Some instructions need AVX, see tsc_amd64.s for details.
Expand Down

0 comments on commit fc01e48

Please sign in to comment.