为什么 CPU 使用率没有增加?

Why CPU usage not increase?

有第二个代码:

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。

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

这是windows限制?使用 Windows 服务器 2016。

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

 while (true)
        {
            var a = 1 + 2;
        }

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

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

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

您是否尝试过 运行ning UniqPicture 按顺序循环?我担心的是您的硬盘驱动器可能正在抖动。但一般来说,您的硬盘驱动器的输入/输出 (IO) 很可能需要花费相当长的时间,因此 CPU 在可以对 [中的图像进行操作之前等待相当长的时间=11=]。如果您可以将图像预加载到内存中,我认为 CPU 利用率会高得多,如果不是最大化您的 CPU.

排名不分先后,以下是一些想法

  1. 如果你按顺序 运行 会发生什么?这将使 CPU 上的一个核心最大化,但它可以防止硬盘驱动器抖动。如果有 100 个线程正在运行,那么硬盘驱动器需要同时处理很多请求。

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

new ParallelOptions { MaxDegreeOfParallelism = 1 },

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

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