Форум программистов, компьютерный форум, киберфорум
C# .NET
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.85/34: Рейтинг темы: голосов - 34, средняя оценка - 4.85
24 / 24 / 5
Регистрация: 04.04.2012
Сообщений: 107

Parallel.ForEach эффективное использование

29.10.2018, 20:01. Показов 7981. Ответов 72

Студворк — интернет-сервис помощи студентам
Хотелось бы услышать реальный опыт использования параллельных циклов и плюсы от использования, если они есть.
Как я понимаю такие циклы надо завязывать на количество ядер процессора.
Общий обычный цикл, а внутри параллельные по количеству ядер.
Кусок кода "внутреннего цикла" внизу оч долгой работы > 5 ч.

C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
Parallel.ForEach(current, (r) =>
                    {
                        currentData = Path.Combine(baseFolder, Path.GetFileNameWithoutExtension(r));
                        Directory.CreateDirectory(currentData);
                        using (ArchiveFile rar = new ArchiveFile(r))
                        {
                            rar.Extract(currentData);
                        }
 
                        foreach (var s in Directory.EnumerateFiles(currentData, "*.*", SearchOption.AllDirectories))
                        {
                            if (Path.GetExtension(s) == ".pdf")
                            {
                                iTextPdf.ExtractTextPdf(s);
                                File.Delete(s);
                            }
                            else
                                File.Delete(s);
                        }
 
                        Utils.CopyFolderContents(currentData, outData);
                        Directory.Delete(currentData, true);
                    });
0
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
29.10.2018, 20:01
Ответы с готовыми решениями:

Распараллеливание. Parallel.ForEach
На данный момент выполняется такой код: Hashtable files2copy; void startButton_Click(object sender, RoutedEventArgs e) { ...

Parallel.Foreach изменение коллекции
Если коллекция Dictionary<string,Class> dic; Первый поток добавляет и удаляет элементы из коллекции используя Parallel.Foreach Второй...

Pause и Resume в Parallel.Foreach
Сделал пробный проект, в котором идет просто вывод переменной из List<int>. При нажатии на кнопку Button2 переменной isPaused...

72
TheGreatCornholio
 Аватар для Woldemar89
1255 / 733 / 285
Регистрация: 30.07.2015
Сообщений: 2,408
29.10.2018, 21:10
Цитата Сообщение от rams Посмотреть сообщение
Кусок кода "внутреннего цикла" внизу оч долгой работы > 5 ч.
Ясен пень оч долгой, вы насилуете жесткий диск с максимальной жестокостью.

Как вы себе представляете физическое параллельное чтение с диска? o_0
(если, конечно, это не что-то новомодное, что позволяет это делать)

Вы пытаетесь распараллелить логику в очень узком месте.

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

Записи на диск тоже касается - желательно чтобы и чтение и запись на диск обрабатывал один поток асинхронно.
0
24 / 24 / 5
Регистрация: 04.04.2012
Сообщений: 107
29.10.2018, 21:30  [ТС]
Цитата Сообщение от Woldemar89 Посмотреть сообщение
Как вы себе представляете параллельное чтение с диска?
Не понял в чем проблема, там есть такое
C#
1
2
3
4
using (ArchiveFile rar = new ArchiveFile(r))
                        {
                            rar.Extract(currentData);
                        }
это обычная распаковка rar архива, можно открыть два проводника и наблюдать как параллельно распаковываются два и более архива.
Дальше не буду и комментировать
Цитата Сообщение от Woldemar89 Посмотреть сообщение
Записи на диск тоже касается - желательно чтобы и чтение и запись на диск обрабатывал один поток асинхронно.
0
TheGreatCornholio
 Аватар для Woldemar89
1255 / 733 / 285
Регистрация: 30.07.2015
Сообщений: 2,408
29.10.2018, 21:33
Цитата Сообщение от rams Посмотреть сообщение
Не понял в чем проблема
Цитата Сообщение от rams Посмотреть сообщение
можно открыть два проводника и наблюдать как параллельно распаковываются два и более архива
Вы вообще в курсе как устроены жесткие диски и про их быстродействие?
0
24 / 24 / 5
Регистрация: 04.04.2012
Сообщений: 107
29.10.2018, 21:41  [ТС]
Цитата Сообщение от Woldemar89 Посмотреть сообщение
Вы вообще в курсе как устроены жесткие диски и про их быстродействие?
Ладно я понял спасибо за ответ.
0
Эксперт .NET
 Аватар для Wolfdp
3784 / 1758 / 371
Регистрация: 15.06.2012
Сообщений: 6,528
Записей в блоге: 3
31.10.2018, 13:46
Цитата Сообщение от rams Посмотреть сообщение
Как я понимаю такие циклы надо завязывать на количество ядер процессора.
не особо, есть еще такая штука как "потоки" и пулл. Вообще Parallel.ForEach довольно оптимально раскидывает задачи именно для CPU.

Цитата Сообщение от rams Посмотреть сообщение
ArchiveFile
нагрузка не под 100%? Как бы не понятно какой обьем вы хотите "распаковать" -- 100500 файлов по 10Кб или 10 штук по 100500Гб? Ну и не совсем понятно что происходит в
C#
1
iTextPdf.ExtractTextPdf(s);
0
24 / 24 / 5
Регистрация: 04.04.2012
Сообщений: 107
31.10.2018, 22:48  [ТС]
Цитата Сообщение от Wolfdp Посмотреть сообщение
Вообще Parallel.ForEach довольно оптимально раскидывает задачи именно для CPU.
Вот это была суть моего вопроса как оптимально?
По синтаксису так просто запускает делегат на каждую итерацию, что очень не оптимально у вас 200 итераций и ... 200 делегатов так накладные расходы сделают такой цикл дольше обычного, тогда в чем смысл.
Ладно я в вопросе просил рассказать про реальный опыт вот моя табличка сначала простой цикл, потом паралл, потом простой а внутри паралл на 2, 4, 6 итераций.

00:06:26.4783393 - 1
00:07:55.2581924 - all

00:04:51.8370480 - 2
00:04:56.0815210 - 4
00:06:58.4193538 - 6

Как видно если просто заменить обычный цикл на паралл время выполнения только увеличивается
0
309 / 221 / 74
Регистрация: 23.05.2011
Сообщений: 981
01.11.2018, 01:55
rams, Вам выше посоветовали узнать, как устроена работа с ЖД дисками.

Вкратце, Вы одновременно открываете кучу файлов и читаете из них. Из-за этого головка жёсткого диска прыгает ежесекундно по всему жёсткому диску, постоянно прерываясь и в итоге грузит очень медленно.
Когда же данные грузятся по одному файлу целиком, а потом двигаются к другому, работы намного меньше: головка встала у начала файла, прочла его в память, потом начала читать другой. Ну, немного идиллию портит фрагментация.
0
24 / 24 / 5
Регистрация: 04.04.2012
Сообщений: 107
01.11.2018, 11:47  [ТС]
Цитата Сообщение от New man Посмотреть сообщение
Вам выше посоветовали узнать, как устроена работа с ЖД дисками.
Какое отношение работа hdd имеет к циклу Parallel.ForEach. Тест проводился на данных в памяти. Про hdd у вас как и товарища сверху поверхностные знания для вас это виниловая пластинка с иголкой которая играет песня за песней это не так и вообще к моему вопросу не имеет отношения. Есть реальный опыт использования параллельных циклов? Есть плюсы? Напишите, вот в чем вопрос я не нашел
0
TheGreatCornholio
 Аватар для Woldemar89
1255 / 733 / 285
Регистрация: 30.07.2015
Сообщений: 2,408
01.11.2018, 12:23
Цитата Сообщение от rams Посмотреть сообщение
Есть реальный опыт использования параллельных циклов? Есть плюсы?
Есть, есть.
0
24 / 24 / 5
Регистрация: 04.04.2012
Сообщений: 107
01.11.2018, 12:57  [ТС]
Цитата Сообщение от Woldemar89 Посмотреть сообщение
Есть, есть.
Так может ссылки дадите. Про hdd вот картинка как файлы хранятся на диске
https://studme.org/93857/infor... iya_faylov
0
TheGreatCornholio
 Аватар для Woldemar89
1255 / 733 / 285
Регистрация: 30.07.2015
Сообщений: 2,408
01.11.2018, 13:45
Цитата Сообщение от rams Посмотреть сообщение
Так может ссылки дадите. Про hdd вот картинка как файлы хранятся на диске
Нет, не дам. Каким образом хранятся файлы значения не имеет, за исключением замедления чтения из-за вышеупомянутой дефрагментации.
Но это в данном случае не важно, гораздо важнее то, что дефолтный жесткий диск не умеет читать и писать файлы параллельно.

C#
1
2
3
4
5
6
7
              
currentData = Path.Combine(baseFolder, Path.GetFileNameWithoutExtension(r));
Directory.CreateDirectory(currentData);
using (ArchiveFile rar = new ArchiveFile(r))
{
     rar.Extract(currentData);
}
здесь происходит чтение архива с диска, разархивация, запись файлов на диск
причем это все дело уже может выполнятся параллельно используя ресурсы ПК если не по максимуму - то не по минимуму уж точно,
так как (де)архиватор скорее всего не дураки писали

далее здесь идет чтение
C#
1
2
3
4
5
6
7
8
9
10
     foreach (var s in Directory.EnumerateFiles(currentData, "*.*", SearchOption.AllDirectories))
                        {
                            if (Path.GetExtension(s) == ".pdf")
                            {
                                iTextPdf.ExtractTextPdf(s);
                                File.Delete(s);
                            }
                            else
                                File.Delete(s);
                        }

и снова чтение\запись
C#
1
Utils.CopyFolderContents(currentData, outData);
таким образом, у вас постоянно идет и чтение и запись на диск,
то есть диск уже и так нагружен неплохо, и введение лишнего потока может только навредить:

как я уже упомянул,
дефолтный жесткий диск не умеет читать и писать файлы параллельно.
добавляя количество потоков вы заставляете жесткий диск метаться от файла к файлу:
там прочитал 4KB, там записал 10KB, и так каждый раз в разном месте,

представьте что вам надо читать 5 книг и писать в 5 тетрадей параллельно?

Цитата Сообщение от rams Посмотреть сообщение
Есть плюсы?
Да есть, если параллелить и использовать Parallel правильно,
в вашем случае это скорее замедляет работу, чем ускоряет.
Советы по оптимизации я уже давал.

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

Андерстенд?
1
24 / 24 / 5
Регистрация: 04.04.2012
Сообщений: 107
01.11.2018, 14:18  [ТС]
Цитата Сообщение от Woldemar89 Посмотреть сообщение
дефолтный жесткий диск не умеет читать и писать файлы параллельно.
жесткий диск умеет читать и писать файлы параллельно. Возьмите два больших файла и скопируйте их куда нибудь. В win10 это отлично видно. Да и реализуется это элементарно создайте буфер и читайте по кластеру из каждого файла потом пишите куда надо. Все ваши рассуждение строится вокруг того, что обращение к диску дорогая операция, спасибо это я и сам знаю. Тут уж контекста задачи зависит.
0
Эксперт .NET
6691 / 4102 / 1607
Регистрация: 09.05.2015
Сообщений: 9,569
01.11.2018, 14:21
Цитата Сообщение от rams Посмотреть сообщение
жесткий диск умеет читать и писать файлы параллельно
Уметь то умеет, но скорость от этого только падает.
0
24 / 24 / 5
Регистрация: 04.04.2012
Сообщений: 107
01.11.2018, 14:34  [ТС]
Цитата Сообщение от Someone007 Посмотреть сообщение
Уметь то умеет, но скорость от этого только падает.
Совершенно верно и вот здесь то и основная проблема как и параллельным прог. как лучше последовательно все выполнить или где то разделить на отдельные потоки.
По поводу Parallel.ForEach я пока остался на том что просто синтаксический сахар я так же могу на каждую итерацию в обычном цикле написать Task.Run();
0
TheGreatCornholio
 Аватар для Woldemar89
1255 / 733 / 285
Регистрация: 30.07.2015
Сообщений: 2,408
01.11.2018, 14:40
Цитата Сообщение от rams Посмотреть сообщение
жесткий диск умеет читать и писать файлы параллельно.
Цитата Сообщение от Woldemar89 Посмотреть сообщение
Как вы себе представляете физическое параллельное чтение с диска?
На уровне контроллера и\или драйвера, операционной системы - согласен, иллюзия параллельности создается.
А на физическом уровне как это работает? (говорим о "дефолтном" жестком диске)
0
24 / 24 / 5
Регистрация: 04.04.2012
Сообщений: 107
01.11.2018, 14:54  [ТС]
Цитата Сообщение от Woldemar89 Посмотреть сообщение
Как вы себе представляете физическое параллельное чтение с диска?
Я же не про кластер а про файл. Файл состоит из кластеров. Вам надо прочитать два файла с ж диска в оп память и дальше снова на диск (копирование) ну так и читайте 1 кластер с 1 файла потом 1 кластер со 2 файла а потом сразу пишите. Я конечно все упростил.
0
TheGreatCornholio
 Аватар для Woldemar89
1255 / 733 / 285
Регистрация: 30.07.2015
Сообщений: 2,408
01.11.2018, 14:59
Цитата Сообщение от rams Посмотреть сообщение
ну так и читайте 1 кластер с 1 файла потом 1 кластер со 2 файла
Чего это вдруг сначала один потом другой?
Оба сразу! Одновременно! Нет?
Вы же мне тут про параллельное чтение наваливаете вроде как.
0
24 / 24 / 5
Регистрация: 04.04.2012
Сообщений: 107
01.11.2018, 15:09  [ТС]
Цитата Сообщение от Woldemar89 Посмотреть сообщение
Вы же мне тут про параллельное чтение наваливаете вроде как.
Что то вы себя как тролль ведете
Если вам надо любой ценой доказать что вы правы не напрягайтесь я с вами согласен вы правы.
0
TheGreatCornholio
 Аватар для Woldemar89
1255 / 733 / 285
Регистрация: 30.07.2015
Сообщений: 2,408
01.11.2018, 15:19
Цитата Сообщение от rams Посмотреть сообщение
Если вам надо любой ценой доказать что вы правы не напрягайтесь я с вами согласен вы правы.
У меня нет потребности что-либо доказывать, просто вы говорите о параллельности,
а в пример приводите полностью синхронную последовательность действий.
Просто не люблю взаимоисключающие параграфы в рассуждениях.
Цитата Сообщение от rams Посмотреть сообщение
Что то вы себя как тролль ведете
О да, я прям с первого поста вас начал троллить, - раскусили, поздравляю
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
01.11.2018, 15:19
Помогаю со студенческими работами здесь

PLINQ или Parallel.ForEach?
Пытаюсь сообразить как лучше сделать задачку. Есть большой список EXCEL файлов и мне надо их считать проделать некоторые операции (все...

Parallel.ForEach и его неадекватное поведение
Задача простая. Я выполняю какие либо действия, в результате чего у меня появляется допустим огромный массив с данными, которые мне нужно...

Parallel.ForEach что не верно? Не компилируется
class Program { static void Main(string args) { ParallelOptions parOpt = new ParallelOptions(); ...

Сравнение списков Parallel.ForEach неадекватный результат
Сравниваю два списка, возвращаю первое совпадение. Но возвращаемое значение всегда разное при одинаковых списках. В чем может заключаться...

Parallel foreach ожидание для каждого потока
Добрый день. Есть Parallel.ForEach, который внутри себя вызывает json запрос на сервер. Parallel.ForEach(arr, v => { ...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Новые блоги и статьи
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 . Быстренько разберем подход "на фреймах". Мы делаем одну. . .
Фото: Daniel Greenwood
kumehtar 13.11.2025
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2025, CyberForum.ru