Delphi时间粒度问题?(200分)

  • 主题发起人 主题发起人 gohigh
  • 开始时间 开始时间
G

gohigh

Unregistered / Unconfirmed
GUEST, unregistred user!
[?]在Delphi的有关时间的函数中,取得当前时间据我所知有Now, Time。都是TDateTime类型的,
计时精度最多只能达到毫秒级。我目前正在编制有关网络测试方面的程序,需要计时精度达到
微秒级,有谁知道怎么办吗?

先谢了!
 
你可以查查《delphi深度历险》中的高分辨率性能计数器部分
网络中有电子书,你自己查查吧,精确到8微妙
function queryperformancefrequency(
; var lpfrequency:tlargeinteger):bool;stdcall;
 
这款控件是奔腾RDTSC指令的封装,使你能够得到十亿分之一秒的时间间隔,而且使用非常简单。
{ -----------------------------------------------------------------------------}
{ Copyright 2000-2001, Zloba Alexander. ;All Rights Reserved. ; ; ; ; ; ; ; ; ;}
{ This unit can be freely used and distributed in commercial and private ; ; ; }
{ environments, provided this notice is not modified in any way. ; ; ; ; ; ; ; }
{ -----------------------------------------------------------------------------}
{ Feel free to contact me if you have any questions, comments or suggestions at}
{ ; zal@specosoft.com (Zloba Alexander) ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ;}
{ You can always find the latest version of this unit at: ; ; ; ; ; ; ; ; ; ; ;}
{ ; http://www.specosoft.com ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; }

{ -----------------------------------------------------------------------------}
{ Date last modified: ;20/04/2001 ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ;}
{ -----------------------------------------------------------------------------}
{ Description: ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; }
{ ; This unit include function to work with RDTSC instruction of pentium ; ; ; }
{ ; ;processors ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ;}
{ ;Example 1: ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ;}
{ ; ; var ticks:int64; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; }
{ ; ; ... ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ;}
{ ; ; ticks := cpugettick; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; }
{ ; ; ;dosomething; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ;}
{ ; ; label1.caption := format('"dosomething" time = %d ms',[cpugetms(ticks)]) }
{ ;Example 2: ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ;}
{ ; ; var tick1,tick2:int64; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; }
{ ; ; ... ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ;}
{ ; ; tick1 := cpugettick; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; }
{ ; ; ;dosomething; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ;}
{ ; ; tick2 := cpugettick; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; }
{ ; ; ;... // do other work ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ;}
{ ; ; label1.caption := format('"dosomething" time = %d ms', ; ; ; ; ; ; ; ; ; }
{ ; ; ; ; ; ; ; ; ; ; ; ; ; ; ;[cpucalcms(tick2,tick1)]) ; ; ; ; ; ; ; ; ; ; ; }
{ ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ;}
{------------------------------------------------------------------------------}
{ Revision History: ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ;}
{ 1.00: ;+ First public release ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ;}
{------------------------------------------------------------------------------}


unit rdtsc;

interface

uses windows,dialogs;

//
// ;Used when determine the CPU frequency
//
const SleepTime:dword = 200;

Var
//
// ;CPU frequency MHz
//
; CPUFrequency : dword = 0;

//
// ;_1CPUFrequencyMS := 0.001/CPUFrequency
//
; _1CPUFrequencyMS : single;
; _1CPUFrequencyMKS : single;

//
// Measure CPU frequency
//
; function cpuGetSpeed: WORD;

; function cpuGetTick:int64;
; Function cpuGetms( Tick:int64 ):dword;
; Function cpuGetmks( Tick:int64 ):dword;
; function cpucalcms(const Tick1,Tick2:int64 ):int64;
; Function cpucalcmks(const Tick1,Tick2:int64 ):int64;

implementation

var inited:boolean=false;

function cpugettick:int64;
asm
; ; dw 310Fh // rdtsc
;End;

Function cpugetms( Tick:int64 ):dword;
begin
; asm
; ; dw 310Fh // rdtsc
; ; sub eax, dword [Tick]
; ; sbb edx, dword [Tick+4]
; ; mov dword[Tick], eax
; ; mov dword[Tick+4], edx
; end;
; if not inited then cpugetspeed;
; result:=round(Tick*_1CPUFrequencyMS);
end;

Function cpugetmks( Tick:int64 ):dword;
begin
; asm
; ; dw 310Fh // rdtsc
; ; sub eax, dword [Tick]
; ; sbb edx, dword [Tick+4]
; ; mov dword[Tick], eax
; ; mov dword[Tick+4], edx
; end;
; if not inited then cpugetspeed;
; result:=round(Tick*_1CPUFrequencyMKS);
end;

function cpucalcmks(const Tick1,Tick2:int64 ):int64;
begin
; if not inited then cpugetspeed;
; result:=round(abs(Tick2-Tick1)*_1CPUFrequencyMKS);
end;

function cpucalcms(const Tick1,Tick2:int64 ):int64;
begin
; if not inited then cpugetspeed;
; result:=round(abs(Tick2-Tick1)*_1CPUFrequencyMS);
end;

function CPUGetSpeed: WORD;
var _cpufreq: DWORD;
; ; len:integer;
; ; rh:HKEY;
; ; i1,i2,t:int64;
; ; pr:dword;
begin
; if CPUFrequency <> 0 then begin
; ;Result := CPUFrequency;
; ;exit;
; end;
; ;if regOpenKeyEx(HKEY_LOCAL_MACHINE,
; ; ; ; ; ; ; ; ; ;'HARDWARE/DESCRIPTION/System/CentralProcessor/0',
; ; ; ; ; ; ; ; ; ;0, KEY_READ, rh) = ERROR_SUCCESS
; ;then begin
; ; if RegQueryValueEx(rh,'~MHz', nil,@pr, @_cpufreq, @len) = ERROR_SUCCESS then
begin
; ; ;Result := _cpufreq;
; ; ;CPUFrequency := _cpufreq;
; ; end
; ; else begin
; ; ; ; pr := GetThreadPriority(GetCurrentThread );
; ; ; ; SetThreadPriority(GetCurrentThread,THREAD_PRIORITY_TIME_CRITICAL);
; ; ; ; QueryPerformanceCounter( i1 );
; ; ; ; t := cpugettick;
; ; ; ; Sleep(SleepTime);
; ; ; ; asm
; ; ; ; ; dw 310Fh // rdtsc
; ; ; ; ; sub eax, dword[t]
; ; ; ; ; sbb edx, dword[t+4]
; ; ; ; ; mov dword[t], eax
; ; ; ; ; mov dword[t+4], edx
; ; ; ; end;
; ; ; ; QueryPerformanceCounter( i2 );
; ; ; ; i2 := i2-i1;
; ; ; ; QueryPerformanceFrequency( i1 );
; ; ; ; i2 := i2*1000000 div i1;
; ; ; ; Result := round(t/(i2));
; ; ; ; CPUFrequency := Result;
; ; ; ; SetThreadPriority(GetCurrentThread,pr);
; ; end;
; ; RegCloseKey( rh );
; ;end;
; _1CPUFrequencyMS := 0.001/CPUFrequency;
; _1CPUFrequencyMKS := 1/CPUFrequency;
; ;inited := true;
end;
end.
 
谢谢以上两位仁兄!

使用QueryPerformanceFrequency可能会有问题,而Zloba的组件确实很容易使用。
(对不起,分数给反了。反正是游戏,以后再补上吧 :) ).
 
后退
顶部