Многопоточность равна меньше процессора? - PullRequest
3 голосов
/ 04 октября 2011

У меня есть небольшой список довольно больших файлов, которые я хочу обработать, что заставило меня задуматься ...

В C # я думал об использовании Parallel.ForEach TPL для использования преимуществ современных многоядерных процессоров, но мой вопрос носит скорее гипотетический характер;

Означает ли практическое использование многопоточности, что параллельная загрузка файлов (с использованием как можно большего количества ядер ЦП) займет больше времени, а не последовательная загрузка каждого файла (но, вероятно, с меньшим количеством ЦП использование)

Или по-другому (:

Какой смысл многопоточности? Больше задач параллельно, но с меньшей скоростью, в отличие от сосредоточения всех вычислительных ресурсов на одной задаче за раз?

Ответы [ 6 ]

4 голосов
/ 04 октября 2011

Чтобы не увеличивать задержку, параллельные вычислительные программы обычно создают только один поток на ядро. Приложения, которые не являются чисто вычислительными, имеют тенденцию добавлять больше потоков, так что количество работающих потоков - это количество ядер (остальные находятся в состоянии ожидания ввода-вывода и не конкурируют за процессорное время).

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

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

3 голосов
/ 04 октября 2011

Вы задали несколько вопросов, поэтому я разбил свой ответ на несколько ответов:

  1. Многопоточность может не влиять на скорость загрузки, в зависимости от того, какое у вас узкое место во время загрузки. Если вы загружаете много данных с диска или из базы данных, ввод-вывод может быть вашим ограничивающим фактором. С другой стороны, если «загрузка» включает в себя большую часть работы ЦП с некоторыми данными, вы можете ускорить использование многопоточности.

  2. Вообще говоря, вы не можете сосредоточить «все вычислительные ресурсы на одной задаче». Некоторые многоядерные процессоры имеют возможность разгонять одно ядро ​​в обмен на отключение других ядер, но это повышение скорости не равно потенциальному выигрышу в производительности, который вы получили бы от полного использования всех ядер с использованием многопоточности / многопроцессорности. Другими словами, он асимметричен - если у вас 4-ядерный процессор 1 ГГц, он не сможет разогнать одно ядро ​​до 4 ГГц в обмен на отключение остальных. Фактически, это причина, по которой индустрия в первую очередь становится многоядерной - по крайней мере, на данный момент мы достигли пределов того, насколько быстро мы можем запустить один процессор, поэтому вместо этого мы пошли по пути добавления большего количества процессоров.

  3. Есть 2 причины многопоточности. Во-первых, вы хотите, чтобы задачи выполнялись в одно и то же время просто потому, что желательно, чтобы оба выполнялись одновременно - например, вы хотите, чтобы ваш графический интерфейс продолжал реагировать на щелчки или нажатия клавиш клавиатуры, пока он выполняет другую работу (хотя цикл событий - это еще один способ сделать это). Второе - использовать несколько ядер для увеличения производительности.

3 голосов
/ 04 октября 2011

При загрузке файлов с диска это может значительно замедлить процесс * . Что происходит, так это то, что операционная система пытается выложить файлы на диск так, что вам потребуется только один раз выполнить дорогостоящий поиск на диске для каждого файла. Если у вас есть много потоков, читающих много файлов, вы будете иметь разногласия по поводу того, какой поток имеет доступ к диску, и вам придется искать в нужном месте файла каждый раз, когда следующий поток получает включить.

Что вы можете сделать, это использовать ровно две нити. Установите один для загрузки всех файлов в фоновом режиме, а второй оставьте доступным для других задач, например, для обработки пользовательского ввода. В C # winforms вы можете сделать это легко с помощью элемента управления BackgroundWorker.

2 голосов
/ 04 октября 2011

Многопоточность полезна для задач с высокой степенью параллелизации. Интенсивные задачи процессора идеальны. Ваш процессор имеет много ядер, многие потоки могут использовать много ядер. Они будут использовать больше процессорного времени, но в конце они будут использовать меньше «пользовательского» времени. Если ваше приложение ограничено вводом / выводом, то многопоточность не всегда является решением (но МОЖЕТ помочь)

1 голос
/ 04 октября 2011

Может быть полезно сначала понять разницу между многопоточностью и параллелизмом, поскольку чаще всего я вижу, что они используются взаимозаменяемо. Джозеф Албахари написал довольно интересное руководство по этому вопросу: Потоки в C # - Часть 5 - Параллелизм

0 голосов
/ 04 октября 2011

Как и во всех великих начинаниях программирования, зависит от .В общем, вы будете запрашивать файлы из одного физического хранилища или одного физического контроллера, который все равно будет сериализовывать запросы (или, что еще хуже, вызывать ОГРОМНУЮ голову на классическом жестком диске) и замедлять ужемедленный ввод / вывод.

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

...