为啥CPU使用率不增加?

Posted

技术标签:

【中文标题】为啥CPU使用率不增加?【英文标题】:Why CPU usage not increase?为什么CPU使用率不增加? 【发布时间】:2020-01-27 21:20:02 【问题描述】:

有第二个代码:

class Methods

    public MemoryStream UniqPicture(string imagePath)
    
        var photoBytes = File.ReadAllBytes(imagePath); // change imagePath with a valid image path
        var quality = 70;
        var format = ImageFormat.Jpeg; // we gonna convert a jpeg image to a png one
        var size = new Size(200, 200);

        using (var inStream = new MemoryStream(photoBytes))
        
            using (var outStream = new MemoryStream())
            

                using (var imageFactory = new ImageFactory())
                

                    imageFactory.Load(inStream)
                        .Rotate(new Random().Next(-7, 7))
                        .RoundedCorners(new RoundedCornerLayer(190))
                        .Pixelate(3, null)
                        .Contrast(new Random().Next(-15, 15))
                        .Brightness(new Random().Next(-15, 15))
                        .Quality(quality)
                        .Save(outStream);
                

                return outStream;
            
        
    

    public void StartUniq()
    
        var files = Directory.GetFiles("mypath");
        Parallel.ForEach(files, (picture) =>  UniqPicture(picture); );
    


当我启动 StartUniq() 方法时,我的 CPU 绑定到 12-13% 并且没有更多。我可以使用更多的 CPU % 来执行此操作吗?为什么不增加?

我尝试用 python 来做,也只有 12-13%。它是酷睿 i7 8700。

让它运行得更快的唯一方法是启动应用程序的第二个窗口。

这是窗口限制?使用 Windows Server 2016。

我认为这是系统限制,因为如果我尝试这个简单的代码,它也会绑定 12% 的 CPU!

 while (true)
        
            var a = 1 + 2;
        

【问题讨论】:

为什么你认为使用更多的 CPU 会使其运行得更快?您的 CPU 有 6 个内核,看起来像 100/6 => 16,所以它可能使用了一个内核(它没有针对多核处理进行优化)。如果您无法修改它以使其成为多线程,请并行处理更多文件。如果你只有一个文件要处理,那你可能就不走运了 我的猜测是,您可能是磁盘 IO 受限,或者您从 ImageFactory 使用的库可能是写成单线程的。 我会根据图像处理来衡量文件 I/O。其中一个可能比另一个更快。只有有了这些结果,我才会考虑如何优化。 我必须尝试启动它来创建新任务、新线程。还尝试为每张图像创建任务,没有一种方法可以帮助。 您是否尝试将 Thread.CurrentThread 的 Priority Property 增加到最高,或者 Process.GetCurrentProcess().PriorityClass = ProcessPriorityClass.RealTime(危险)? 【参考方案1】:

一些研究表明,您正在使用来自 https://imageprocessor.org/ 的 ImageFactory,它包装了 System.Drawing。 System.Drawing 本身通常是 GDI/GDI+ 的包装器,它...包含进程范围的锁,因此您对多线程的尝试将受到严重的瓶颈。试试更好的图片库。

【讨论】:

如果性能对您的项目真的很重要,那么您可能需要考虑使用imageresizing.net 进行调查,我过去曾在各种项目中使用过它,并且在性能方面工作得非常好。质量还可以,一些更高级的功能不是免费的,而且文件大小(压缩)不是很好。但它坚如磐石,速度超快。 感谢您的回答,我会尝试其他库。【参考方案2】:

(请参阅 Robert McKee 的回答,虽然这可能与磁盘 IO 有关,但也可能不是。)

所以,我以前没有使用过Paralell.ForEach,但您似乎应该为给定目录中的所有文件并行运行UniqPicture 方法。我认为您的方法在这里很好,但最终您的硬盘驱动器可能会降低程序的速度(反之亦然)。

您是否尝试过按顺序循环运行UniqPicture?我在这里担心的是您的硬盘驱动器可能会抖动。但总的来说,硬盘的输入/输出 (IO) 很可能需要相当长的时间,因此 CPU 需要等待相当长的时间才能对UniqPicture 中的图像进行操作。如果您可以将图像预加载到内存中,我认为 CPU 利用率会高得多,如果不是最大限度地利用您的 CPU。

没有特别的顺序,这里有一些想法

    如果按顺序运行会发生什么?这将最大限度地增加 CPU 上的一个核心,但它可以防止硬盘驱动器抖动。如果有 100 个线程正在启​​动,那么硬盘驱动器需要同时处理大量请求。

您应该能够添加此选项以使其按顺序运行(或仅使其成为没有Parallel. 的正常循环):

new ParallelOptions MaxDegreeOfParallelism = 1 ,

也许尝试 2、3 或 4 个线程,看看是否有任何变化。

    在任务管理器中检查您的硬盘驱动器利用率。存储图像的硬盘驱动器上的延迟是多少? Winows 将其报告为繁忙的百分比是多少?您希望硬盘驱动器一直处于忙碌状态(100% 使用率),但您还希望它以尽可能高的吞吐量抓取您的图像,以便 CPU 可以完成其工作。 一般来说,旋转硬盘驱动器 (HDD) 的 IOPS(每秒 IO)远低于 SSD。 SSD 通常有 1000 到 100,000+ IOPS,但我相信 HDD 大约是 200,而且吞吐量通常要低得多。 SSD 应该可以帮助您的程序更多地利用 CPU。 图像文件的大小可能会在此处产生影响,同样与 IO 相关。 或者查看Robert Mckee 的关于您的线程遇到瓶颈的回答。也许 13% 的 CPU 利用率是你能得到的最好的。 1 / 6(您的 CPU 有 6 个内核)的最大内核数约为 16.7%,因此实际上您已经离最大化一个内核的距离不远了。 最终,确定需要多长时间。 CPU 利用率应该与运行时间成反比(更高的 CPU 使用率 = 更低的运行时间),但时间只是为了确定,因为这是真正的基准测试。

【讨论】:

感谢您的回答!所以,MaxDegreeOfParallelism 不会改变一切。不确定它可以是我的 SSD - 当我在第二个窗口中启动我的应用程序时,它以相同的速度运行。不太明白为什么我的第一个窗口不能像两个应用程序窗口一样工作 @Keln 你是说如果你同时运行这个程序的两个实例(两个进程)你的CPU使用率会加倍吗?这基于其他 cmets 是有意义的,因为由于您使用的库,您可能仅限于一个线程。每个进程的使用率不会超过 ~16.7%(1 / 6 个内核),其中进程是程序的另一个“窗口”。即使您有 SSD,IO(读取图像的字节)仍然是需要考虑的重要因素,尽管(再次)可能是您使用的库是最大的瓶颈。

以上是关于为啥CPU使用率不增加?的主要内容,如果未能解决你的问题,请参考以下文章

为啥我的应用程序最小化时 CPU 使用率会增加?

为啥运行应用程序时 Eclipse CPU 使用率会增加?

求助!为啥X86以上的CPU指令集不提供给用户呢?比如X86-64,sSSE3等等。

CPU 特权环:为啥不使用环 1 和 2?

我电脑CPU的使用率突然达到100%静止不动,程序运行缓慢这是为啥?

为啥 pmap|reducers/map 不使用所有 cpu 内核?