2017-02-07 8 views
-1

Я использую System.Threading.Tasks.Parallel.ForEach(). По какой-то причине установка MaxDegreeOfParallelism на «-1» или даже «50» приводит к тому, что цикл работает быстрее (примерно 15 секунд, и он согласован). Значение по умолчанию параметра MaxDegreeOfParallelism равно -1 и установка его на 50 или любой другой номер должен только замедлять работу. В чем причина?Задание по умолчанию MaxDegreeOfParallelism приводит к ускорению работы параллельного цикла

System.Collections.Concurrent.ConcurrentBag<FileDataInfo> filesData = new System.Collections.Concurrent.ConcurrentBag<FileDataInfo>(); 
     System.Threading.Tasks.Parallel.ForEach(filesInfo, 
      new System.Threading.Tasks.ParallelOptions() { MaxDegreeOfParallelism = -1 }, 
      info => 
     { 
      if (!string.IsNullOrEmpty(info.FolderPath)) 
       info.FolderPath = System.IO.Path.Combine(dataPathDirName, info.FolderPath); 
      else 
       info.FolderPath = dataPathDirName; 

      var storageHandler = FileStorageFactory.CreateStorageHander(); 
      byte[] data = storageHandler.GetFileData(info.FilePath); 
      filesData.Add(new FileDataInfo() { Info = info, Data = data }); 
     }); 
+1

Ваше последнее предложение противоречит вашему первому предложению. –

+3

Можете ли вы перефразировать свой вопрос? В одном предложении вы говорите, что это быстрее, а затем вы говорите, что это медленнее. Что ты спрашиваешь? –

+1

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

ответ

0

MaxDegreeOfParallelism сообщает TPL, сколько вещей может работать одновременно. Это может повлиять на скорость выполнения во многих отношениях. Установив это значение на меньшее значение, он позволяет запускать задачи на своем собственном CPU/Core. Это заставляет вещи работать быстрее, потому что вы получаете хороший параллелизм. Если вы установите это значение выше (или -1), вы можете запускать больше задач с процессорами/ядрами. Когда это произойдет, время, затрачиваемое на совместное использование CPU между задачами, может занять значительное время и заставить операции выглядеть так, как будто они медленнее.

Общее правило: не устанавливайте параллелизм выше, чем количество ядер/процессоров в вашей системе.

0

Ваша проблема не связана с ЦП, она связана с I/O. Современные диски могут использовать большую очередь ввода-вывода для более эффективной работы. Используя Parallel.ForEach, вы заполняете эту очередь и позволяете приводу работать с максимальной эффективностью.

И хотя вы можете заметить ускорение здесь, хорошо заметить, что вы создаете большое количество потоков для этого. Чрезмерные потоки почти никогда не являются хорошей идеей, потому что она становится очень неэффективной из-за накладных расходов планировщика и сбоя кэша. Если возможно, я предлагаю преобразовать код для использования потока данных async и TPL. Это позволит вам использовать один поток для управления большим количеством параллельных запросов ввода-вывода.