【问题标题】:Parallel.For how to get number of threads that are using in loop?Parallel.For 如何获取循环中使用的线程数?
【发布时间】:2019-08-17 02:16:20
【问题描述】:

我对@9​​87654324@ 方法有疑问。

我想在图像处理算法中使用 1 到 4 个线程进行比较。我像这样设置我的Parallel.For

        ParallelOptions po = new ParallelOptions();
        po.MaxDegreeOfParallelism = 4;

        Parallel.For(0, height - 1, po, y =>
        {
            int offset = y * stride; //row
            for (int x = 0; x < width - 1; x++)
            {
                //do stuff here
            }
         });

时间以Stopwatch 类计算。

var stopwatch = Stopwatch.StartNew();
MethodWithParallelFor.Execute();
stopwatch.Stop();

我的问题是,为什么当我将MaxDegreeOfParallelism 设置为任何值(我的 CPU 有 8 个线程)时,我得到完全相同的时间?当我将 Degree 设置为 1 或 4 时,我得到相同的执行时间。

那么,如何调试Parallel.For 来获取信息,我的循环中有多少线程正在运行?如何强制程序使用我想要的那么多线程?如果需要,我可以分享我的完整代码

我在 c# 7.3 和 WPF 4.6.2 中实现了我的测试程序

【问题讨论】:

  • 您的图片有多大?报告了多少时间?
  • 我的头像是200x300px 8bpp,我得到15-20ms
  • 您的图像可能太小而无法并行化。MaxDegreeOfParallelism 只控制最大值;由线程池决定是否启动它认为合适的新线程。
  • 您不能“强制”它使用 x 个线程。 MaxDegreeOfParallelism 用于限制并发任务的数量。这并不意味着会使用一定数量的线程。实际使用的线程数是基于算法计算的,并且可能会不时发生变化。请参阅this 线程了解更多信息。如果你知道你总是想使用 x 个线程,你可以显式地创建线程。
  • 对我来说这听起来像是在做微基准测试。不要手动做这些事情(有很多陷阱),而是使用经过实战测试的工具,我个人建议使用BenchmarkDotNet

标签: c# multithreading parallel-processing task-parallel-library


【解决方案1】:

如果您只想知道 Parallel.For 在任何给定时间有多少线程同时运行,您可以使用 Interlocked.Increment 和 Interlocked.Decrement(在循环的开始和结束时),检查如果变量中的值比之前大,并在 Parallel.For 完成后输出,如下所示:

public void TestParallelism() {
    int maxThreads = 0;
    int currentThreads = 0;

    Parallel.For(0, 100, (i) => {

        var max = Interlocked.Increment(ref currentThreads);

        if (maxThreads < max) {
            maxThreads = max; 
        }

        // your code here...

        Interlocked.Decrement(ref currentThreads);
    });

    Console.WriteLine($ "Max Parallel Threads: {maxThreads}");
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-05-02
    • 2020-01-21
    • 1970-01-01
    • 1970-01-01
    • 2021-01-09
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多