Оптимизация производительности

Материал из WebHMI Wiki
Перейти к: навигация, поиск
На этой странице были произведены изменения, не отмеченные для перевода.

Другие языки:
English • ‎русский

Для понимания принципов работы WebHMI давайте разберем как работает ее ядро.

Схематично структуру ядра системы можно изобразить так:

WebHMI-диаграма.png

Ядро работает циклично. Это значит что все действия выполняются последовательно. Если на каком-то из этапов возникают задержки то это оказывает влияние на время выполнения всего цикла.

Давайте рассмотрим каждый из блоков этой диаграммы.

Чтение конфигурации

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

Когда настройки проекта прочитаны ядро входит в главный цикл.

Запись новых значений в регистры

В начале цикла происходит запись новых значений в регистры. В системе есть специальная очередь для записи новых значений в регистры. Есть 2 способа записать данные в регистр - через API и через сценарии. В обоих случаях запись происходит не в тот момент когда поступает запрос (т.к. система может быть не готова к этому, например по RS-485 в данный момент уже идет обмен с ПЛК) а позже, в подходящее для этого время. Запрос на запись поступает в очередь. Все запросы на запись будут выполнены в начале следующего главного цикла.

Чтение регистров

Далее происходит чтение регистров из внешних устройств и внутренних регистров WebHMI. Регистры читаются группами. Группировка происходит по их соединению. Например, если в проекте есть соединение с ПЛК Delta, ПЛК Siemens и внутренними регистрами WebHMI то чтение будет выглядеть так:

1. Читаются все регистры из ПЛК Delta
2. Читаются все регистры из ПЛК Siemens
3. Читаются все внутренние регистры WebHMI

Внутренние регистры WebHMI читаются всегда последними (т.к. в них есть регистры C0, C1, C2... в которых хранятся ошибки чтения из остальных соединений).

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

Если для любого из соединений указана стабилизационная пауза то перед чтением группы регистров этого соединения произойдет соответствующая пауза. Это иногда необходимо для стабильной работы разнородных устройств на одной шине RS-485. Без этой паузы некоторые устройства могут не успеть определить начало кадра сообщения и пропускать первый пакет на чтение первого регистра.

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

Это значит что если нет связи с одним из внешних устройств то общее время опроса (минимальная длина главного цикла) увеличится на Timeout × Количество регистров в этом соединении.

Пример. У нас есть подключение к ПЛК Delta SX2 по ModBus RTU. Мы читаем из него 5 регистров на скорости 115200. Timeout установлен в 100 мс. Среднее время чтения всех пяти регистров составляет 30 мс (посмотреть его можно во внутреннем регистре WebHMI T1). Если связь с ПЛК пропадет по любой из причин то среднее время чтения всех пяти регистров теоретически увеличится до 5 × 100 мс = 500 мс (а на практике будет примерно 525 мс).

Это означает что если в проекте есть опрос неподключенного устройства то это замедлит весь цикл на существенное количество времени. Если необходимо минимизировать эту задержу то необходимо максимально увеличивать скорость обмена и уменьшать Timeout и Stabilization pause. Но лучше всего - или восстановить связь с устройством или отключить это соединение в настройках.

Выполнение сценариев

После того как регистры были прочитаны ядро выполняет сценарии. Сценарии выполняются очень быстро и задержек здесь быть не должно при разумном количестве и сложности сценариев. Единственная особенность на которую следует обратить внимание - это различие в механизме работы операций Set и Write.

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

Операция Write делает все то же самое то и Set с тем лишь отличием что добавляет команду на запись нового значения в очередь записи. И в начале следующего цикла это значение будет записано в соответствующий регистр внешнего устройства.

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

Вычисление состояний регистров

К этому моменту главного цикла уже значения всех регистров вычислены и дальше меняться не будут. Поэтому именно в этом месте вычисляются состояния для каждого регистра (invalid / disabled / normal / warning / alert).

Обработка событий

После того как все данные собраны и подготовлены, запускается механизм идентификации и обработки событий.

Обработка событий начинается с проверки условия наступления события. Аналогично сценариям, если любой регистр из условия не был прочитан в текущем цикле, то это условие не будет обработано. И соответсвенно не будет обработано все событие.

Если событие НЕ имеет протяженности во времени то условие его наступления проверяется в каждом цикле. И при каждом выполнении этого условия будут выполнятся действия для этого события. В каждом последующем цикле если условие выполнится опять то это будет уже новое наступление события и действия выполнятся снова.

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

При выполнении условия начала события флаг выполнения взводится в true. При выполнении условия окончания (если оно задано) или при первом невыполнении условия начала (если не задано условие окончания) события флаг сбрасывается в false.

Пока этот флаг равен true, выполняются все действия для этого события. Этот флаг также можно вычитать через внутренние регистры WebHMI по адресу ESx, где x - ID события. Обратите внимание, что первое значение true будет вычитано в цикле, следующем за тем, в котором это значение true было выставлено.

Среди действий, доступных для событий, есть запись информации о событии в базу данных. Следует понимать что эта операция - ресурсоемка. Поэтому рекомендуется писать данные настолько редко насколько это допустимо. И собирать только необходимые данные. Нет смысла записывать все регистры в базу в каждом цикле, если достаточно собрать данные о пяти регистрах с интервалом 5 секунд. Также, черезмерная детализация при сборе данных чревата большой нагрузкой на SD карту и повышенному ее износу.

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

Одной из опций при сохранении данных о событии является запись среза значений регистров каждые N секунд. Фактически это реализовано так, что запись будет происходить не чаще чем через каждые N секунд от прошедшей записи в базу данных. Здесь следует объяснить особенность работы этого интервала. Лучше всего это сделать на примере.

Пример. Ядро читает 150 регистров по ModBus, средняя длина цикла 1.3 секунды. Событие настроено записывать данные каждые 5 секунд. Допустим что событие выполнилось первый раз в T+0.0 секунд. Данные были записаны в базу данных тоже в T+0.0 секунд.

В следующем цикле событие все еще выполняется. Время с последней записи T+1.3 секунды. 1.3 c < 5 c поэтому запись в БД не произойдет.
В следующем цикле событие все еще выполняется. Время с последней записи T+2.6 секунды. 2.6 c < 5 c поэтому запись в БД не произойдет.
В следующем цикле событие все еще выполняется. Время с последней записи T+3.9 секунды. 3.9 c < 5 c поэтому запись в БД не произойдет.
В следующем цикле событие все еще выполняется. Время с последней записи T+5.2 секунды. 5.2 c < 5 c поэтому запись в БД произойдет. Далее система будет сравнивать время с моментом T+5.2.

Обратите внимание, что фактическое время между записями составит 5.2 секунды а не 5. Т.к. система отображает время с секундной точностью то это может привести к тому что время между записями будет отображаться как 6 секунд, а при некоторых вариациях и 7 секунд (например, первая запись была в T+0.9, а вторая - в T+6.1).

Т.е. из-за того что длина цикла может быть непостоянной то и фактический интервал записи данных тоже будет зависеть от этой длины. Оптимальнее всего система будет себя вести если заданный интервал опроса устройств (Communication interval) превышает фактическую длину цикла и запись в базу ведется с интервалом кратным (Communication interval).

Подготовка значений регистров для API

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

Запись значений в базу данных

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

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

Поэтому рекомендуется писать в лог только те регистры, которые действительно необходимы. Также рекомендуем писать их не слишком часто. Запись 10-20 параметров каждую секунду может существенно загрузить систему, уменьшить отзывчивость интерфейса, увеличить длину цикла.

Пауза

После того как все операции были выполнены, система определяет сколько фактически было затрачено времени на выполнение текущего цикла. Если это время меньше чем настройка Communication interval то система сделает паузу в работе на разницу [Communication interval – фактическое время] для того, что бы общая длина цикла составила ровно указанное в Communication interval время.

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

Если необходимо вложиться в указанный интервал то есть несколько путей оптимизации:
1. Увеличить скорость обмена по шинам RS-485, RS-232. Скорость 9600 слишком медленная для большого количества данных. Рекомендуем выбирать скорость 115200 и выше.
2. Если регистров много и не все нужно опрашивать в каждом цикле то можно указать больший интервал опроса менее важных регистров. Это разгрузит систему и шины данных.