C#(单核)不使用所有核
我们正在Mono上运行一个C#项目,我们希望利用多核CPU。我们正在使用C#(单核)不使用所有核,c#,multithreading,class,parallel-processing,mono,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
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");
}
}
}
使用系统;
使用System.Threading.Tasks;
命名空间Cognite.OptimizerMain
{
公共阶级三角
{
}
内部静态类程序
{
私有静态void Main(字符串[]args)
{
Console.WriteLine(“开始并行工作”);
双和=0.0;
Parallel.For(0,5000,node=>
{
对于(var k=0;k<1000000;k++)
{
sum+=Math.Abs(Math.Cos(k));
对于(var j=0;j<5000;j++)
{
//var测试_三角形=新三角形();
}
}
});
控制台写入线(总和);
控制台写入线(“结束的并行工作”);
}
}
}
如果按原样运行,它将占用700%-800%的CPU。如果您使用test\u triangle
取消对该行的注释,那么我们只使用了350%的CPU
我们正在使用这个build命令:msbuild Optimizer.sln/p:Configuration=Debug
并像这样运行程序mono program.exe
内存分配/垃圾回收会有问题吗?您永远不应该分析调试版本,因为在调试版本中有很多代码在发布版本中被删除,这给了您比发布版本更多的行为 您创建的新三角形基本上是无用的,因为它将在发布版本中被删除,因为没有结果将被使用 我没有mono,所以我尝试在windows计算机(.NET Core 2.1)上重现您描述的行为。我也可以通过调试构建看到您描述的行为。 发布版本的cpu使用率接近94%,调试版本的cpu使用率接近56% 线 我预计会发生这种情况,因为在调试构建中
var test_triangle = new Triangle();
被执行。在一个发布版本中,它被优化掉了,这可能导致整个for循环被优化掉了,而编译器可以优化第二个for循环等等,这在调试版本中是不会完成的。必须检查生成的IL代码以验证这一点,我现在懒得这么做。:)
因此,首先您应该对发布版本进行概要分析,其次为了获得更好的测试,您应该在内部循环中执行一些操作,这些操作将在程序结束时使用。为此,优化器无法删除循环。该程序在Linux上运行的时间是否显著延长?或者CPU使用率是唯一可见的影响?这也需要更长的时间来解决run@FredrikAnfinsen您使用的是哪种版本的Mono,因为在使用
Parallel.ForEach
时,我绝对看不到这一点。你的Parallel.ForEach到底是什么样子的。另外,请不要为代码使用图像,将格式化的代码直接粘贴到您的问题中(图像不可搜索、可索引、在不同屏幕大小上可读、可访问的限制等)@sushingover我使用的是Mono-JIT编译器版本5.14.0.177
。Parallel.ForEach
函数是system.Threading.Tasks
下的一个系统函数。我怀疑JIT足够聪明,可以在删除var test_triangle=new triangle()时删除无用的循环代码>行,从而使迭代更快地完成。我不确定这是否足以解释CPU使用率的差异。谢谢你的回复。这只是一个小例子,重现了我们在更大项目中遇到的问题。我们正在构建一个大项目,该项目的核心利用率与调试构建相同。
var test_triangle = new Triangle();