summaryrefslogtreecommitdiff
path: root/tier0/pmc360.cpp
blob: 0d18441b4a4f0d8800b8c9514fdb3c9eb20abea6 (plain) (blame)
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
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose: Inner workings of Performance Monitor Counters on the xbox 360; 
// they let vprof track L2 dcache misses, LHS, etc.
//
//=============================================================================//

#include "pch_tier0.h"

#ifndef _X360
#error pmc360.cpp must only be compiled for XBOX360! 
#else

#include "tier0/platform.h"
#include "tier0/vprof.h"
#include <pmcpbsetup.h>
#include "tier0/dbg.h"
#include "pmc360.h"

#include "tier0/memdbgon.h"

static bool s_bInitialized = false;

CPMCData::CPMCData() 
{
}

void CPMCData::InitializeOnceProgramWide( void )
{
#if !defined( _CERT )
	// Select a set of sixteen counters
	DmPMCInstallAndStart( PMC_SETUP_FLUSHREASONS_PB0T0 );
	// Reset the Performance Monitor Counters in preparation for a new sampling run.
	DmPMCResetCounters();
#endif
	s_bInitialized = true;
}

bool CPMCData::IsInitialized()
{
	return s_bInitialized;
}

void CPMCData::Start()
{
#if !defined( _CERT )
	// stop the stopwatches, save off the counter, start them again.
	DmPMCStop();

	PMCState pmcstate;
	// Get the counters.
	DmPMCGetCounters( &pmcstate );

	// in the default state as set up by InitializeOnceProgramWide, 
	// counters 9 and 6 are L2 misses and LHS respectively
	m_OnStart.L2CacheMiss = pmcstate.pmc[9];
	m_OnStart.LHS = pmcstate.pmc[6];

	DmPMCStart();
#endif
}

void CPMCData::End()
{
#if !defined( _CERT )
	DmPMCStop();

	// get end-state counters
	PMCState pmcstate;
	// Get the counters.
	DmPMCGetCounters( &pmcstate );

	// in the default state as set up by InitializeOnceProgramWide, 
	// counters 9 and 6 are l2 misses and LHS respectively
	const uint64 &endL2 = pmcstate.pmc[9];
	const uint64 &endLHS = pmcstate.pmc[6];

	// compute delta between end and start. Because these are 
	// unsigned nums, even in overflow this still works out
	// correctly under modular arithmetic.
	m_Delta.L2CacheMiss = endL2 - m_OnStart.L2CacheMiss;
	m_Delta.LHS = endLHS - m_OnStart.LHS;

	DmPMCStart();
#endif
}

#endif