Почему загрузка процессора не увеличивается? - PullRequest
1 голос
/ 27 сентября 2019

Имея второй код:

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 (), мой ЦП привязывается к 12-13% и не более.Могу ли я использовать больше CPU% для выполнения этой операции?Почему бы не увеличить?

Я пытаюсь сделать это из Python, это также только 12-13%.Это Core i7 8700.

Единственный способ ускорить работу - запустить второе окно приложения.

Это предел Windows?Использование Windows Server 2016.

Я думаю, что это системный лимит, потому что, если я попробую этот простой код, он также будет связан с 12% ЦП!

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

Ответы [ 2 ]

2 голосов
/ 27 сентября 2019

Небольшое исследование показывает, что вы используете ImageFactory из https://imageprocessor.org/,, который упаковывает System.Drawing.Сам по себе System.Drawing часто является оберткой для GDI / GDI +, которая ... включает блокировки всего процесса, поэтому ваши попытки многопоточности будут сильно затруднены.Попробуйте лучшую библиотеку изображений.

1 голос
/ 27 сентября 2019

(См. Ответ Роберта Макки, хотя, возможно, это может быть связано с дисковым вводом-выводом, но, возможно, нет.)

Итак, я раньше не использовал Paralell.ForEach, но, похоже, вы должны запустить свой UniqPicture метод параллельно для всех файлов в данном каталоге.Я думаю, что ваш подход здесь хорош, но в конечном итоге ваш жесткий диск, вероятно, убивает скорость вашей программы (и наоборот).

Вы пытались запустить UniqPicture в цикле последовательно?Я обеспокоен тем, что твой жесткий диск может сломаться.Но в целом, наиболее вероятно, что ввод / вывод (IO) с вашего жесткого диска занимает значительное количество времени, поэтому процессор ждет значительное количество времени, прежде чем он сможет работать с изображениями в UniqPicture.Если бы вы могли предварительно загрузить изображения в память, я бы подумал, что загрузка ЦП будет намного выше, если не увеличить ваш ЦП.

В произвольном порядке, вот некоторые мысли

  1. Что произойдет, если вы запустите это последовательно?Это позволит максимально использовать одно ядро ​​процессора, но это может предотвратить перегрузку жесткого диска.Если было запущено 100 потоков, это означает, что на жесткий диск приходится много запросов одновременно.

Вы можете добавить эту опцию, чтобы она запускалась последовательно (или простоэто обычный цикл без Parallel.):

new ParallelOptions { MaxDegreeOfParallelism = 1 },

Возможно, попробуйте 2, 3 или 4 потока и посмотрите, не изменится ли что-либо.

  1. Проверьтеиспользование вашего жесткого диска в диспетчере задач.Какова задержка на жестком диске, где хранятся изображения?Какой процент, который Winows сообщает, что он занят?Вы хотите, чтобы жесткий диск был занят все время (100% использования), но вы также хотите, чтобы он захватывал ваши изображения с максимально возможной пропускной способностью, чтобы процессор мог выполнять свою работу.
  2. Вращающийся жесткий диск(HDD) имеет гораздо более низкие IOPS (IO в секунду), чем SSD в целом.У SSD обычно будет 1000-10000+ операций ввода-вывода в секунду, но, как я полагаю, у жесткого диска около 200, а пропускная способность обычно намного ниже.Твердотельный накопитель должен помочь вашей программе использовать процессор гораздо больше.
  3. Размер файлов изображений может оказать здесь влияние, опять же, относящийся к IO.
  4. Или, может быть, увидеть Роберт Макки ответ о том, что ваши темы становятся узкими.Может быть, лучшее использование процессора - 13%.Максимальное число ядер составляет 1/6 (ваш процессор имеет 6 ядер), что составляет ~ 16,7%, так что вы уже не так уж далеки от того, чтобы максимально использовать одно ядро.
  5. В конечном счете, сколько времени это займет.Загрузка ЦП должна масштабироваться обратно линейно (более высокая загрузка ЦП = меньшее время работы) со временем, которое требуется для запуска, но это время, чтобы быть уверенным, поскольку это реальный тест.
...