Почему мой 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
Я бы предположил, что он считывает размеры файлов из вашего постоянного хранилища, что объясняет, почему ваш процессор используется не полностью.