【问题标题】:Hyper-V PLINQ Virtual Machine Parallel issueHyper-V PLINQ 虚拟机并行问题
【发布时间】:2015-04-09 14:26:44
【问题描述】:

我有一个这样的 PLINQ 查询...

batch
.AsParallel()
.WithExecutionMode(ParallelExecutionMode.ForceParallelism)
.WithCancellation(cancellationToken);
.Select(i => new { instruction = i, accountKey = new AccountKey(i.x, i.y, i.z) })
.GroupBy(x => x.accountKey)
.ForAll(grouping =>
{
    foreach (var instructionBatch in grouping.OrderBy(i => i.instruction.FileRow).Select(i => i.instruction))
    {
        // High CPU method.
    }
});

在一个批次中,可以有 10,000 条记录。这些调用高 CPU 方法,该方法反过来调用 Web 服务并将信息保存到数据库。

在我的物理 64 位 pc i7-4770 CPU @ 3.40 GHz 16.0GB 内存上。运行此代码的服务会启动大约 32 个线程并占用大约 150,000 - 200,000 KB 的内存使用量。

在 64 位虚拟机 E5-2630 v3 @2.40GHz 的 Hyper-V 测试环境中,它生成超过 200 个线程,内存接近 2gb 限制。

有什么原因导致它启动了这么多线程以及为什么没有在虚拟机上释放内存?

我是否需要使用 WithDegreeOfParallelism。如果这个过程可能会同时调用 4 个不同的批次(例如 1 x 1 记录、1 x 100 记录、1 x 1000 和 1 x 10,000),这是否意味着当我指定 WithDegreeOfParallelism 时,这 4 个批次将分别触发线程数,甚至是 1 条记录的批次?

感谢您的帮助。

【问题讨论】:

    标签: multithreading parallel-processing virtual-machine hyper-v plinq


    【解决方案1】:

    TPL Parallel 和 PLINQ 工具不擅长处理 IO。他们倾向于选择错误的线程数。这些方法使用的线程数是启发式驱动的。我相信它是包含这种启发式的线程池。

    当 IO 发挥作用时,我强烈建议使用 WithDegreeOfParallelism。您可以使用Environment.ProcessorCount。如果涉及 IO,您可能希望稍微超额订阅并添加恒定数量的线程。

    在 PLINQ 中,WithDegreeOfParallelism 是一个绝对数量。不多也不少。所以是的,4 个并发查询导致线程数的 4 倍。我相信内置的自动线程计数启发式不会发生这个问题。

    考虑对所有并发查询使用固定并发 TaskScheduler

    这是一个实验:使用Thread.Sleep(1000000) 运行该循环。你会发现很多线程。大概,每 500 毫秒一个。当它认为需要更多线程来避免死锁和提高利用率时,这是注入线程的线程池方式。完全不适合 IO。

    【讨论】:

    • 感谢@usr。如果我将 TPL 与 MaxDegreeOfParallelism 并行使用。它似乎限制了线程。然而,我仍然看到的另一个问题是 Hyper-V 机器上的内存不断增加,直到接近 2GB 限制。在物理机上。您可以看到正在使用和释放的内存在 180,000 KB 左右。您知道这是环境问题还是我需要在应用程序中编写代码?
    • 我怀疑这是环境问题。也许不同的线程数或其他 IO 延迟配置文件。 PLINQ 存在/存在一个错误,即它并不总是及时释放对象引用。这可以让垃圾保持活力。考虑通过您手动清除的 PLINQ 推送包装器对象。例如,如果您在完成后在该列表上推送 List 调用 Clear。现在几乎是空的列表可能会保留,但不会保留原来的大列表。
    【解决方案2】:

    在运行性能监视器的最后,我注意到在虚拟化环境中,Perf 计数器# of Exceps Thrown / Sec 显示了一个非常高的数字。我关注http://blogs.msdn.com/b/spike/archive/2011/06/23/how-to-figure-out-what-exception-is-causing-a-high-number-in-of -exceps-throw-sec-using-procdump-and-windbg.aspx 并确定在尝试连接到 mysql 数据库时引发了未处理的异常。这是因为没有设置防火墙规则。

    关于并行性。正在启动高 CPU 方法下方的第二个“即发即忘”任务以生成字母。然而这并没有 围绕它的任何异常/日志处理。这是引发错误的地方。为了克服这个问题,我将 await Task.Run 包装在 try catch 中。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-11-10
      • 1970-01-01
      相关资源
      最近更新 更多