Linux 上的 .Net 5.0 空闲 CPU 使用率高于 Windows

Posted

技术标签:

【中文标题】Linux 上的 .Net 5.0 空闲 CPU 使用率高于 Windows【英文标题】:.Net 5.0 Idle CPU Usage on Linux higher than on Windows 【发布时间】:2021-06-04 10:34:52 【问题描述】:

根据以下代码(取自 https://medium.com/@jackwild/getting-cpu-usage-in-net-core-7ef825831b8b),我确定了用 C# (.Net 5.0) 编写的控制台应用程序的 CPU 使用率:

class Program

    static async Task Main(string[] args)
    
        Console.WriteLine("Hello World!");

        Process p = Process.GetCurrentProcess();

        while (true)
        
            await Task.Delay(2000);
            var cpuUsage = await GetCpuUsageForProcess(p);

            Console.WriteLine("CPU: " + cpuUsage + "%");
        
    

    static async Task<double> GetCpuUsageForProcess(Process proc)
    
        var startTime = DateTime.UtcNow;
        var startCpuUsage = proc.TotalProcessorTime;
        await Task.Delay(1000);

        var endTime = DateTime.UtcNow;
        var endCpuUsage = proc.TotalProcessorTime;
        var cpuUsedMs = (endCpuUsage - startCpuUsage).TotalMilliseconds;
        var totalMsPassed = (endTime - startTime).TotalMilliseconds;
        var cpuUsageTotal = cpuUsedMs / (Environment.ProcessorCount * totalMsPassed);
        return cpuUsageTotal * 100;
    

在 Windows 上运行应用程序时(通过调试或发布后),应用程序在空闲时的预期平均使用率为 0%。但是,当我在我的 linux VM 上运行完全相同的已发布代码时,空闲使用率介于 0 和 0.24 之间

来自窗口的示例输出:

CPU: 0%
CPU: 0%
CPU: 0%
CPU: 0%
CPU: 0%
CPU: 0%
CPU: 0%
CPU: 0%
CPU: 0%
CPU: 0%
CPU: 0%
CPU: 0%
CPU: 0%
CPU: 0%
CPU: 0%
CPU: 0%
CPU: 0%
CPU: 0%
CPU: 0%
CPU: 0%
CPU: 0%
CPU: 0%
CPU: 0%
CPU: 0%

Linux VM (ubuntu 18.04) 上的输出:

CPU: 0.12440051392340312%
CPU: 0.12427189099068557%
CPU: 0%
CPU: 0%
CPU: 0%
CPU: 0.24839400853779886%
CPU: 0%
CPU: 0%
CPU: 0%
CPU: 0%
CPU: 0.12470035751093696%
CPU: 0%
CPU: 0%
CPU: 0%
CPU: 0%
CPU: 0.24555489168426392%
CPU: 0%
CPU: 0%
CPU: 0%
CPU: 0%
CPU: 0%
CPU: 0%
CPU: 0.12460451772120468%
CPU: 0%
CPU: 0.12426320617164646%

这似乎出乎意料,因为代码是相同的,并且空闲不应该占用任何 cpu 时间。 现在,在示例中,如果它偶尔占用一些 cpu 时间为 0.1%,这似乎不是一个大问题,但在我们的主程序中,它仅在空闲时占用 0.2% - 2%(而在 Windows 上为 0%)并且逻辑似乎在 linux 上运行得有点慢。这让我想知道在 linux 上运行 .net 核心应用程序是否效率较低,或者我是否遗漏了一些东西,例如在使用 Process.TotalProcessorTime 属性时,在 linux 上计算的 cpu 使用率是否不同/更准确。

有什么方法可以从运行时环境中找出导致 CPU 使用率的原因吗?我尝试使用 perf (https://docs.microsoft.com/en-us/dotnet/core/diagnostics/debug-highcpu?tabs=linux#trace-generation),但该报告并没有真正帮助我,因为我无法弄清楚是什么导致了 CPU 使用率。

【问题讨论】:

【参考方案1】:

为了确定导致 CPU 使用率的原因,我不确定,但根据https://github.com/dotnet/runtime/issues/2130 .NET Core 已知基于 linux 和 IIS 的服务器之间的性能差异,并且有两个不同的部署选项,IIS 和进程内托管适用于 Windows 和 Kestrel 进程外托管,这也会显着降低性能。

【讨论】:

感谢您的回答。我遇到了提到的 github 问题,它已有 1 年多的历史了,他们说他们将“在未来几个月内解决这个问题”。问题存在于在 VM 中运行 Windows 10 + Ubuntu 的同一台机器上,所以我不确定基于 IIS 的服务器是否相关。此外,Kestrel 进程外托管似乎只与 ASP.NET 相关,而与 .Net (Core) 5.0 无关

以上是关于Linux 上的 .Net 5.0 空闲 CPU 使用率高于 Windows的主要内容,如果未能解决你的问题,请参考以下文章

在哪里可以找到触发 unset() 上的垃圾收集的“低内存”和“空闲 CPU 周期”调用?

linux怎么看cpu使用率

cpu利用率

在 Linux 上调用哪个函数来唤醒 cpu

linux 性能自我学习 ———— cpu 高怎么办 [三]

仅在机器空闲时运行 cron 作业(linux)