Почему мой Parallel.Foreach не использует 10 потоков?

Кажется, что нет MinDegreeOfParallelism. Следующий код, похоже, использует только 1% ЦП, поэтому я подозреваю, что он НЕ использует ядра должным образом:

Parallel.ForEach(lls, new ParallelOptions { MaxDegreeOfParallelism = 10 },  GetFileSizeFSO);

Есть ли способ принудительно использовать 10 ядер / потоков?

Дополнительная информация:

private void GetFileSizeFSO(List<string> l)
{
    foreach (var dir in l)
    {

        var ds = GetDirectorySize3(dir);
        Interlocked.Add(ref _size, ds);
    }
}

    public static long GetDirectorySize3(string parentDirectory)
    {
        Scripting.FileSystemObject fso = new Scripting.FileSystemObject();
        Scripting.Folder folder = fso.GetFolder(parentDirectory);
        Int64 dirSize = (Int64)folder.Size;

        Marshal.ReleaseComObject(fso);


        return dirSize;
    }

4 ответа

Что твоя функция GetFileSizeFSO делать? Если он обращается к файлам на диске, это должно быть вашим основным потребителем времени. Процессор просто слишком быстрый, и диск не может догнать процессор. Таким образом, процессор имеет достаточно времени, чтобы сэкономить и ждать, пока жесткий диск завершит свою работу.

Если вам нужно оптимизировать свой код, вам лучше взглянуть на файлы более эффективно, чем пытаться загрузить процессор на 100%.

Это называется MaxDegreeOfParallelismне MinDegreeOfParallelism, Parallel предназначен для работы с процессором - нет смысла использовать больше потоков, чем у вас есть процессоры. Похоже, что ваша работа связана с вводом / выводом, а не с процессором, поэтому Parallel просто не подходящий инструмент для работы.

В идеале, найти асинхронный API, чтобы делать то, что вы пытаетесь сделать - это лучший способ использовать имеющиеся у вас ресурсы. Если нет асинхронного API, вам придется порождать эти потоки самостоятельно - однако не ожидайте увидеть загрузку процессора. И самое главное, измерить - очень возможно, что распараллеливание рабочей нагрузки вообще не улучшит пропускную способность (например, ввод-вывод уже может быть насыщенным).

ManInMoon, ваш процессор, вероятно, медленный, потому что основная часть работы, которую вы делаете, вероятно, связана с вашим механизмом хранения. 10 ядер, попадающих на один и тот же жесткий диск для получения размеров файлов, могут быть не быстрее, чем 2 ядра, потому что попадание и нанесение удара по жесткому диску является относительно (смешно) более дорогой операцией, чем имеющаяся у вас логика C#.

Итак, у вас нет проблемы с параллелизмом, у вас есть проблема ввода-вывода.

Примечание, возможно, не используйте FSO, используйте вместо этого.NET FileInfo.

Простой ответ - ты не можешь.

Но почему ты должен? .NET неплохо подходит для выбора оптимального количества используемых потоков. Использование MaxDegreeOfParallelism ограничивать параллелизм, а не форсировать его, например, если вы не хотите передавать все системные ресурсы в цикл.

Как примечание, судя по названию вашей функции GetFileSizeFSOЯ бы предположил, что он считывает размеры файлов из вашего постоянного хранилища, что объясняет, почему ваш процессор используется не полностью.

Другие вопросы по тегам