hvdebtim.cpp
来自「symbian 下的helix player源代码」· C++ 代码 · 共 649 行 · 第 1/2 页
CPP
649 行
/* ***** BEGIN LICENSE BLOCK *****
* Source last modified: $Id: hvdebtim.cpp,v 1.2.40.1 2004/07/09 01:56:06 hubbe Exp $
*
* Portions Copyright (c) 1995-2004 RealNetworks, Inc. All Rights Reserved.
*
* The contents of this file, and the files included with this file,
* are subject to the current version of the RealNetworks Public
* Source License (the "RPSL") available at
* http://www.helixcommunity.org/content/rpsl unless you have licensed
* the file under the current version of the RealNetworks Community
* Source License (the "RCSL") available at
* http://www.helixcommunity.org/content/rcsl, in which case the RCSL
* will apply. You may also obtain the license terms directly from
* RealNetworks. You may not use this file except in compliance with
* the RPSL or, if you have a valid RCSL with RealNetworks applicable
* to this file, the RCSL. Please see the applicable RPSL or RCSL for
* the rights, obligations and limitations governing use of the
* contents of the file.
*
* Alternatively, the contents of this file may be used under the
* terms of the GNU General Public License Version 2 or later (the
* "GPL") in which case the provisions of the GPL are applicable
* instead of those above. If you wish to allow use of your version of
* this file only under the terms of the GPL, and not to allow others
* to use your version of this file under the terms of either the RPSL
* or RCSL, indicate your decision by deleting the provisions above
* and replace them with the notice and other provisions required by
* the GPL. If you do not delete the provisions above, a recipient may
* use your version of this file under the terms of any one of the
* RPSL, the RCSL or the GPL.
*
* This file is part of the Helix DNA Technology. RealNetworks is the
* developer of the Original Code and owns the copyrights in the
* portions it created.
*
* This file, and the files included with this file, is distributed
* and made available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY
* KIND, EITHER EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS
* ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET
* ENJOYMENT OR NON-INFRINGEMENT.
*
* Technology Compatibility Kit Test Suite(s) Location:
* http://www.helixcommunity.org/content/tck
*
* Contributor(s):
*
* ***** END LICENSE BLOCK ***** */
/////////////////////////////////////////////////////////////////////////////
// CVvDebugTimer --
/* How to use it:
in C (here local creation of struct)
#include "hvdebtim.h"
struct CVvDebugTimer * pDebTim = newCVvDebugTimer();
ResetTime(pDebTim);//reset accu
StartTime(pDebTim);
Debugee();
StopAndAccuTime(pDebTim);
//AverageAndOutputAccuTime(pDebTim, "Resamp@22 kHz", 1);
OutputAccuTime(pDebTim, "Resamp@22 kHz", 1);
in C++:
#include "hvdebtim.h"
CVvDebugTimer DebTim01;
CVvDebugTimer DebTim02;
CVvDebugTimer DebTim03;
DebTim01.StartTime();
Debugee();
DebTim01.StopAndAccuTime();
//DebTim01.AverageAndOutputAccuTime("VvDecode", 1);
DebTim01.OutputAccuTime("VvDecode ", 1);
DebTim01.ResetTime();//reset accu
*/
#include <stdio.h>
#include "hvutils.h"
#include "hvdebtim.h"
#include "hxstrutl.h"
/********************************/
/* time helper functions */
extern "C" {
#if TIMERTYPE!=WIN31_TIME
static LARGE_INTEGER liFrequency = {0};
static S32 nFrequencyValid = FREQUENCY_NOTMEASURED;
#endif
/********************************/
void VvGetAbsCpuClocks(__int64 *time)
{
// _asm RdTsc ; Get count of cycles into EDX: EAX
_asm {
_emit 0x0F //0F 31 is RDTSC opcode: Reads Pentium CPU clock (costs only 6 clocks at Ring 0, 11 at Ring 3)
_emit 0x31 // into EDX:EAX
mov ebx, time
mov [ebx], eax;//Intel Little Endian
mov [ebx+4], edx
}
}
/********************************/
void VvZeroAbsCpuClocks(void) //Force Pentium clock to 0 (Can be done at Ring 0 only)
{
_asm{
mov ECX, 0x10 //Machine-specific register 10h is the Time Stamp Counter
xor EAX,EAX //Timestamp we want to set goes
xor EDX,EDX // into EDX:EAX
_emit 0x0F //WRMSR opcode is 0F 30
_emit 0x30
}
}
/********************************/
#define TOLERANCE 1 // Number of MHz to allow
// samplings to deviate from
// average of samplings.
// Initially set to 2.
#define ROUND_THRESHOLD 6
U32 GetRDTSCCpuSpeed()
{
unsigned long in_cycles=0; // Internal clock cycles during
// test
unsigned long ex_ticks=0; // Microseconds elapsed during
// test
unsigned long raw_freq=0; // Raw frequency of CPU in MHz
unsigned long norm_freq=0; // Normalized frequency of CPU
LARGE_INTEGER t0,t1; // Variables for High-
// Resolution Performance
// Counter reads
unsigned long freq =0; // Most current frequ. calculation
unsigned long freq2 =0; // 2nd most current frequ. calc.
unsigned long freq3 =0; // 3rd most current frequ. calc.
unsigned long total; // Sum of previous three frequency
// calculations
int tries=0; // Number of times a calculation has
// been made on this call to
// cpuspeed
unsigned long total_cycles=0, cycles; // Clock cycles elapsed
// during test
unsigned long stamp0, stamp1; // Time Stamp Variable
// for beginning and end
// of test
unsigned long total_ticks=0, ticks; // Microseconds elapsed
// during test
LARGE_INTEGER count_freq; // High Resolution
// Performance Counter
// frequency
#ifdef WIN32
int iPriority;
HANDLE hThread = GetCurrentThread();
#endif // WIN32;
if ( !QueryPerformanceFrequency ( &count_freq ) )
return raw_freq;//return 0
// On processors supporting the Read
// Time Stamp opcode, compare elapsed
// time on the High-Resolution Counter
// with elapsed cycles on the Time
// Stamp Register.
do { // This do loop runs up to 20 times or
// until the average of the previous
// three calculated frequencies is
// within 1 MHz of each of the
// individual calculated frequencies.
// This resampling increases the
// accuracy of the results since
// outside factors could affect this
// calculation
tries++; // Increment number of times sampled
// on this call to cpuspeed
freq3 = freq2; // Shift frequencies back to make
freq2 = freq; // room for new frequency
// measurement
QueryPerformanceCounter(&t0);
// Get high-resolution performance
// counter time
t1.LowPart = t0.LowPart; // Set Initial time
t1.HighPart = t0.HighPart;
#ifdef WIN32
iPriority = GetThreadPriority(hThread);
if ( iPriority != THREAD_PRIORITY_ERROR_RETURN ) {
SetThreadPriority(hThread, THREAD_PRIORITY_TIME_CRITICAL);
}
#endif // WIN32
while ( (unsigned long)t1.LowPart - (unsigned long)t0.LowPart<50) {
// Loop until 50 ticks have
// passed since last read of hi-
// res counter. This accounts for
// overhead later.
QueryPerformanceCounter(&t1);
__asm {
_emit 0x0F //0F 31 is RDTSC opcode: Reads Pentium CPU clock (costs only 6 clocks at Ring 0, 11 at Ring 3)
_emit 0x31 // into EDX:EAX
MOV stamp0, EAX
}
}
t0.LowPart = t1.LowPart; // Reset Initial
t0.HighPart = t1.HighPart; // Time
while ((unsigned long)t1.LowPart-(unsigned long)t0.LowPart<1000 ) {
// Loop until 1000 ticks have
// passed since last read of hi-
// res counter. This allows for
// elapsed time for sampling.
QueryPerformanceCounter(&t1);
__asm {
_emit 0x0F //0F 31 is RDTSC opcode: Reads Pentium CPU clock (costs only 6 clocks at Ring 0, 11 at Ring 3)
_emit 0x31 // into EDX:EAX
MOV stamp1, EAX
}
}
#ifdef WIN32
// Reset priority
if ( iPriority != THREAD_PRIORITY_ERROR_RETURN ) {
SetThreadPriority(hThread, iPriority);
}
#endif // WIN32
cycles = stamp1 - stamp0; // Number of internal
// clock cycles is
// difference between
// two time stamp
// readings.
ticks = (unsigned long) t1.LowPart - (unsigned long) t0.LowPart;
// Number of external ticks is
// difference between two
// hi-res counter reads.
// Note that some seemingly arbitrary mulitplies and
// divides are done below. This is to maintain a
// high level of precision without truncating the
// most significant data. According to what value
// ITERATIIONS is set to, these multiplies and
// divides might need to be shifted for optimal
// precision.
ticks = ticks * 100000;
// Convert ticks to hundred
// thousandths of a tick
ticks = ticks / ( count_freq.LowPart/10 );
// Hundred Thousandths of a
// Ticks / ( 10 ticks/second )
// = microseconds (us)
total_ticks += ticks;
total_cycles += cycles;
if ( ticks%count_freq.LowPart > count_freq.LowPart/2 )
ticks++; // Round up if necessary
freq = cycles/ticks; // Cycles / us = MHz
if ( cycles%ticks > ticks/2 )
freq++; // Round up if necessary
total = ( freq + freq2 + freq3 );
// Total last three frequency
// calculations
} while ( (tries < 3 ) ||
(tries < 20)&&
((abs(3 * freq -total) > 3*TOLERANCE )||
(abs(3 * freq2-total) > 3*TOLERANCE )||
(abs(3 * freq3-total) > 3*TOLERANCE )));
// Compare last three calculations to
// average of last three calculations.
// Try one more significant digit.
freq3 = ( total_cycles * 10 ) / total_ticks;
freq2 = ( total_cycles * 100 ) / total_ticks;
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?