C#(单声道)未利用所有内核

时间:2018-08-15 19:37:59

标签: c# multithreading class parallel-processing mono

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

我们尝试调试时没有任何运气,但发现有些奇怪。但是设法用下面的代码片段重现了这个问题:

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

运行程序

内存分配/垃圾回收有问题吗?

1 个答案:

答案 0 :(得分:0)

您永远不应该剖析调试版本,因为在调试版本中,很多代码会在发行版本中删除,并且给您带来除发行版本之外的其他行为。

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

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

var test_triangle = new Triangle();

我希望发生这种情况是因为在调试中建立了行

var test_triangle = new Triangle();

被执行。在发行版本中,它已经进行了优化,这可能导致优化整个for循环,而编译器则可以优化第二个for循环,依此类推,这在调试版本中不会完成。必须检查生成的IL代码以验证这一点,我现在太懒了。 :)

因此,首先您应该概要分析发行版本,其次要进行更好的测试,您应该在内部循环内执行一些操作,以在编程结束时使用。为此,优化器无法删除循环。