【问题标题】:C# (mono) not utilizing all coresC#(单声道)不使用所有内核
【发布时间】:2019-01-22 17:17:03
【问题描述】:

我们正在 Mono 中运行一个 C# 项目,我们希望利用多核 CPU。我们正在使用System.Threading.Tasks.Parallel.For 这样做。但是我们在$ top 中看到,当我们在 8 核笔记本电脑上运行时,Mono 仅使用 350% 的 CPU(这很奇怪,我们预计会使用 700 - 800%)。

我们尝试调试它没有任何运气,但我们发现了一些奇怪的东西。但设法用这段代码 sn-p 重现问题:

using System;
using System.Threading.Tasks;

namespace Cognite.OptimizerMain
{
  public class Triangle
  {
  }

  internal static class Program
  {
    private static void Main(string[] args)
    {
      Console.WriteLine("Starting parallel work");
      double sum = 0.0;
      Parallel.For(0, 5000, node =>
      {
        for (var k = 0; k < 1000000; k++)
        {
          sum += Math.Abs(Math.Cos(k));
          for (var j = 0; j < 5000; j++)
          {
            // var test_triangle = new Triangle();
          }
        }
      });
      Console.WriteLine(sum);
      Console.WriteLine("Ended parallel work");
    }
  }
}

如果您按原样运行它,它会占用 700% - 800% 的 CPU。如果您取消注释 test_triangle 行,那么我们只使用了 350% 的 CPU。

我们正在使用这个构建命令:msbuild Optimizer.sln /p:Configuration=Debug 并像这样运行程序mono program.exe

内存分配/垃圾回收会不会有什么问题?

【问题讨论】:

  • 程序在 Linux 上运行的时间是否明显延长?还是 CPU 使用率是唯一可见的影响?
  • 运行时间也较长
  • @FredrikAnfinsen 您使用的是什么版本的 Mono,因为我在使用 Parallel.ForEach 时绝对看不到。您的 Parallel.ForEach 到底是什么样的。另外请不要使用图像作为代码,将格式化的代码直接粘贴到您的问题中(图像不可搜索、可索引、在不同的屏幕尺寸上可读、可访问的限制等。)
  • @SushiHangover 我正在使用Mono JIT compiler version 5.14.0.177Parallel.ForEach函数是System.Threading.Tasks下的系统函数。
  • 我怀疑 JIT 足够聪明,可以在删除 var test_triangle = new Triangle(); 行时删除无用的循环,从而使迭代更快地完成。我不确定这是否足以解释 CPU 使用率的差异

标签: c# multithreading class parallel-processing mono


【解决方案1】:

您永远不应该分析调试版本,因为在调试版本中有很多代码会在发布版本中被删除,这会给您带来不同于发布版本的行为。

您创建的新 Triangle 基本上是无用的,因为它将在发布版本中删除,因为没有将使用的结果。

我没有单声道,所以我尝试在 Windows 机器(.NET Core 2.1)上重现您描述的行为。通过调试版本,我也可以看到您描述的行为。 在发布版本中,我获得了近 94% 的 cpu 使用率,而在调试版本中,我获得了近 56% 的 CPU 使用率 线

var test_triangle = new Triangle();

我预计会发生这种情况,因为在调试构建行中

var test_triangle = new Triangle();

被执行。在发布版本中,它被优化了,这可能导致优化整个 for 循环,而不是编译器可以优化第二个 for 循环等等,这在调试版本中不会完成。必须检查生成的IL代码才能验证这一点,我现在懒得做。 :)

因此,首先您应该分析发布版本,其次为了获得更好的测试,您应该在程序结束时使用的内部循环内做一些事情。为此,优化器无法移除循环。

【讨论】:

  • 感谢您的回复。这只是一个小例子,用于重现我们在更大项目中遇到的问题。我们正在为大型项目构建发布,该项目对内核的利用与调试构建相同。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-11-08
  • 1970-01-01
  • 2010-12-15
  • 2019-04-16
  • 1970-01-01
相关资源
最近更新 更多