В версии 5.5.18 расширен объем мониторинговой инфомации от диспетчеров. Теперь можно получать статистику по временам работы и простоя рабочих нитей диспетчеров.
Сбор информации о том, сколько событий обрабатывают рабочие нити диспетчеров и сколько времени на это уходит, нужно явным образом включить. По умолчанию эта информация не собирается дабы не оказывать отрицательного влияния на производительность SObjectizer-а. Включение может происходить как на уровне конкретного диспечера:
using namespace so_5::disp::active_obj; auto disp = create_private_disp( env, "my_disp", // В свойствах диспетчера явным образом включаем сбор // статистики об активности рабочих нитей. disp_params_t{}.turn_work_thread_activity_tracking_on() ); |
Либо это можно сделать сразу для всего SObjectizer Environment при запуске:
so_5::launch( []( so_5::environment_t & env ) { ... // Какие-то начальные действия. []( so_5::environment_params_t & params ) { // Явным образом включаем сбор статистики об активности // рабочих нитей для всех диспетчеров. params.turn_work_thread_activity_tracking_on(); ... } ); |
В этом случае сбор статистики об активности рабочих нитей будет включен для всех диспетчеров, которые будут работать в рамках SObjectizer Environment. Если такую статистику для какого-то из диспетчеров нужно отключить, то это можно сделать в свойствах самого диспетчера:
so_5::launch( []( so_5::environment_t & env ) { ... // Какие-то начальные действия. // Создаем диспетчер, для которого сбор статистики об // активности рабочих нитей будет отключен не смотря на // глобальные параметры для всего SObjectizer Environment. auto my_disp = so_5::disp::one_thread::create_private_disp( env, "my_disp", so_5::disp::one_thread::disp_params_t{} .turn_work_thread_activity_tracking_off() ); ... []( so_5::environment_params_t & params ) { // Явным образом включаем сбор статистики об активности // рабочих нитей для всех диспетчеров. params.turn_work_thread_activity_tracking_on(); ... } ); |
Распространение информации об активности рабочих нитей диспетчеров выполняется обычным образом -- через сообщения, которые отсылаются на почтовый ящик т.н. stats_collector-а. В качестве типа сообщения с этой информации используется тип work_thread_activity из пространства имен so_5::stats::messages.
class activity_listener final : public so_5::agent_t { public : activity_listener( context_t ctx ) : so_5::agent_t( ctx ) { so_default_state().event( so_environment().stats_controller().mbox(), &activity_listener::evt_monitor_activity ); } private : void evt_monitor_activity( const so_5::stats::messages::work_thread_activity & evt ) { namespace stats = so_5::stats; std::cout << evt.m_prefix << evt.m_suffix << " [" << evt.m_thread_id << "] ->\n" << " working: " << evt.m_stats.m_working_stats << "\n" << " waiting: " << evt.m_stats.m_waiting_stats << std::endl; ... } }; |
Внутри work_thread_activity, помимо уже привычных m_prefix и m_suffix, находятся следующие поля:
- m_thread_id с идентификатором рабочей нити, для которой получена статистика;
- m_working_stats с информацией о временах работы этой нити;
- m_waiting_stats с информацией о временах простоя этой нити.
Поля m_working_stats и m_waiting_stats имеют тип so_5::stats::activity_stats_t:
struct activity_stats_t { //! Count of events in that period of time. std::uint_fast64_t m_count{}; //! Total time spent for events in that period of time. duration_t m_total_time{}; //! Average time for one event. duration_t m_avg_time{}; }; |
Где тип duration_t -- это либо std::chrono::high_resolution_clock::duration, либо std::chrono::steady_clock::duration (в зависимости от того, является для на данной платформе high_resolution_clock т.н. steady clock-ом или нет).
Т.о. посредством сообщения work_thread_activity можно узнать: сколько всего событий было обработанно нитью (с самого начала ее работы), сколько всего времени было потрачено внутри обработчиков событий (с самого начала работы нити), какова средняя длительность обработчика события. Аналогично и по временам простоя рабочей нити.
Вот небольшой пример того, как эта статистическая информация может выглядеть:
disp/atp/0x2b7fb70/threads.count: 4
disp/atp/0x2b7fb70/agent.count: 5
disp/atp/0x2b7fb70/wt-14/thread.activity [14] ->
working: [count=5651;total=3.86549ms;avg=0.000655ms]
waiting: [count=5652;total=492.831ms;avg=3.60857ms]
disp/atp/0x2b7fb70/wt-15/thread.activity [15] ->
working: [count=62394;total=40.4094ms;avg=0.000644ms]
waiting: [count=62395;total=363.346ms;avg=0.201897ms]
disp/atp/0x2b7fb70/wt-16/thread.activity [16] ->
working: [count=69073;total=46.2095ms;avg=0.000637ms]
waiting: [count=69073;total=361.668ms;avg=0.000813ms]
disp/atp/0x2b7fb70/wt-17/thread.activity [17] ->
working: [count=80587;total=52.904ms;avg=0.000656ms]
waiting: [count=80588;total=325.136ms;avg=0.003536ms]
disp/atp/0x2b7fb70/cq/__so5_au...e_2__/agent.count: 5
disp/atp/0x2b7fb70/cq/__so5_au...e_2__/demands.count: 4
Это дамп мониторинговой информации для adv_thread_pool-диспетчера с четырьмя рабочими нитями. На этом диспетчере работает одна кооперация с пятью агентами внутри. Можно увидеть информацию по каждой из рабочих нитей (в квадратных скобках указан ID нити). В данном случае можно определить, что рабочие нити больше времени проводят в ожидании событий, а не в их обработке.
Несколько слов о влиянии сбора статистики об активности рабочих нитей на производительность диспечтеров. Это сильно зависит как от типа диспетчера, так и от профиля нагрузки. Для one_thread-диспетчера с большим потоком сообщений это влияние может быть совсем незаметным. А для active_obj-диспетчера с одиночными сообщениями производительность может просесть в 3-4 раза. Поэтому каких-то общих показателей изменения производительности в зависимости от включения режима сбора информации об активности рабочих нитей нет, слишком уж большой разброс.
В любом случае данный механизм сейчас рассматривается как вспомогательный, предназначенный для целей отладки и профилирования. Необходимо предварительно проверить, какое именно влияние данный механизм оказывает именно на ваше приложение под вашим профилем нагрузки. И только после этого принимать решение о том, стоит ли активировать этот механизм для запущенных "на бой" приложений.
Комментариев нет:
Отправить комментарий