Это сложный вопрос, который вы задаете. Трудно сказать, не зная больше о природе ваших тем. Некоторые вещи, которые следует учитывать при диагностике производительности системы:
Является ли процесс / поток
- Процессор привязан (требуется много ресурсов процессора)
- Ограничение памяти (требуется много ресурсов оперативной памяти)
- Привязка ввода / вывода (ресурсы сети и / или жесткого диска)
Все эти три ресурса являются конечными, и любой из них может ограничить производительность системы. Вы должны посмотреть, что (может быть 2 или 3 вместе) потребляет ваша конкретная ситуация.
Вы можете использовать ntop
и iostat
, и vmstat
для диагностики того, что происходит.
"Почему это происходит?" вроде легко ответить. Представьте, что у вас есть коридор, в котором вы можете разместить четырех человек рядом друг с другом. Вы хотите переместить весь мусор с одного конца, с другого конца. Самое эффективное количество людей - 4.
Если у вас 1-3 человека, вам не хватает пространства в коридоре. Если у вас 5 или более человек, то, по крайней мере, один из этих людей все время застревает в очереди за другим человеком. Добавление все большего количества людей просто забивает коридор, это не ускоряет активность.
Таким образом, вы хотите, чтобы у вас было столько людей, сколько вы можете вместить без очереди. Почему у вас есть очереди (или узкие места) зависит от вопросов в ответе slm.
источник
4
это лучший номер.Общая рекомендация - это n + 1 потоков, где n - количество доступных процессорных ядер. Таким образом, n потоков могут работать с процессором, в то время как 1 поток ожидает дискового ввода-вывода. Меньшее количество потоков не будет полностью использовать ресурс ЦП (в какой-то момент всегда будет ожидание ввода / вывода), а наличие большего количества потоков вызовет конфликты потоков за ресурс ЦП.
Потоки приходят не бесплатно, а с переключателями контекста, как издержки, и - если обмен данными происходит между потоками, как это обычно бывает, - различные механизмы блокировки. Это стоит затрат только тогда, когда у вас есть больше выделенных ядер ЦП для запуска кода. На одноядерном процессоре один процесс (без отдельных потоков) обычно быстрее, чем любая поточная обработка. Потоки магическим образом не заставляют ваш процессор работать быстрее, это просто означает дополнительную работу.
источник
Как другие отмечали, ( ОДС ответ , EightBitTony ответ ) это сложный вопрос , и тем более, так как вы не описать то , что вы thred делать и как они это делают.
Но окончательное добавление большего количества потоков может ухудшить ситуацию.
В области параллельных вычислений существует закон Амдала, который может быть применим (или не может, нет, но вы не описываете детали вашей проблемы, так что ...) и может дать общее представление об этом классе проблем.
Суть закона Амдаля заключается в том, что в любой программе (в любом алгоритме) всегда есть процент, который не может быть запущен параллельно ( последовательная часть ), и есть другой процент, который может быть запущен параллельно ( параллельная часть ) [Очевидно, эти две части составляют до 100%].
Эта часть может быть выражена в процентах от времени выполнения. Например, 25% времени может быть потрачено на строго последовательные операции, а оставшиеся 75% времени уходит на операции, которые могут выполняться параллельно.
(Изображение из Википедии )
Закон Амдаля предсказывает, что для каждой заданной параллельной части (например, 75%) программы вы можете ускорить выполнение только до сих пор (например, не более 4 раз), даже если для выполнения работы вы используете все больше и больше процессоров.
Как правило, чем больше вы программируете программ, которые вы не можете преобразовать при параллельном выполнении, тем меньше вы можете получить, используя больше исполнительных блоков (процессоров).
Учитывая, что вы используете потоки (а не физические процессоры), ситуация может быть даже хуже, чем эта. Помните, что потоки могут обрабатываться (в зависимости от реализации и доступного аппаратного обеспечения, например, процессоров / ядер), использующих один и тот же физический процессор / ядро (это форма многозадачности, как указано в другом ответе).
Этот теоретический прогноз (о времени ЦП) не учитывает практические узкие места как
это легко может быть ограничивающим фактором в практическом применении.
источник
Виновником здесь должно быть «ПЕРЕКЛЮЧЕНИЕ КОНТЕКСТА». Это процесс сохранения состояния текущего потока, чтобы начать выполнение другого потока. Если несколько потоков имеют одинаковый приоритет, их необходимо переключать до завершения выполнения.
В вашем случае, когда имеется 50 потоков, происходит много переключений контекста по сравнению с просто выполнением 10 потоков.
На этот раз накладные расходы, связанные с переключением контекста, заставляют вашу программу работать медленно
источник
ps ax | wc -l
225 процессов, и он ни в коем случае не сильно загружен). Я склонен согласиться с предположением @ EightBitTony; аннулирование кеша, вероятно, является более серьезной проблемой, потому что каждый раз, когда вы очищаете кеш, процессор должен ждать эоны для кода и данных из оперативной памяти.Чтобы исправить метафору EightBitTony:
Человек здесь - это поток, а сегмент представляет собой узкое место, где находится ресурс выполнения. Добавление большего количества потоков не поможет, если они ничего не могут сделать. Кроме того, мы должны подчеркнуть, что передача ведра от одного человека другому обычно медленнее, чем один человек, несущий ведро на одинаковом расстоянии. То есть два потока по очереди на ядре обычно выполняют меньше работы, чем один поток, работающий вдвое дольше: это связано с дополнительной работой, выполняемой для переключения между двумя потоками.
То, является ли ограничивающий ресурс выполнения (сегмент) процессором, ядром или гиперпоточным конвейером команд для ваших целей, зависит от того, какая часть архитектуры является вашим ограничивающим фактором. Обратите внимание, что мы предполагаем, что потоки полностью независимы. Это только в том случае , если они не разделяют ни одного данных (и избежать каких - либо столкновений кэша).
Как предположили несколько человек, для ввода-вывода ограничивающим ресурсом может быть количество полезных операций ввода-вывода, которые можно поставить в очередь: это может зависеть от целого ряда аппаратных факторов и факторов ядра, но может легко оказаться намного больше, чем число сердечники. Здесь переключение контекста, которое так дорого по сравнению с кодом, связанным с выполнением, довольно дешево по сравнению с кодом, связанным с вводом / выводом. К сожалению, я думаю, что метафора полностью выйдет из-под контроля, если я попытаюсь оправдать это ведрами.
Обратите внимание, что оптимальное поведение кода, связанного с вводом / выводом, обычно по- прежнему должно содержать не более одного потока на конвейер / ядро / процессор. Однако вы должны написать асинхронный или синхронный / неблокирующий код ввода-вывода, и относительно небольшое повышение производительности не всегда оправдывает дополнительную сложность.
PS. Моя проблема с оригинальной метафорой коридора состоит в том, что я настоятельно рекомендую иметь 4 очереди людей, из которых 2 очереди несут мусор, а 2 возвращаются, чтобы собрать больше. После этого вы можете сделать каждую очередь почти до тех пор , как коридор, и добавляющие люди сделали скорость до алгоритма (вы в основном превратили весь коридор в конвейерной ленте).
На самом деле этот сценарий очень похож на стандартное описание взаимосвязи между задержкой и размером окна в сети TCP, поэтому он у меня появился.
источник
Это довольно просто и понятно. Имея больше потоков, чем поддерживает ваш процессор, вы фактически сериализуетесь, а не распараллеливаете. Чем больше у вас потоков, тем медленнее будет ваша система. Ваши результаты на самом деле являются доказательством этого явления.
источник