Задачи параллелизма медленнее обычного выполнения? - PullRequest
0 голосов
/ 18 января 2012

Я немного запутался, потому что, когда я использую этот код:

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 секунд.

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

Спасибо

Ответы [ 2 ]

6 голосов
/ 18 января 2012

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

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

Множество вопросов.По сути, не думайте, что параллельный код выполняется быстрее.

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

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

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

0 голосов
/ 18 января 2012

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

...