📄 hvdebtim.cpp
字号:
/* ***** 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 accuStartTime(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_TIMEstatic 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 6U32 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 + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -