Skip to content

Commit 41376ef

Browse files
committed
implement fast TSC reading
1 parent 029a512 commit 41376ef

File tree

2 files changed

+36
-15
lines changed

2 files changed

+36
-15
lines changed

src/cpucounters.cpp

Lines changed: 34 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3448,11 +3448,11 @@ uint64 RDTSC();
34483448
void PCM::computeNominalFrequency()
34493449
{
34503450
const int ref_core = 0;
3451-
uint64 before = 0, after = 0;
3452-
MSR[ref_core]->read(IA32_TIME_STAMP_COUNTER, &before);
3453-
MySleepMs(1000);
3454-
MSR[ref_core]->read(IA32_TIME_STAMP_COUNTER, &after);
3455-
nominal_frequency = after-before;
3451+
const uint64 before = getInvariantTSC_Fast(ref_core);
3452+
MySleepMs(100);
3453+
const uint64 after = getInvariantTSC_Fast(ref_core);
3454+
nominal_frequency = 10ULL*(after-before);
3455+
std::cerr << "WARNING: Core nominal frequency has to be estimated\n";
34563456
}
34573457
std::string PCM::getCPUBrandString()
34583458
{
@@ -4095,6 +4095,18 @@ bool PCM::supportsRTM() const
40954095
return (info.reg.ebx & (0x1 << 11)) ? true : false;
40964096
}
40974097

4098+
bool PCM::supportsRDTSCP() const
4099+
{
4100+
static int supports = -1;
4101+
if (supports < 0)
4102+
{
4103+
PCM_CPUID_INFO info;
4104+
pcm_cpuid(0x80000001, info);
4105+
supports = (info.reg.edx & (0x1 << 27)) ? 1 : 0;
4106+
}
4107+
return 1 == supports;
4108+
}
4109+
40984110
#ifdef __APPLE__
40994111

41004112
uint32 PCM::getNumInstances()
@@ -4215,12 +4227,24 @@ bool PCM::decrementInstanceSemaphore()
42154227

42164228
uint64 PCM::getTickCount(uint64 multiplier, uint32 core)
42174229
{
4218-
return (multiplier * getInvariantTSC(CoreCounterState(), getCoreCounterState(core))) / getNominalFrequency();
4230+
return (multiplier * getInvariantTSC_Fast(core)) / getNominalFrequency();
42194231
}
42204232

4221-
uint64 PCM::getTickCountRDTSCP(uint64 multiplier)
4233+
uint64 PCM::getInvariantTSC_Fast(uint32 core)
42224234
{
4223-
return (multiplier*RDTSCP())/getNominalFrequency();
4235+
if (supportsRDTSCP())
4236+
{
4237+
TemporalThreadAffinity aff(core);
4238+
return RDTSCP();
4239+
}
4240+
else if (core < MSR.size())
4241+
{
4242+
uint64 cInvariantTSC = 0;
4243+
MSR[core]->read(IA32_TIME_STAMP_COUNTER, &cInvariantTSC);
4244+
if (cInvariantTSC) return cInvariantTSC;
4245+
}
4246+
std::cerr << "ERROR: cannot read time stamp counter\n";
4247+
return 0ULL;
42244248
}
42254249

42264250
SystemCounterState getSystemCounterState()
@@ -4292,7 +4316,7 @@ void BasicCounterState::readAndAggregateTSC(std::shared_ptr<SafeMsrHandle> msr)
42924316
const auto cpu_model = m->getCPUModel();
42934317
if (m->isAtom() == false || cpu_model == PCM::AVOTON)
42944318
{
4295-
msr->read(IA32_TIME_STAMP_COUNTER, &cInvariantTSC);
4319+
cInvariantTSC = m->getInvariantTSC_Fast(msr->getCoreId());
42964320
MSRValues[IA32_TIME_STAMP_COUNTER] = cInvariantTSC;
42974321
}
42984322
else
@@ -5544,7 +5568,7 @@ ServerUncoreCounterState PCM::getServerUncoreCounterState(uint32 socket)
55445568
//std::cout << "Energy status: " << val << "\n";
55455569
MSR[refCore]->read(MSR_PACKAGE_THERM_STATUS,&val);
55465570
result.PackageThermalHeadroom = extractThermalHeadroom(val);
5547-
MSR[refCore]->read(IA32_TIME_STAMP_COUNTER, &result.InvariantTSC);
5571+
result.InvariantTSC = getInvariantTSC_Fast(refCore);
55485572
readAndAggregatePackageCStateResidencies(MSR[refCore], result);
55495573
}
55505574
// std::cout << std::flush;

src/cpucounters.h

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1695,11 +1695,7 @@ class PCM_API PCM
16951695
//! \return time counter value
16961696
uint64 getTickCount(uint64 multiplier = 1000 /* ms */, uint32 core = 0);
16971697

1698-
//! \brief Return TSC timer value in time units using rdtscp instruction from current core
1699-
//! \param multiplier use 1 for seconds, 1000 for ms, 1000000 for mks, etc (default is 1000: ms)
1700-
//! \warning Processor support is required bit 27 of cpuid EDX must be set, for Windows, Visual Studio 2010 is required
1701-
//! \return time counter value
1702-
uint64 getTickCountRDTSCP(uint64 multiplier = 1000 /* ms */);
1698+
uint64 getInvariantTSC_Fast(uint32 core = 0);
17031699

17041700
//! \brief Returns uncore clock ticks on specified socket
17051701
uint64 getUncoreClocks(const uint32 socket_);
@@ -2101,6 +2097,7 @@ class PCM_API PCM
21012097

21022098
bool supportsHLE() const;
21032099
bool supportsRTM() const;
2100+
bool supportsRDTSCP() const;
21042101

21052102
bool useSkylakeEvents() const
21062103
{

0 commit comments

Comments
 (0)