|
24 / 24 / 5
Регистрация: 04.04.2012
Сообщений: 107
|
||||||
Parallel.ForEach эффективное использование29.10.2018, 20:01. Показов 7996. Ответов 72
Хотелось бы услышать реальный опыт использования параллельных циклов и плюсы от использования, если они есть.
Как я понимаю такие циклы надо завязывать на количество ядер процессора. Общий обычный цикл, а внутри параллельные по количеству ядер. Кусок кода "внутреннего цикла" внизу оч долгой работы > 5 ч.
0
|
||||||
| 29.10.2018, 20:01 | |
|
Ответы с готовыми решениями:
72
Распараллеливание. Parallel.ForEach
Pause и Resume в Parallel.Foreach |
|
24 / 24 / 5
Регистрация: 04.04.2012
Сообщений: 107
|
||
| 01.11.2018, 15:39 [ТС] | ||
|
А вы как видите параллельную операцию любую напишите пример чтоб я понял.
0
|
||
|
TheGreatCornholio
1255 / 733 / 285
Регистрация: 30.07.2015
Сообщений: 2,408
|
||
| 01.11.2018, 16:23 | ||
|
перефразирую пример Эрика Липперта со SO:
Вам нужно приготовить бутерброд: Поджарить хлеб в тостере - 3 минуты Нарезать колбасу - 5 минут Синхронная модель (один поток - вы): Вы включаете тостер, ждете пока он приготовит хлеб, режете колбасу 3+5 = 8 минут и бутерброд готов Асинхронная модель (один поток - вы): Смотреть, как тостер готовит хлеб необязательно, значит эта операция может быть выполнена асинхронно (как IO операция(ввода\вывода) IO-bound) Резка колбасы не может быть выполнена в асинхронном режиме, но может быть выполнена другим работником (в отдельном потоке, CPU-bound) - об этом в параллельной модели Ставите хлеб в тостер, включаете, начинаете резать колбасу Когда тостер выплюнул хлеб, прерываете резку колбасы, достаете хлеб (5 секунд), дорезаете колбасу 5 минут 5 секунд и бутерброд готов Параллельная модель (два потока - вы и ваша собака): Вы режете колбасу, собака жарит тост 5 минут (наибольшее время среди работы 2х потоков) и бутерброд готов Но ресурсов затрачено в 2 раза больше (2 работника) Добавлено через 3 минуты Вам нужно понять, что операции чтение записи на диск IO-bound и должны выполняться асинхронно Операции разархивирования, парсинга PDF - CPU-bound и должны бы распараллелены Таким образом
0
|
||
|
|
||
| 01.11.2018, 16:27 | ||
|
rams, ответе все же на вопрос поставленый выше: какой тип даных и их обьем обрабатывается?
Если ооооочерь хочется разобратся что к чему: читайте доку по Parallel.ForEach. Если кратко, даный зверь юзает TaskScheduler, который в свою очередь общается с пулом потоков приложения. Из того что я видел при работе с ним: - на старте пулл держит колекцию потоков равную количеству логических процессоров (потоков отображаемых в диспечере задач). - если какая-то задача занимает очень долго время юзания потока из пула, создается еще один поток для выполения следующей задачи. Процесс создания вообще не шустрый - если задача очень долгая, и насоздавать условных 100 потоков, то просядите на переключении между ними. И єто только то что я задел поверхностно, расматривая паралелизацию определеных процесов. По вашей же задачи: rar.Extract явно отьедает основное время и нужно смотреть реализацию ArchiveFile, и уже плясать от нее. В идеале нужно разделить поток считывания и поток обработки, но если там размер файла под 1Гб, будет весело -- в память его не запихнешь, а значит очередь не построишь.
0
|
||
|
24 / 24 / 5
Регистрация: 04.04.2012
Сообщений: 107
|
|
| 01.11.2018, 20:00 [ТС] | |
|
Wolfdp,
Все верно вы говорите, и внятного алгоритма когда применять все эти Parllel async await и т. д. нет, за исключением сетевых штук там почти все можно делать async. Причем сами разработчики tpl также ограничиваются общими рекомендациями добавляя в конце что только тест может дать окончательный ответ. И серьезных примеров я не нашел на .net может не там искал. На с все понятно nvidia cuda и будет тебе счастье. Но сколько времени занимает решить одну и ту же задачу на с и с# в десятки раз больше у меня по крайней мере.
0
|
|
|
309 / 221 / 74
Регистрация: 23.05.2011
Сообщений: 981
|
|||||||
| 01.11.2018, 20:34 | |||||||
|
rams, я применял Parallel.ForEach года три назад и добивался трёхкратного ускорения
![]() Если хотите, можете меня не слушать. Добавлено через 9 минут Wolfdp, вообще, скорее всего есть какая-то библиотека, которая умеет один архив параллельно распаковывать из памяти в память. Я бы смотрел в эту сторону. Что-то вроде такого псевдокода:
0
|
|||||||
|
24 / 24 / 5
Регистрация: 04.04.2012
Сообщений: 107
|
||
| 01.11.2018, 21:26 [ТС] | ||
|
Добавлено через 40 минут А задача простая и уже давно решена просто я ищу возможности выполнять ее быстрее. Коротко есть rar архивы 50 -70 шт не большие 40 - 80 мб в них pdf 100 - 200 шт. Нужно извлечь текст из каждой страницы pdf и сохранить как текстовый файл. В .net нет нативных средств для работы с rar и pdf так что используются сторонние библиотеки iText и SevenZipExactor
0
|
||
|
309 / 221 / 74
Регистрация: 23.05.2011
Сообщений: 981
|
||||||
| 02.11.2018, 00:28 | ||||||
|
rams, бросай программирование. Это не твоё.
Я ни разу не работал с 7z, но разобрался и написал почти рабочую прогу за 20 минут. Тебе надо было лишь почитать очень короткую документацию.
Поясняю, что происходит. В отдельном потоке я считываю данные с диска и кладу в потокобезопасную очередь. Считываю до конца один файл и только потом пытаюсь открыть друго. Запускаю до 10 параллельных распаковщиков (думаю, .Net запустит ровно столько, сколько ядер). Каждый из них берёт загруженный в память файл и распаковывает из него только pdf, причём распаковывает тоже напрямую в память, потому что насиловать диск не нужно. Потом из памяти сразу же конвертирует pdf в текстовый поток и сохраняет это в память. Потом, когда уже всё закончилось, я сохраняю последовательно каждый текст в конечный текстовый файл. Добавлено через 17 минут В итоге то, что быстрее работает параллельно, считается параллельно. То, что быстрее работает последовательно, работает последовательно.
0
|
||||||
|
24 / 24 / 5
Регистрация: 04.04.2012
Сообщений: 107
|
|
| 02.11.2018, 00:31 [ТС] | |
|
Я тебя просил код показать Parallel.For который в 3 раза быстрее, чем обычный.
Предвижу ответ потерялся, не помню и т.д.
0
|
|
|
14086 / 9303 / 1348
Регистрация: 21.01.2016
Сообщений: 34,915
|
|
| 02.11.2018, 06:51 | |
|
rams,
Parallel.ForEach не волшебная палочка-ускорялочка. Всё, что данный метод делает - выполняет полученный делегат в N потоков для обработки коллекции. Тоже самое можно сделать и вручную, с помощью Task.Run.Чтобы это работало быстрее последовательной обработки, вам нужно понимать и думать, что вы делаете. А ваш пример такое понимание не демонстрирует. Вы в N потоков обращаетесь к одному ресурсу - жёсткому диску. Параллельная работа жёсткого диска (или SSD) - только видимость, создаваемая операционной системой. Вы можете и в сто потоков работать с диском, но на каждый поток будет приходиться одна сотая пропускной способности, плюс расходы на общение с диском, плюс расходы на переключения контекстов потоков. Т.е. работать с диском параллельно не имеет смысла, ибо работа такая будет длиться дольше, чем синхронная. New man, наличие Thread.Sleep в цикле делает вашу реализацию... не особо эффективной. Все потоки будут крутиться в бесконечном цикле ожидая появления загруженного файла... Для эффективной реализации consumer-producer можно использовать BlockingCollection<T> или произвольную коллекцию в связке с ManualResetEventSlim. А бесконечные циклы в связке с Thread.Sleep - фу неописуемое.
0
|
|
| 02.11.2018, 11:36 | |
|
Не по теме: Usaga, не тратьте время в этой теме - тут слой железобетона несколько метров походу.
0
|
|
|
24 / 24 / 5
Регистрация: 04.04.2012
Сообщений: 107
|
||||||
| 02.11.2018, 12:30 [ТС] | ||||||
|
Usaga, Вот тесты посмотрите может я что то не так делаю, но StopWatch показывает что не все так однозначно.
Woldemar89, Пожалуйста не надо флудить здесь люди пытаются разобраться и найти оптимальное решение я так полагаю.
0
|
||||||
|
14086 / 9303 / 1348
Регистрация: 21.01.2016
Сообщений: 34,915
|
|
| 02.11.2018, 12:48 | |
|
rams, мне не зачем смотреть на результаты бенчмарков, когда невооружённым глазом видно "фу".
![]() Цикл с Thread.Sleep внутри не нужно оправдывать. Это нужно исправлять.
0
|
|
|
309 / 221 / 74
Регистрация: 23.05.2011
Сообщений: 981
|
|||||||||||||
| 02.11.2018, 12:54 | |||||||||||||
|
Проблема в том, что я ни разу не писал consumer-producer на C#, т.к. в основном я пишу на C++, а лезть разбираться в документацию в этой теме незачем. Впрочем, спасибо, теперь я знаю, что гуглить. Ну, и если это тебя успокоит ![]()
А мой код прост. Интересно, что он тебе даст:
0
|
|||||||||||||
|
24 / 24 / 5
Регистрация: 04.04.2012
Сообщений: 107
|
||||||||||||||||
| 02.11.2018, 13:04 [ТС] | ||||||||||||||||
|
New man, Вот ваш код
потом мне говорите что надо документацию читать а там сказано зачем нужен такой конструктор когда скачиваешь файл из интернета и пример приведен здесь это оправдано можно не сохранять архив а сразу распаковывать.
И дайте нормальный пример смысл вырвать строчку из кода и показать.
0
|
||||||||||||||||
|
1 / 2 / 0
Регистрация: 02.06.2018
Сообщений: 33
|
|
| 02.11.2018, 13:11 | |
|
Нужно не распараллеливать, а совмещать операции распаковки и записи на диск.
Распаковка –синхронная операция. Кстати можете распараллелить по ядрам саму распаковку, чтение исходников с диска не распараллелится. Запись производить асинхронно. Т.е распаковали один файл, отдали на запись асинхронному сервису, распаковываете другой файл и т.д.
0
|
|
|
24 / 24 / 5
Регистрация: 04.04.2012
Сообщений: 107
|
|
| 02.11.2018, 13:32 [ТС] | |
|
B_S_V, Ок то есть вы предлагаете
Распаковал файл в память -> async func вся работа с pdf () Правильно понял? Согласен надо пробовать сделаю.
0
|
|
|
1 / 2 / 0
Регистрация: 02.06.2018
Сообщений: 33
|
|
| 02.11.2018, 14:13 | |
|
Нужно распланировать ядра процессора. Предположим у вас 4 ядра.
На первом ядре делаем синхронный сервис чтения сжатых файлов. На двух следующих открываем два асинхронных сервиса распаковки. На последнем ядре делаем асинхронный сервис записи на диск int CREATE_SERVICE(string name, object method, int core,i nt isProcess) CREATE_SERVICE (“Read,” object methodRead , 0 , 0) CREATE_SERVICE_ASYNC ( “UnPack_1”, methodUnPack, 1, 0) CREATE_SERVICE_ASYNC (UnPack_2”, methodUnPack, 2, 0) CREATE_SERVICE_ASYNC ( “Write”, methodWrite , 3 ,0) Сервис Read читает файлы и передает их поочередно в один из двух асинхронных серверов распаковке. Те распаковывают и передают файл в асинхронный сервис записи на диск.
0
|
|
|
309 / 221 / 74
Регистрация: 23.05.2011
Сообщений: 981
|
||
| 02.11.2018, 14:27 | ||
|
Я сначала копирую байты с диска в оперативную память, потом открываю память как архив. Время между чтением байта с памяти в сотни раз быстрее чем с диска, поэтому процесс идёт быстрее. + мы можем параллельно читать с диска и распаковывать. У тебя же сначала n потоков одновременно читают с диска, потом они уже одновременно пытаются распаковать. Чтение с диска почти не тратит ресурсы процессора, но тратит ресурс системной шины, сдвигов головки и т.п. Распаковка же тратит в основном ресурсы процессора. В итоге твой код сначала сильно загружает диск, причём очень неоптимально (потому что читать последовательно с диска по одному файлу намного быстрее, чем много файлов параллельно), но заставляет простаивать проц. Потом у тебя простаивает диск но перегружается проц. Потом у тебя опять перегружается диск. В общем, оптимизировать тебе надо именно работу с диском, используя MemoryStream вместо FileStream на всех этапах кроме самого первого чтения и последней записи. Потому что работа с памятью напрямую в сотни раз быстрее. Потом надо параллелить распаковку pdf и выделение текста из PDF, причём работать надо только в ОЗУ, потому что файлы у тебя помещаются.
0
|
||
|
24 / 24 / 5
Регистрация: 04.04.2012
Сообщений: 107
|
||
| 02.11.2018, 14:40 [ТС] | ||
|
Все что я имею Environment.ProcessorCount;//amount cores узнать количество ядер. И их 2 например и что делать?
0
|
||
|
309 / 221 / 74
Регистрация: 23.05.2011
Сообщений: 981
|
|||
| 02.11.2018, 14:43 | |||
|
Автор документации не думал, что тебе нужно будет сотни файлов параллельно распаковывать. Добавлено через 1 минуту Или Parallel.For
0
|
|||
| 02.11.2018, 14:43 | |
|
Помогаю со студенческими работами здесь
40
Parallel.ForEach и его неадекватное поведение Parallel.ForEach что не верно? Не компилируется
Parallel foreach ожидание для каждого потока Искать еще темы с ответами Или воспользуйтесь поиском по форуму: |
|
Новые блоги и статьи
|
||||
|
PhpStorm 2025.3: WSL Terminal всегда стартует в ~
and_y87 14.12.2025
PhpStorm 2025. 3: WSL Terminal всегда стартует в ~ (home), игнорируя директорию проекта
Симптом:
После обновления до PhpStorm 2025. 3 встроенный терминал WSL открывается в домашней директории. . .
|
Access
VikBal 11.12.2025
Помогите пожалуйста !! Как объединить 2 одинаковые БД Access с разными данными.
|
Новый ноутбук
volvo 07.12.2025
Всем привет.
По скидке в "черную пятницу" взял себе новый ноутбук Lenovo ThinkBook 16 G7 на Амазоне:
Ryzen 5 7533HS
64 Gb DDR5
1Tb NVMe
16" Full HD Display
Win11 Pro
|
Музыка, написанная Искусственным Интеллектом
volvo 04.12.2025
Всем привет. Некоторое время назад меня заинтересовало, что уже умеет ИИ в плане написания музыки для песен, и, собственно, исполнения этих самых песен. Стихов у нас много, уже вышли 4 книги, еще 3. . .
|
От async/await к виртуальным потокам в Python
IndentationError 23.11.2025
Армин Ронахер поставил под сомнение async/ await. Создатель Flask заявляет: цветные функции - провал, виртуальные потоки - решение. Не threading-динозавры, а новое поколение лёгких потоков. Откат?. . .
|
|
Поиск "дружественных имён" СОМ портов
Argus19 22.11.2025
Поиск "дружественных имён" СОМ портов
На странице:
https:/ / norseev. ru/ 2018/ 01/ 04/ comportlist_windows/
нашёл схожую тему. Там приведён код на С++, который показывает только имена СОМ портов, типа,. . .
|
Сколько Государство потратило денег на меня, обеспечивая инсулином.
Programma_Boinc 20.11.2025
Сколько Государство потратило денег на меня, обеспечивая инсулином.
Вот решила сделать интересный приблизительный подсчет, сколько государство потратило на меня денег на покупку инсулинов.
. . .
|
Ломающие изменения в C#.NStar Alpha
Etyuhibosecyu 20.11.2025
Уже можно не только тестировать, но и пользоваться C#. NStar - писать оконные приложения, содержащие надписи, кнопки, текстовые поля и даже изображения, например, моя игра "Три в ряд" написана на этом. . .
|
Мысли в слух
kumehtar 18.11.2025
Кстати, совсем недавно имел разговор на тему медитаций с людьми. И обнаружил, что они вообще не понимают что такое медитация и зачем она нужна. Самые базовые вещи. Для них это - когда просто люди. . .
|
Создание Single Page Application на фреймах
krapotkin 16.11.2025
Статья исключительно для начинающих. Подходы оригинальностью не блещут.
В век Веб все очень привыкли к дизайну Single-Page-Application .
Быстренько разберем подход "на фреймах".
Мы делаем одну. . .
|