Больше потоков, лучшая производительность?

import pandas_datareader.data as web 
import datetime
df = web.DataReader('SPY', 'yahoo', '2019-02-12','2019-02-19')
df = df.reset_index()
df['Date'] = df['Date'].astype(str)

DataFrame

>>> df
    Date        High        Low         Open        Close       Volume      Adj Close
0   2019-02-12  274.519989  272.339996  272.420013  274.100006  72270200    274.100006
1   2019-02-13  275.929993  274.559998  275.029999  274.989990  65277200    274.989990
2   2019-02-14  275.640015  272.869995  273.779999  274.380005  83234400    274.380005
3   2019-02-15  277.410004  276.130005  276.359985  277.369995  97088700    277.369995
4   2019-02-19  278.579987  276.470001  276.480011  277.850006  59120800    277.850006

Участок

ax = df['Close'].plot(marker='o')
ax.set_xticks(df.index)
ax.set_xticklabels(df['Date']);

Plot

5
задан Shog9 21 June 2009 в 21:45
поделиться

10 ответов

Все зависит.

Например:

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

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

3
ответ дан 18 December 2019 в 10:48
поделиться

Конкретный выбор модели потоков должен зависеть от характера проблемы, которую вы пытаетесь решить. Не существует единого «правильного» подхода к разработке модели потоков для такого приложения. Однако, если мы примем следующие допущения:

  1. сообщения приходят часто
  2. сообщения независимы и не слишком сильно зависят от общих ресурсов
  3. , желательно ответить на прибывающее сообщение как можно быстрее
  4. Вы хотите, чтобы приложение хорошо масштабировалось на архитектурах обработки (т. е. многокодовых / многопроцессорных системах).
  5. масштабируемость является ключевым требованием при проектировании (например, увеличение количества сообщений с более высокой скоростью)
  6. . 12106] По моему опыту, наиболее эффективной архитектурой потоков будет использование пула потоков. Все сообщения поступают в одну очередь, несколько потоков ждут в очереди и обрабатывают сообщения по мере их поступления. Реализация пула потоков может смоделировать все три примера распределения потоков.

    # 1 Один поток обрабатывает все сообщения => пул потоков только с одним потоком

    # 2 Поток на N типов сообщений => пул потоков с N потоками каждый поток заглядывает в очередь, чтобы найти подходящие типы сообщений

    # 3 Несколько потоков для всех сообщений => пул потоков с несколькими потоками

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

    Существует множество хороших библиотек пула потоков, доступных для большинства платформ, включая .NET, C ++ / STL, Java и т. Д.

    Что касается вашего второго вопроса, следует ли использовать стандартный механизм диспетчеризации сообщений Windows. Этот механизм имеет значительные накладные расходы и на самом деле предназначен только для прокачки сообщений через цикл пользовательского интерфейса Windows-приложения. Если это не та проблема, которую вы пытаетесь решить, я бы не советовал использовать ее в качестве общего решения для рассылки сообщений. Кроме того, сообщения Windows несут очень мало данных - это не объектно-ориентированная модель. Каждое сообщение Windows имеет код и 32-битный параметр. Этого может быть недостаточно для построения чистой модели обмена сообщениями. Наконец, очередь сообщений Windows не предназначена для обработки таких случаев, как насыщение очереди, нехватка потоков или повторная очередь сообщений;

8
ответ дан 18 December 2019 в 10:48
поделиться

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

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

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

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

3
ответ дан 18 December 2019 в 10:48
поделиться

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

Если вы пишете приложение с графическим интерфейсом, пользовательский интерфейс должен быть отзывчивым. Вам не важно, сколько кликов в секунду вы можете обработать, но вам важно показать ответ в течение одной десятой секунды или около того (в идеале меньше). Это одна из причин, по которой лучше иметь отдельный поток, посвященный обработке GUI (другие причины были упомянуты в других ответах). Поток GUI должен в основном конвертировать сообщения Windows в рабочие элементы и позволить вашей рабочей очереди справиться с тяжелой работой. По завершении работы он уведомляет поток графического интерфейса, который затем обновляет отображение, чтобы отразить любые изменения. Это делает такие вещи, как рисование окна, но не рендеринг данных для отображения. Это дает приложению быструю «привязанность», что и требуется большинству пользователей, когда они говорят о производительности. Их не волнует, что для выполнения чего-то сложного требуется 15 секунд, пока они нажимают кнопку или меню, они реагируют мгновенно.

Другая характеристика производительности - пропускная способность. Это количество заданий, которые вы можете обработать за определенное время. Обычно этот тип настройки производительности необходим только для приложений серверного типа или другой сложной обработки. Он измеряет, сколько веб-страниц может быть обработано за час, или сколько времени занимает рендеринг DVD. Для такого рода заданий вы хотите иметь 1 активный поток на процессор. Меньше, чем это, и вы будете тратить время простоя часов. Больше чем это, и потоки будут конкурировать за процессорное время и спотыкаясь друг на друга. Взгляните на второй график в этой статье DDJ Articles для компромисса, с которым вы имеете дело. Обратите внимание, что идеальное количество потоков больше, чем количество доступных процессоров, из-за таких вещей, как блокировка и блокировка. Ключом является число активных потоков.

1
ответ дан 18 December 2019 в 10:48
поделиться

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

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

1
ответ дан 18 December 2019 в 10:48
поделиться

Хорошее начало - спросите себя, зачем вам нужно несколько потоков.

Продуманный ответ на этот вопрос приведет вас к наилучшему ответу на следующий вопрос, «Как мне использовать несколько потоков в моем приложении?»

И это должен быть следующий вопрос; не основной вопрос. Первый вопрос должен быть почему, а не как.

0
ответ дан 18 December 2019 в 10:48
поделиться

Я думаю, это зависит от того, как долго будет работать каждый поток. Каждое сообщение занимает одинаковое количество времени для обработки? Или, например, определенные сообщения займут несколько секунд. Если бы я знал, что для завершения Сообщения А потребуется 10 секунд, я бы определенно использовал новый поток, потому что зачем мне задерживать очередь для длинного потока ...

Мои 2 цента.

0
ответ дан 18 December 2019 в 10:48
поделиться

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

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

Отдельная очередь дает лучший контроль в том смысле, что вы можете переупорядочить ее так, как хотите (может зависеть от приоритета)

0
ответ дан 18 December 2019 в 10:48
поделиться

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

(1) представляет узкое место для обработки сообщений
(3) вводит конфликт блокировки, потому что вам нужно синхронизировать доступ к вашей общей очереди.

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

Если вам нравится вариант №2, звучит так, как если бы вы были заинтересованы в реализации архитектуры SEDA . Потребуется некоторое чтение, чтобы понять, что происходит, но я думаю, что архитектура хорошо вписывается в ваш образ мышления.

Кстати, Выход - хорошая гибридная реализация на C ++ / Python.

0
ответ дан 18 December 2019 в 10:48
поделиться

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

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

Более сложный подход - это самоанализ системы. собственные характеристики производительности и адаптировать использование ресурсов, в частности потоков, по мере продвижения. Вероятно, это излишек для большинства пользовательских кодов приложений, но я уверен, что есть продукты, которые это делают.

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

0
ответ дан 18 December 2019 в 10:48
поделиться
Другие вопросы по тегам:

Похожие вопросы: