Подтвердить что ты не робот

Threading vs single thread

Всегда ли гарантируется, что многопоточное приложение будет работать быстрее, чем однопоточное приложение?

У меня есть два потока, которые заполняют данные из источника данных, но разные сущности (например: база данных из двух разных таблиц), похоже, что однопоточная версия приложения работает быстрее, чем версия с двумя потоками.

Почему бы так поступить? когда я смотрю на монитор производительности, оба процессора очень шики? это связано с переключением контекста?

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

Надеюсь, это не двусмысленно.

4b9b3361

Ответ 1

Аналогия может помочь.

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

Сигналы трафика в вашем городе - идеальные сигналы трафика. Они всегда зеленые, если в перекрестке нет кого-то.

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

Проблема заключается в том, что у вас есть только один мотоцикл *. Итак, теперь ваш первый водитель едет на мотоцикле какое-то время, а затем время от времени останавливается, уходит, а второй водитель поднимается, прыгает и едет.

Это быстрее? Нет, конечно нет. Это медленнее. Добавление большего количества потоков не делает ничего быстрее. Нитки не магические. Если процессор способен выполнять миллиард операций в секунду, добавление другого потока не позволяет сделать еще один миллиард операций второй доступной. Скорее, он крадет ресурсы из других потоков. Если мотоцикл может проехать 100 миль в час, остановка велосипеда и привлечение другого водителя не ускоряется! Ясно, что в среднем письма не ускоряются в этой схеме, они просто доставляются в другом порядке.

Хорошо, так что, если вы нанимаете двух водителей и два мотоцикла? Теперь у вас есть два процессора и один поток на процессор, так что будет быстрее, не так ли? Нет, потому что мы забыли про светофоры. Раньше в один момент на скорости был только один мотоцикл. Теперь есть два водителя и два мотоцикла, а это значит, что теперь иногда одному из мотоциклов придется ждать, потому что другой находится на перекрестке. Опять же, добавление большего количества потоков замедляет вас, потому что вы тратите больше времени на блокировки. Чем больше процессоров вы добавляете, тем хуже получается; вы в конечном итоге все больше времени тратите на красные огни и все меньше и меньше времени на вождение сообщений.

Добавление большего количества потоков может привести к отрицательной масштабируемости, если при этом блокируются блокировки. Чем больше потоков, тем больше конфликтов, тем медленнее все идет.

Предположим, что вы делаете двигатели быстрее - теперь у вас больше процессоров, больше потоков и более быстрых процессоров. Всегда ли это происходит быстрее? NO. Часто это не так. Увеличение скорости процессора может привести к замедлению работы многопоточных программ. Опять подумайте о трафике.

Предположим, у вас есть город с тысячами водителей и шестьдесят четыре мотоцикла, водители все бегут туда-сюда между мотоциклами, некоторые из мотоциклов на перекрестках блокируют другие мотоциклы. Теперь вы делаете все эти мотоциклы быстрее. Это помогает? Что ж, в реальной жизни, когда вы едете, вы получаете то место, где вы будете в два раза быстрее в Porsche, чем в Honda Civic? Конечно нет; большую часть времени в городе вождения вы застреваете в движении.

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

Многопоточная производительность может быть очень противоречивой. Если вы хотите экстремально высокую производительность, я рекомендую не использовать многопоточное решение, если у вас нет приложения, которое "смущает параллель", то есть какое-то приложение, которое, очевидно, поддается броску нескольких процессоров, таких как вычисления наборов Мандельброта или трассировка лучей или некоторые такие вещи. И тогда, не бросайте больше проблем в проблему, чем у вас есть процессоры. Но для многих приложений запуск большего количества потоков замедляет вас.

Ответ 2

Мое мнение

Нет, не гарантируется, что многопоточное приложение будет работать быстрее, чем однопоточное приложение. Основная проблема заключается в правильном распределении рабочей нагрузки ко всем доступным ядрам и минимизации блокировки и переключения контекста.

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

В тех случаях, когда задействован пользовательский интерфейс, он почти всегда предпочитает делегировать всю интенсивную работу процессора на потоки, чтобы поддерживать отзывчивость интерфейса. Это, вероятно, самое популярное использование для потоков.

... кажется однопоточной версией приложение работает быстрее, чем версия с двумя потоками.

Проводили ли вы анализ производительности? Если вы этого не сделали, то то, что вы заметили, несколько не имеет значения.

Каковы наилучшие практики для jack CPU и полностью использовать его?

Учитывая описание вашей проблемы, похоже, что ваши проблемы с производительностью связаны с ЦП, но привязка ввода/вывода... ваша связь с базой данных намного медленнее, чем ваш кеш процессора, и если это сетевая база данных, то он даже медленнее, чем ваш жесткий диск. Узкое место вашей производительности связано с вашей базой данных, поэтому все, что вам нужно сделать, это создать достаточно потоков, чтобы максимизировать пропускную способность вашего подключения к базе данных.


Непосредственно из Wikipedia:

Преимущества

Некоторые преимущества включают в себя:

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

Недостатки

Некоторые критические замечания по многопоточности включают:

  • Несколько потоков могут мешать друг другу при совместном использовании аппаратных ресурсов, таких как кеши или буферы перевода (TLB).
  • Времена выполнения одного потока не улучшаются, но могут быть деградированы, даже если выполняется только один поток. Это связано с более медленными частотами и/или дополнительными этапами конвейера, которые необходимы для размещения аппаратуры переключения потоков.
  • Аппаратная поддержка многопоточности более заметна для программного обеспечения, что требует больше изменений как для прикладных программ, так и для операционных систем, чем для многопроцессорной обработки.

Update

Кроме того, сервер базы данных находится на тот же компьютер, что и код. это не сервер sql. это s nosql DBMS. поэтому, пожалуйста, не принимайте ничего о сервере базы данных.

Некоторые системы NoSQL основаны на дисках, и чтение с диска из нескольких потоков почти гарантирует снижение производительности. Жесткому диску, возможно, придется переместить голову в разные сектора диска при переходе между потоками и тем плохим!

Я понимаю, что вы хотели make - это скорость ввода-вывода. но все же это одна и та же машина. почему IO так медленно?

Ваша система NoSQL может быть основана на дисках, поэтому все ваши данные хранятся на диске вместо загрузки в память (например, SQL Server). Кроме того, подумайте об архитектуре: диск - это кеш для ОЗУ, ОЗУ - кеширование кэш-памяти процессора, а кэш CPU - для регистров процессора. Итак, Disk → Ram → cache cache → Registers, есть 3 уровня кэширования, прежде чем вы попадете в регистры. В зависимости от того, сколько данных вы используете, вы можете получать много промахов в кешках для обоих ваших потоков на каждом из этих уровней... промаха в кэше в кэше ЦП будет загружать больше данных из ОЗУ, пропустить кеш в ОЗУ загрузит больше данных с диска, все это приведет к снижению пропускной способности.

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

Не совсем... у вас всего два потока. Сколько раз вы создаете потоки? Как часто вы их создаете? Если вы создаете только два потока и выполняете всю свою работу в этих двух потоках на протяжении всего срока службы приложения, то из-за создания потоков, о которых вы должны беспокоиться, практически нет накладных расходов.

Ответ 3

Если ваша программа тяжелая вводе/выводе и тратит больше времени на ожидание ввода-вывода (например, операции с базой данных), чтобы потоковая передача не выполнялась быстрее.

Если он очень сильно вычисляет в CPU, значит, он будет иметь выгоду или нет, зависит от того, как вы его пишете.

Ответ 4

Конечно нет. Threading налагает накладные расходы, поэтому зависит ли преимущество приложения от parallel.

Ответ 5

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

Ответ 6

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

Я бы предложил написать масштабируемые приложения в SEDA (Staged Event Driven Architecture), когда система состоит из нескольких (5-15) компонентов, и каждый компонент имеет собственную очередь сообщений с ограниченным пулом потоков. Вы можете настроить размер пулов и даже применять алгоритмы, которые изменяют размеры пула потоков, чтобы сделать некоторые компоненты более производительными, чем другие (поскольку все компоненты имеют одни и те же процессоры). Вы можете настроить размер пулов для конкретного оборудования, что делает приложения SEDA чрезвычайно настраиваемыми.

Ответ 7

Я видел примеры в реальном мире, где код так плохо работал с добавлением большего количества процессоров (ужасное нарушение блокировки среди потоков), что системе необходимо было удалить процессоры для восстановления производительности; так что да, можно сделать код хуже, добавив больше потоков выполнения.

Приложения с ограничением IO - еще один хороший пример, упомянутый выше.

Ответ 8

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

введите описание изображения здесь