4

Task Parallel Library と TPL Dataflow を使用すると、最大の並列度を指定できます。その値は上限であり、保証ではありません。実際、TPL は、システム リソースを含む多くの要因に基づいて、プログラマが指定した最大値を超えることなく、実際の並列度を決定します。

ある時点で TPL が行った並列度の選択を決定するメカニズムはありますか?

TPL Dataflow を使用するためにいくつかのかなり複雑なコードを移植したため、具体的に質問していますが、全体的なスループットは元のコードよりもはるかに少なくなっています。TPLが私に代わって行った選択を見て、なぜそれがはるかに遅いのかを理解したいと思います.

4

1 に答える 1

3

私はあなたと非常によく似た状況に遭遇しました。最終的にログ データを使用して、1 分間に使用されているスレッドの数を概算しました。これにより、大まかな数値が得られましたが、正確ではありません。

TPL がスレッドの使用に関するテレメトリを提供できるとは思えません。より正確なものを実装したい場合は、各タスク/スレッドにロジックを実装して、開始時刻と終了時刻の共有リストをマークすることをお勧めします。これは、開始するためにどのようにアプローチするかの例です。

public class DoSomeTPLWork
{
    public static void Start()
    {
        List<int> numberList = Enumerable.Range(1, 1000).ToList();

        Parallel.ForEach(numberList, number =>
            {
                ThreadTracking.ThreadStarted();

                int square = number * number;
                Console.WriteLine("Square of {0} is {1}", number, square);

                ThreadTracking.ThreadFinished();
            }
        );

        var threadInfo = ThreadTracking.GetThreadInfo();
    }
}

public class ThreadTracking
{
    private static ConcurrentBag<ThreadInfo> _threadInfo = new ConcurrentBag<ThreadInfo>();

    public static void ThreadStarted()
    {
        var threadInfo = new ThreadInfo(Thread.CurrentThread.ManagedThreadId);
        threadInfo.Start();
        _threadInfo.Add(threadInfo);
    }

    public static void ThreadFinished()
    {
        var threadInfo = _threadInfo.Where(ti => ti.ThreadId == Thread.CurrentThread.ManagedThreadId && !ti.Complete).SingleOrDefault();
        if(threadInfo != null)
        {
            threadInfo.Stop();
        }
    }

    public static List<ThreadInfo> GetThreadInfo()
    {
        return _threadInfo.ToList();
    }
}

public class ThreadInfo
{
    public bool Complete { get; set; }
    public int ThreadId { get; set; }
    public DateTime? TimeStarted { get; set; }
    public DateTime? TimeFinished { get; set; }

    public ThreadInfo(int threadId)
    {
        ThreadId = threadId;
    }

    public void Start()
    {
        TimeStarted = DateTime.Now;
        Complete = false;
    }

    public void Stop()
    {
        TimeFinished = DateTime.Now;
        Complete = true;
    }
}

データを使用すると、データをクエリするメソッドをいくつか追加するか、Excel にポップして操作するだけで、特定の 1 秒間に使用されているスレッドの数を確認できます。

于 2012-11-12T22:34:22.903 に答える