2012-01-18 2 views
0

Я немного смущен, потому что, когда я использую этот код:Задачи параллелизма медленнее обычного исполнения?

catalog.Elements = GetElements(myProvider.Elements); 
catalog.Programs = GetPrograms(myProvider.Programs); 
catalog.Details = GetDetails(myProvider.Details); 

У меня есть 4 секунды.

И когда я пытаюсь сделать это с задачами (.NET 4.0):

Task<List<Element>> elementsTask = Task.Factory.StartNew<List<Element>>(
    delegate { 
     return GetElements(myProvider.Elements); 
    }); 
Task<List<Program>> programsTask = Task.Factory.StartNew<List<Program>>(
    delegate { 
     return GetPrograms(myProvider.Programs); 
    }); 
Task<List<Detail>> detailsTask = Task.Factory.StartNew<List<Detail>>(
    delegate { 
     return GetDetails(myProvider.Details); 
    }); 

catalog.Elements = elementsTask.Result; 
catalog.Programs = programsTask.Result; 
catalog.Details = detailsTask.Result; 

я получаю 6 секунд.

Нормально ли, что это быстрее, когда я не использую параллелизм задачи?

Thanks

+1

как вы измеряете время? –

+0

Сколько ядер у вас есть? –

+0

С классом секундомера – ahikaz

ответ

6

Параллелизм принимает множество форм. Это полностью зависит от базового оборудования и проблемы, которую вы пытаетесь «параллелизировать».

В вашем случае вы можете получить конфликт ресурсов на уровне ЦП. Сколько ядер? Общий кеш? Вычислительные дорогостоящие процедуры? Очень легкие процедуры, поэтому накладные расходы на перекачку перевешивают прибыль? Доступны ли подпрограммы к общему состоянию?

Много вопросов. В принципе, не предполагайте, что параллельный код работает быстрее.

Извините, это не ответ на ваши проблемы с производительностью, но для этого вам нужно будет объяснить, что делает каждая процедура.

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

На самом деле, чтобы ответить на ваш вопрос: да, это может быть нормальным, но требует понимания проблемы, которую вы пытаетесь parallelise. Не принимайте этот пример как показатель ожидаемой производительности от TPL. Я всегда ем скромный пирог, когда речь заходит о ошибках или предположениях, которые я делаю с асинхронным кодом ...

+0

В этом коде я просто готовлю новые объекты с содержимым, которое я уже загрузил, поэтому не нужно обращаться к базе данных только с данными, обрабатывающими – ahikaz

+1

@ahikaz. В зависимости от аппаратного обеспечения, если среда выполнения решает перейти на разные потоки, потоки будут бороться за время процессора друг с другом. В многоядерных системах это часто не видно. В одной базовой системе вы можете увидеть переключение контекста, чтобы дать возможность использовать временные фрагменты потоков. Это расходы на переключение. Это более заметно по вычислительно-интенсивным задачам. –

+0

@AdamHouldsworth - не забывайте о сетевом трафике. –

0

Вместо того, чтобы просто накладывать потоки на два ядра, слепо создавая новые задачи, вы должны использовать метод ThreadPool.QueueUserWorkItem, так как это уже выполняет некоторую настройку производительности, например, для рециркуляции потоков и балансировки нагрузки.

Смежные вопросы