10

Task非同期実行に (TPL) オブジェクトを使用するアプリケーションがあります。

メイン スレッドは、トリガー (何らかの TCP パケット) を待ってから、いくつかのタスクを実行します。私がやりたいのは、タスクに費やされた時間を測定することです。

コードを見てください。開始/停止Generatorで囲まれた長い操作 ( ) があります。Stopwatch's

Task.Factory.StartNew((t) => {

    Stopwatch sw = new Stopwatch();
    sw.Start();

    Generator g = new Generator();
    g.GenerateIntervals(); // lengthy operation

    sw.Stop();
    GlobalStopwatch.Add(sw.Elapsed);
});

これが問題です。ストップウォッチは の瞬間に使用DateTime.UtcNow.Ticksし、 の瞬間にStart()再び使用しStop()ます。次に、これら 2 つを減算して経過時間を取得します。

Generator問題は、(シングルスレッドシステムの) 他のスレッドが、 (コードから)GenerateIntervals()長い操作を実行している間に、ある程度のプロセッサ時間を取得できることです。つまり、ストップウォッチによって記録された経過時間には、Generaor.GenerateIntervals()時間だけでなく、その間に他のスレッドがジョブを実行した時間も含まれます。

タイムシェアリングメカニズムの結果として他のスレッドからの実行時間を含めずに、あるメソッドがどれだけのプロセッサ時間を要したかを正確に知る簡単な方法はありますか?

4

4 に答える 4

4

あなたの質問への答えは「いいえ」です... いいえ、特定thread.

(サイドラン:答える前に質問を読んで理解してほしい!!!)

processわかりました、あなたの質問に戻ります...あなたができる最も正確なことは、タスクごとに別々にスピンオフし、プロセスのCPU時間を測定することです(これは.Netで実行できます)...しかし、それはやり過ぎです。

その方法についてサポートが必要な場合は、そのために別の質問をする必要があります。

于 2011-12-12T14:13:42.370 に答える
1

ここに素敵な記事があります。それを使用するか、VS2010 の組み込みパフォーマンス アナライザーを使用してそれらの時間を比較できます。

于 2011-12-12T14:18:21.153 に答える
0

Windows API のQueryPerformanceCounter()およびQueryPerformanceFrequency()メソッドを使用して、タイマーが開始されてから経過したミリ秒数を取得できます。

using System;
using System.Runtime.InteropServices;
using System.ComponentModel;
using System.Threading;

namespace Win32
{
    internal class WinTimer
    {
        [DllImport("Kernel32.dll")]
        private static extern bool QueryPerformanceCounter(
            out long lpPerformanceCount);

        [DllImport("Kernel32.dll")]
        private static extern bool QueryPerformanceFrequency(
            out long lpFrequency);

        private long startTime, stopTime;
        private long freq;

        // Constructor
        public HiPerfTimer()
        {
            startTime = 0;
            stopTime  = 0;

            if (QueryPerformanceFrequency(out freq) == false)
            {
                // high-performance counter not supported
                throw new Win32Exception();
            }
        }

        // Start the timer
        public void Start()
        {
            // lets do the waiting threads there work
            Thread.Sleep(0);

            QueryPerformanceCounter(out startTime);
        }

        // Stop the timer
        public void Stop()
        {
            QueryPerformanceCounter(out stopTime);
        }

        // Returns the duration of the timer (in seconds)
        public double Duration
        {
            get
            {
                return (double)(stopTime - startTime) / (double) freq;
            }
        }
    }
}
于 2011-12-12T14:09:41.917 に答える
0

実際、答えはイエスです (ただし、相互運用を使用する必要があります)。

QueryThreadCycleTimeと呼ばれる WINAPI 関数があり、まさにこれを行います。

"指定されたスレッドのサイクル タイムを取得します。"

于 2012-10-20T00:08:39.367 に答える