|
Parallel.ForEach - первый блин комом
|
|||
---|---|---|---|
#18+
Возможно я чего-то недопонял или совсем не понял, потому такой наивный вопрос: Вот эта вот кривая поделка будет копировать файлы с одного источника на Х получателей ПАРАЛЛЕЛЬНО или нет? Ну то есть например с флэшки сразу на два диска или наоборот с диска на 2е флэшки. Дополнительный вопрос: Если запустить под Debag'ом, то "Готово!" не появляется. А вот под Releas'ом MessageBox отрабатывает верно. Почему так? Спасибо. Код: c# 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29.
... |
|||
:
Нравится:
Не нравится:
|
|||
06.02.2013, 01:09 |
|
Parallel.ForEach - первый блин комом
|
|||
---|---|---|---|
#18+
А можно ещё и так изголиться: Код: c# 1. 2. 3. 4. 5. 6. 7.
Скорость копирования какая-то офигительная. 7 ГБ за несколько секунд (меньше полминуты). Где подвох? ;) ... |
|||
:
Нравится:
Не нравится:
|
|||
06.02.2013, 01:51 |
|
Parallel.ForEach - первый блин комом
|
|||
---|---|---|---|
#18+
StartNew не блокирует UI. ForEach не контролирует уровень параллелизма и создает большое кол-во тредов, что дает только тормоза, а не скорость. Вложенные параллельные операторы не нужно делать по этой же причине. ... |
|||
:
Нравится:
Не нравится:
|
|||
06.02.2013, 09:17 |
|
Parallel.ForEach - первый блин комом
|
|||
---|---|---|---|
#18+
А смысл параллелить копирование файлов, если диск один? И исходний, и целевой. Это только в разы ухудшит быстродействие. ... |
|||
:
Нравится:
Не нравится:
|
|||
06.02.2013, 11:14 |
|
Parallel.ForEach - первый блин комом
|
|||
---|---|---|---|
#18+
Arm79А смысл параллелить копирование файлов, если диск один? И исходний, и целевой. Это только в разы ухудшит быстродействие. Нет нет, диск НЕ ОДИН. Я же написал: Например с винта сразу на ДВЕ флэшки. Я не знаю как там теоретически, а практический замер показал афигительную скорость по сравнению с обычным синхронным foreach. У меня вопрос ещё такой: Как сюда влепить простенький Progressbar? Простенький, потому как не нужен прогресс копирования файлов как таковых, а только прогресс выполнения функций CopyAll, ну то есть если их в цикле 5 штук то считать только количество выполненых и это отображать в прогрессбаре. ... |
|||
:
Нравится:
Не нравится:
|
|||
06.02.2013, 12:51 |
|
Parallel.ForEach - первый блин комом
|
|||
---|---|---|---|
#18+
Ну и если "прогрессивный" Parallel для этих целей не подходит, то как сделать иначе? Открыть "обычным способом" несколько потоков и в них выполнять CopyAll с разными параметрами? Я вот и спашиваю: А Parallel.ForEach делает не тоже самое? ... |
|||
:
Нравится:
Не нравится:
|
|||
06.02.2013, 12:54 |
|
Parallel.ForEach - первый блин комом
|
|||
---|---|---|---|
#18+
M234Я же написал: Например с винта сразу на ДВЕ флэшки. Читать умеем? Arm79А смысл параллелить копирование файлов, если диск один? И исходний, и целевой вот если бы: диск 1 --> флешка 1 диск 2 --> флешка 2 тогда да, скорость от распараллеливания увеличилась бы. M234Я не знаю как там теоретически, а практический замер показал афигительную скорость по сравнению с обычным синхронным foreach Это частный случай. Тут все просто: скорость записи на флешку сильно меньше скорости чтения данных с жеского диска. Но ведь есть уже usb3.0/eSATA флешки - там такой финт ушами не прокатит ... |
|||
:
Нравится:
Не нравится:
|
|||
06.02.2013, 13:06 |
|
Parallel.ForEach - первый блин комом
|
|||
---|---|---|---|
#18+
То есть вы хотите сказать, что Копирование: Диск1 -> Флэшка1 и после завершения Диск1 -> Флэшка2 займёт столько же времени как и Диск1 -> Флэшка1 и "параллельно" (в другом потоке) Диск1 -> Флэшка2 Я вас правильно понял? А мне почему-то кажется что если открыть три окошка (диск1, флэшка1, флэшка2) в Windows Explorer (Win 7) и из первого окошка перетащить папку с файлами в два другие, то процесс копирования завершится быстрее чем если поочерёдно. Это обман зрения такой? ... |
|||
:
Нравится:
Не нравится:
|
|||
06.02.2013, 13:17 |
|
Parallel.ForEach - первый блин комом
|
|||
---|---|---|---|
#18+
M234Это обман зрения такой? Это попытка поспорить со мной не пытаясь вчитаться в мои ответы и понять суть. Диск у вас один. Последовательное чтение с него ну скажем происходит со скоростью 70 МБ/сек. Непоследовательно чтение приводит к тому, что головка диска вынуждена постоянно перемещаться по диску для чтения данных разных файлов (или тех же самых, но больших). Именно для того, чтобы обеспечить как можно большую часть последовательного чтения файлов, используется дефрагментация диска. Так вот, непоследовательное чтение уменьшает скорость в разы. Теперь с флешкой. Если скорость записи на флешку составляет ну скажем 5-10 МБ/сек, это значит, что при последовательном чтении вы можете параллельно писать не более 6-7 флешек за раз. Непоследовательное чтение ИМХО ограничит вас максимум 4 флешками зараз. Как только скорость записи на флешку увеличиться, естественно, количество одновременно используемых флешок уменьшится Теперь, если вы пишете утилиту копирования с одного источника на другой, то для обеспечения максимальной скорости вы должны проанализировать скорости выдачи с источника и скорость записи на целевую систему. И параллелить процессы. ИМХО достаточно нетривиальная задача, учитывая, что что эти скорости нелинейны. Вам не кажется, что проще и надежнее не заморачиваться и исходить из принципа - количество потоков = MIN(количество источников, количество приемников)? ... |
|||
:
Нравится:
Не нравится:
|
|||
06.02.2013, 13:44 |
|
Parallel.ForEach - первый блин комом
|
|||
---|---|---|---|
#18+
SeVaStartNew не блокирует UI. ForEach не контролирует уровень параллелизма и создает большое кол-во тредов, что дает только тормоза, а не скорость. Вложенные параллельные операторы не нужно делать по этой же причине. Ну то есть такую CopyAll как я привёл в примере делать не стоит? Лучше по старинке рекурсивно? Потестил немного копированием на одном и том же диске из одной папки в другую - так с ForEach сильно быстрее получается. Здесь что за "частный случай"? ... |
|||
:
Нравится:
Не нравится:
|
|||
07.02.2013, 17:35 |
|
Parallel.ForEach - первый блин комом
|
|||
---|---|---|---|
#18+
SeVaForEach не контролирует уровень параллелизма и создает большое кол-во тредов Глупости. Много тредов тебе никто и не даст, опять забыл про пул потоков. Вот тут на 1 млн. элементов пул отдал мне только 9 потоков. Код: c# 1. 2. 3. 4.
... |
|||
:
Нравится:
Не нравится:
|
|||
07.02.2013, 18:07 |
|
Parallel.ForEach - первый блин комом
|
|||
---|---|---|---|
#18+
МСУ, а ты хотел 1 млн потоков? =) ... |
|||
:
Нравится:
Не нравится:
|
|||
07.02.2013, 18:28 |
|
Parallel.ForEach - первый блин комом
|
|||
---|---|---|---|
#18+
Без понятия, что у вас вот код: Говнокод[SRC C#] class Program { static void Main(string[] args) { var stopwatch = new Stopwatch(); stopwatch.Start(); File.Copy(@"D:\Test\SW_DVD5_NTRL_Visual_Studio_2010SP1_MultiLang_FPP_VL_MLF_X17-40329.iso", @"D:\Test\SW_DVD5_NTRL_Visual_Studio_2010SP1_MultiLang_FPP_VL_MLF_X17-40329-2.iso"); File.Copy(@"D:\Test\SW_DVD5_VS_Ultimate_2012_Russian_Core_MLF_X18-35848.iso", @"D:\Test\SW_DVD5_VS_Ultimate_2012_Russian_Core_MLF_X18-35848-2.iso"); stopwatch.Stop(); Console.WriteLine("Elapsed sequential sek {0}", stopwatch.ElapsedMilliseconds / 1000); stopwatch.Reset(); File.Delete(@"D:\Test\SW_DVD5_NTRL_Visual_Studio_2010SP1_MultiLang_FPP_VL_MLF_X17-40329-2.iso"); File.Delete(@"D:\Test\SW_DVD5_VS_Ultimate_2012_Russian_Core_MLF_X18-35848-2.iso"); stopwatch.Start(); var task1 = Task.Factory.StartNew(() => File.Copy(@"D:\Test\SW_DVD5_NTRL_Visual_Studio_2010SP1_MultiLang_FPP_VL_MLF_X17-40329.iso", @"D:\Test\SW_DVD5_NTRL_Visual_Studio_2010SP1_MultiLang_FPP_VL_MLF_X17-40329-2.iso")); var task2 = Task.Factory.StartNew(() => File.Copy(@"D:\Test\SW_DVD5_VS_Ultimate_2012_Russian_Core_MLF_X18-35848.iso", @"D:\Test\SW_DVD5_VS_Ultimate_2012_Russian_Core_MLF_X18-35848-2.iso")); task1.Wait(); task2.Wait(); stopwatch.Stop(); Console.WriteLine("Elapsed async sek {0}", stopwatch.ElapsedMilliseconds / 1000); stopwatch.Reset(); File.Delete(@"D:\Test\SW_DVD5_NTRL_Visual_Studio_2010SP1_MultiLang_FPP_VL_MLF_X17-40329-2.iso"); File.Delete(@"D:\Test\SW_DVD5_VS_Ultimate_2012_Russian_Core_MLF_X18-35848-2.iso"); stopwatch.Start(); var lst = new List<string>(new[] {@"D:\Test\SW_DVD5_NTRL_Visual_Studio_2010SP1_MultiLang_FPP_VL_MLF_X17-40329.iso", @"D:\Test\SW_DVD5_VS_Ultimate_2012_Russian_Core_MLF_X18-35848.iso"}); Parallel.ForEach(lst, file => File.Copy(file, file + "_2")); stopwatch.Stop(); Console.WriteLine("Elapsed parallel sek {0}", stopwatch.ElapsedMilliseconds / 1000); stopwatch.Reset(); lst.ForEach(file => File.Delete(file + "_2")); Console.ReadLine(); } }[src] результаты: 79, 87, 86 сек. Есть разница? За такую небольшую разницу скажем спасибо моиму диску и его кэшу. ЗЫ Особенно наглядно это будет выглядеть, если читать с одного CD/DVD и писать куда-нибудь еще ... |
|||
:
Нравится:
Не нравится:
|
|||
07.02.2013, 18:29 |
|
Parallel.ForEach - первый блин комом
|
|||
---|---|---|---|
#18+
Чет заглючило Попытка №2 Код: c# 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. 30. 31. 32. 33. 34. 35. 36. 37.
ЗЫ Оба файла примерно по полтора гига каждый ... |
|||
:
Нравится:
Не нравится:
|
|||
07.02.2013, 18:31 |
|
Parallel.ForEach - первый блин комом
|
|||
---|---|---|---|
#18+
netivanМСУ, а ты хотел 1 млн потоков? =) А большое количество это сколько? ) ... |
|||
:
Нравится:
Не нравится:
|
|||
07.02.2013, 19:04 |
|
Parallel.ForEach - первый блин комом
|
|||
---|---|---|---|
#18+
Arm79, например на SSD разница будет. Да и на обычном ХДД тоже,но не в Х раз конечно. БД как-то же работают на дисках) ... |
|||
:
Нравится:
Не нравится:
|
|||
08.02.2013, 08:38 |
|
Parallel.ForEach - первый блин комом
|
|||
---|---|---|---|
#18+
netivanArm79, например на SSD разница будет. Да и на обычном ХДД тоже,но не в Х раз конечно. БД как-то же работают на дисках) Угу хоть усрись, но последовательный доступ на шпиндель, а с ссд ещё хуже на записи. БД секционируют , журналы и tempdb на разные шпиндели, для параллелизма записи - чтения. ... |
|||
:
Нравится:
Не нравится:
|
|||
08.02.2013, 09:53 |
|
Parallel.ForEach - первый блин комом
|
|||
---|---|---|---|
#18+
Ken@t, да вы не правы, как писать в любом случае решает контроллер диска. И надо сказать крутится он достаточно оперативно.Но мы отвлекаемся от темы. ... |
|||
:
Нравится:
Не нравится:
|
|||
08.02.2013, 09:59 |
|
Parallel.ForEach - первый блин комом
|
|||
---|---|---|---|
#18+
netivan, не выдержал сделал пример. Обычный диск какой то Сигейт 7200 оборотов. Копирую файл с диска на диск в разные папки. Последовательно 2 секунды, параллельно 1.2 в среднем. Так что разница есть. говнокод: static void CopyTest() { var stopwatch = new Stopwatch(); var dirs = new List<string>() {@"c:\copytemp1",@"c:\copytemp2" }; string filename = @"flashtool.7z"; dirs.ForEach(a => { if (!Directory.Exists(a)) { Directory.CreateDirectory(a); } }); //последовательно stopwatch.Start(); //Parallel.ForEach(dirs, d => File.Copy(Path.Combine(@"c:\", filename), Path.Combine(d, filename))); File.Copy(Path.Combine(@"c:\",filename),Path.Combine(dirs[0],filename)); File.Copy(Path.Combine(@"c:\", filename), Path.Combine(dirs[1], filename)); stopwatch.Stop(); dirs.ForEach(a => { if (Directory.Exists(a)) { Directory.Delete(a, true); } }); Console.WriteLine(stopwatch.Elapsed); Console.Read(); //удаляем } ... |
|||
:
Нравится:
Не нравится:
|
|||
08.02.2013, 10:29 |
|
Parallel.ForEach - первый блин комом
|
|||
---|---|---|---|
#18+
netivan, некорректный замер, котороый основывается на дисковом кеше во втором случае. Создай отдельные фолдеры для последовательного копирования и отдельные для параллельного. И замеряй непересекающиеся файло. ... |
|||
:
Нравится:
Не нравится:
|
|||
08.02.2013, 10:40 |
|
Parallel.ForEach - первый блин комом
|
|||
---|---|---|---|
#18+
netivan, какого размера файлы? если не очень большие, то они вполне могут быть в кэше диска. Я же специально для теста выбрал большие файлы, а мой тест - аналог вашего ... |
|||
:
Нравится:
Не нравится:
|
|||
08.02.2013, 10:41 |
|
Parallel.ForEach - первый блин комом
|
|||
---|---|---|---|
#18+
Arm79, 179 мб, не сказал бы что маленький. Попробую найти больше) ... |
|||
:
Нравится:
Не нравится:
|
|||
08.02.2013, 10:43 |
|
|
start [/forum/topic.php?fid=20&msg=38142343&tid=1405200]: |
0ms |
get settings: |
11ms |
get forum list: |
12ms |
check forum access: |
3ms |
check topic access: |
3ms |
track hit: |
53ms |
get topic data: |
10ms |
get forum data: |
3ms |
get page messages: |
55ms |
get tp. blocked users: |
1ms |
others: | 307ms |
total: | 458ms |
0 / 0 |