7

アプリケーションの関数にかかった時間を調べる必要があります。アプリケーションは MS VIsual Studio 2005 ソリューションで、すべて C コードです。

Windows API GetLocalTime(SYSTEMTIME *) を使用して、時間を測定したい関数呼び出しの前後の現在のシステム時間を取得しました。ただし、これには最低分解能が 1msec しかないという欠点があります。それ以下はありません。したがって、マイクロ秒単位で時間の粒度を取得することはできません。

エポック時間からの経過時間を与える time() の分解能も 1msec (マイクロ秒なし) であることを知っています。

1.) 関数で消費される時間を測定するために使用できるマイクロ秒単位の時間を提供する他の Windows API はありますか?

-広告

4

4 に答える 4

10

他にもいくつかの可能性があります。

QueryPerformanceCounterおよびQueryPerformanceFrequency

QueryPerformanceCounterは、「パフォーマンスカウンター」を返します。これは、実際には、コンピューターの電源投入時に0から増分するCPU管理の64ビットカウンターです。このカウンターの頻度は、QueryPerformanceFrequencyによって返されます。時間基準を秒単位で取得するには、パフォーマンスカウンターをパフォーマンス頻度で割ります。Delphiの場合:

function QueryPerfCounterAsUS: int64;     
begin
  if QueryPerformanceCounter(Result) and
     QueryPerformanceFrequency(perfFreq)
  then
    Result := Round(Result / perfFreq * 1000000);
  else
    Result := 0;
end;

マルチプロセッサプラットフォームでは、QueryPerformanceCounterは、スレッドが現在実行されているCPUに関係なく、一貫した結果を返す必要があります。ただし、通常はハードウェアチップまたはBIOSのバグが原因で問題が発生することがあります。通常、パッチはマザーボードメーカーから提供されます。MSDNからの2つの例:

QueryPerformanceCounterのもう1つの問題は、非常に遅いことです。

RDTSC命令

コードを1つのCPU(SetThreadAffinity)に制限できる場合は、RDTSCアセンブラー命令を使用して、プロセッサーから直接パフォーマンスカウンターを照会できます。

function CPUGetTick: int64;
asm
  dw 310Fh // rdtsc
end;

RDTSCの結果は、QueryPerformanceCounterと同じ頻度で増分されます。これをQueryPerformanceFrequencyで除算して、時間を秒単位で取得します。

QueryPerformanceCounterは、複数のCPUと可変周波数のCPUを考慮に入れる必要があるため、RDTSCよりもはるかに低速です。Raymon Chenのブログから:

(QueryPerformanceCounter)は経過時間をカウントします。その値は1秒あたりのユニット数を指定する数値を返すQueryPerformanceFrequency関数によって管理され、システムの実行中に頻度が変化しないように指定されているため、これを行う必要があります。

可変速度で実行できるCPUの場合、これは、経過時間と相関関係がないため、HALがRDTSCのような命令を使用できないことを意味します。

timeGetTime

TimeGetTimeは、Win32マルチメディアWin32関数に属しています。少なくとも最新のハードウェアでは、1ミリ秒の解像度でミリ秒単位の時間を返します。時間の測定を開始する前にtimeBeginPeriod(1)を実行し、終了したらtimeEndPeriod(1)を実行しても問題はありません。

GetLocalTimeおよびGetSystemTime

Vistaより前では、GetLocalTimeGetSystemTimeの両方がミリ秒の精度で現在の時刻を返しますが、ミリ秒の精度ではありません。それらの精度は通常、10〜55ミリ秒の範囲です。(精度は精度と同じではありません)Vistaでは、GetLocalTimeとGetSystemTimeはどちらも1ミリ秒の解像度で動作します。

于 2008-09-08T14:06:28.807 に答える
2

マルチプロセッサ システムに関する 1 つの注意事項:

http://msdn.microsoft.com/en-us/library/ms644904(VS.85).aspxから

マルチプロセッサ コンピュータでは、どのプロセッサが呼び出されるかは重要ではありません。ただし、基本入出力システム (BIOS) またはハードウェア アブストラクション レイヤー (HAL) のバグにより、異なるプロセッサでは異なる結果が得られる可能性があります。スレッドのプロセッサ アフィニティを指定するには、SetThreadAffinityMask 関数を使用します。

アル・ウェイナー

于 2008-12-10T17:07:55.760 に答える
2

2 点間の「ティック」数を提供するclock()の使用を試みることができます。「ティック」は、プロセッサが測定できる時間の最小単位です。

補足として、clock() を使用して実際の時間を決定することはできません。プログラム内の 2 つのポイント間のティック数のみです。

于 2008-09-08T13:12:25.567 に答える
1

Windowsでは、「高性能カウンターAPI」を使用できます。詳細については、 QueryPerformanceCounterおよびQueryPerformanceCounterFrequencyを確認してください。

于 2008-09-08T13:39:12.927 に答える