|
|
||||||
PLINQ и работа с PFX03.01.2015, 10:36. Показов 61763. Ответов 4
Метки нет (Все метки)
Итак, приступим.
Небольшое отступление. На создание этой темы меня подтолкнуло чтение статьи с сайта RSDN (написанной, в свою очередь, на материале из книги Албахари, как я понимаю). В данной статье раскрываются тонкости работы PLINQ и библиотеки PFX (ParallelFramework), предназначенных для повышения производительности создаваемых приложений с учетом возрастания количества ядер процессоров на современных компьютерах. Почитав данные материалы, и поискав по форуму, я заметил, что данное направление пока еще мало раскрыто (именно на форуме), и поэтому, думаю, данный материал (особенно, если его поддержат те, у кого есть намного бОльший опыт в данной области) будет полезен. Сразу скажу, что я сам пока не профи в данной области, и буду благодарен за поддержку моего начинания. Первым делом рассмотрим самое простое - это запросы обычного LINQ. Штука очень удобная, вне всяких сомнений. Но как улучшить производительность для многоядерных компьютеров? Для этой цели в платформу .NET (начиная с версии 4.0) добавлено новое API - PLINQ. Предположим, мы имеем большой набор данных, который нам необходимо перебрать через запросы LINQ. Для повышения производительности мы можем использовать параллельные запросы. Вот простой пример кода. Верхняя часть - обычный запрос, нижняя - параллельный.
Несколько важных комментариев по приведенному коду: 1. Использование метода AsParallel() не гарантирует, что запрос ОБЯЗАТЕЛЬНО будет выполнен параллельно. Если PLINQ сделает вывод о том, что для улучшения производительности необходимо использовать обычный запрос, он будет выполнен именно так. 2. Для того, чтобы использовать именно параллельный запрос (даже если это затребует много ресурсов), после метода AsParallel() мы можем применить метод WithExecutionMode(), в котором указать параметр - один из членов перечисления ParallelExecutionMode, который и укажет коду, как следует выполнить запрос. В данном коде использован элемент ForceParallelism, который указывает, что запрос ОБЯЗАТЕЛЬНО должен быть выполнен параллельно, даже если потребуется больше ресурсов, чем для использования обычного запроса. 3. Так же есть возможность указать степень параллельности выполнения запроса - через статический метод WithDegreeOfParallelism(), с параметром типа int, который указывает, какое количество задач будет выполняться одновременно. В моем примере в качестве этого параметра используется число доступных ядер процессора на компьютере. Кроме данных методов, в PLINQ существуют и другие, и их использование будет постепенно рассмотрено. И напоследок, два скриншота с тестом для демонстрации преимуществ в скорости. Первый сделан на слабом нетбуке, на котором, собственно, и писался данный код. Как видно, использование параллельного запроса привело к увеличению времени выполнения, поскольку затребовало использования больше ресурсов. Второй скриншот сделан на достаточно мощном четырехядерном компьютере, и там сразу видны все преимущества параллельности - загрузка всех ядер процессора распределена равномерно, время выполнения параллельного запроса существенно снижено. Спасибо за внимание. Постепенно, по мере изучения мной возможностей PLINQ и PFX, данная тема будет дополняться новыми постами.
17
|
||||||
| 03.01.2015, 10:36 | |
|
Ответы с готовыми решениями:
4
Можно ли использовать PLINQ на .NET Framework 2.0
|
|
|
||||||
| 03.01.2015, 11:44 [ТС] | ||||||
|
Продолжим. В данном посте рассмотрим одну из особенностей PLINQ - порядок следования элементов в выходной последовательности.
Если используется обычный LINQ то порядок элементов в выходной последовательности соответствует их порядку во входной (не будем рассматривать фильтрацию последовательности, поскольку в данном случае, очевидно, не все члены входной последовательности присутствуют в выходной, хотя и в данном случае порядок следования сохранится). Но при использовании PLINQ данное правило меняется. То есть, не факт, что порядок следования элементов в выходной последовательности будет в точности соответствовать входной. В большинстве случаев это и не важно, однако если порядок следования элементов выходной последовательности должен точно следовать порядку входной, можно явно указать это, используя статический метод AsOrdered(). Это укажет PLINQ отслеживать позицию каждого элемента последовательности, что приведет к замедлению скорости работы. Если порядок следования последовательности после какого-либо запроса PLINQ уже не имеет значения, можно дать команду PLINQ прекратить отслеживание позиций элементов через статический метод AsUnordered(). Вот код, который это демонстрирует, и скриншот выполненной программы.
6
|
||||||
|
|
||||||
| 04.01.2015, 15:59 [ТС] | ||||||
|
Продолжаем тему.
Все мы в процессе использования LINQ часто используем анонимные типы, поскольку это удобно. Однако PLINQ вносит свои коррективы в практику. При использовании параллельных запросов наилучшим выбором будет использование не анонимных типов, а именованных структур. Происходит это из-за того, что структура - тип значения, и хранится в стеке. При параллельных запросах каждому потоку выделяется свой стек. При использовании же анонимных типов (которые, как известно, являются классами) всем потокам приходится обращаться к управляемой куче, что снижает производительность. Я провел несколько экспериментов, и выяснил такую закономерность (на своем железе): при количестве элементов последовательности менее 1000000 анонимные типы работают быстрее. При большем количестве элементов последовательности зависимость изменяется: работа с использованием именованной структуры резко ускоряется, и чем больше элементов, тем четче видна эта разница. Ниже пример кода и скриншот, который показывает разницу в скорости (количество элементов последовательности - 1000000), при различных вариантах (структура-анонимный тип).
10
|
||||||
|
|
|||||||||||
| 10.01.2015, 14:05 [ТС] | |||||||||||
|
Продолжу тему. Рассмотрим два вопроса: отмена параллельных операция и оптимизация параллельной работы.
Для отмены параллельной операции необходимо использовать расширяющий метод WithCancellation(), в который передать объект - маркер отмены - свойство Token объекта CancellationTokenSource, созданного перед этим. После того, как объект отмены создан, вызов его метода Cancel() приведет к передаче в параллельные вычисления объекта CancellationToken, после чего все потоки, выполняющие параллельные вычисления, будут завершены. Необходимо отметить, что в данном случае необходима обязательная обработка ошибок в параллельном коде, поскольку вызов этого метода привод к генерации OperationCanceledException(). Ниже приведен небольшой пример с комментариями к коду.
Ниже приведен простой пример использования данного метода.
7
|
|||||||||||
| 24.08.2015, 11:05 | |||||||
0
|
|||||||
| 24.08.2015, 11:05 | |
|
Помогаю со студенческими работами здесь
5
PLINQ: Читать файл, каждую строку преобразовывать и записывать преобразованную строку в другой файл Многопоточность с TPL и PLINQ
Найти среднее квадратическое отклонение от всех чисел последовательности с помощью PLINQ Искать еще темы с ответами Или воспользуйтесь поиском по форуму: |
|
| Опции темы | |
|
|
Новые блоги и статьи
|
|||
|
http://iceja.net/ сервер решения полиномов
iceja 18.01.2026
Выкатила http:/ / iceja. net/ сервер решения полиномов (находит действительные корни полиномов методом Штурма).
На сайте документация по API, но скажу прямо VPS слабенький и 200 000 полиномов. . .
|
Первый деплой
lagorue 16.01.2026
Не спеша развернул своё 1ое приложение в kubernetes.
А дальше мне интересно создать 1фронтэнд приложения и 2 бэкэнд приложения
развернуть 2 деплоя в кубере получится 2 сервиса и что-бы они. . .
|
Расчёт переходных процессов в цепи постоянного тока
igorrr37 16.01.2026
/ *
Дана цепь постоянного тока с R, L, C, k(ключ), U, E, J. Программа составляет систему уравнений по 1 и 2 законам
Кирхгофа, решает её и находит:
токи, напряжения и их 1 и 2 производные при t = 0;. . .
|
Восстановить юзерскрипты Greasemonkey из бэкапа браузера
damix 15.01.2026
Если восстановить из бэкапа профиль Firefox после переустановки винды, то список юзерскриптов в Greasemonkey будет пустым.
Но восстановить их можно так.
Для этого понадобится консольная утилита. . .
|
|
Изучаю kubernetes
lagorue 13.01.2026
А пригодятся-ли мне знания kubernetes в России?
|
Сукцессия микоризы: основная теория в виде двух уравнений.
anaschu 11.01.2026
https:/ / rutube. ru/ video/ 7a537f578d808e67a3c6fd818a44a5c4/
|
WordPad для Windows 11
Jel 10.01.2026
WordPad для Windows 11
— это приложение, которое восстанавливает классический текстовый редактор WordPad в операционной системе Windows 11. После того как Microsoft исключила WordPad из. . .
|
Classic Notepad for Windows 11
Jel 10.01.2026
Old Classic Notepad for Windows 11
Приложение для Windows 11, позволяющее пользователям вернуть классическую версию текстового редактора «Блокнот» из Windows 10. Программа предоставляет более. . .
|