blob: 6161e95ae29831e898a7395246984e1c49097c37 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
|
#include "stdafx.h"
#include "CpuProfiler.h"
namespace
{
using namespace Whisper;
inline int64_t qpcNow()
{
int64_t res;
QueryPerformanceCounter( (LARGE_INTEGER*)&res );
return res;
}
class CpuTimescale
{
uint64_t frequency = 0;
const int64_t tscStart;
const int64_t qpcStart;
uint64_t computeTscFrequency();
public:
CpuTimescale() :
tscStart( tscNow() ),
qpcStart( qpcNow() )
{ }
inline uint64_t computeTicks( uint64_t tsc )
{
uint64_t freq = frequency;
if( freq == 0 )
freq = computeTscFrequency();
return makeTime( tsc, freq );
}
};
uint64_t __declspec( noinline ) CpuTimescale::computeTscFrequency()
{
int64_t tsc = tscNow();
int64_t qpc = qpcNow();
tsc -= tscStart;
qpc -= qpcStart;
uint64_t qpcFreq;
QueryPerformanceFrequency( (LARGE_INTEGER*)&qpcFreq );
// Seconds = qpc / qpcFreq
// ticks per second = tsc / seconds = tsc * qpcFreq / qpc
uint64_t res = ( (uint64_t)tsc * qpcFreq + ( (uint64_t)qpc / 2 ) - 1 ) / (uint64_t)qpc;
frequency = res;
const double GHz = (double)(int64_t)res * 1.0E-9;
logDebug( u8"Computed CPU base frequency: %g GHz", GHz );
return res;
}
static CpuTimescale timescale;
}
uint64_t Whisper::ticksFromTsc( uint64_t tscDiff )
{
return timescale.computeTicks( tscDiff );
}
|