Reentrant execution

Общие принципы, проектирование, модуляризация, темплейты и шаблоны
Helga
user
user
Сообщения: 89
Зарегистрирован: 14 мар 2010, 10:14
Версия LabVIEW: 9
Контактная информация:

Reentrant execution

Сообщение Helga »

Добрый день!
Мне очень нравиться ваш форум. Читаю с удовольствием! :think:
Работаю сейчас над небольшим проектом. И сразу перешла с 7-ой версии на 8.6. Долго работала на 7-й из-за проблем с лицензиями(маленькие фирмы были, дорого). А новый проект с уже с поставленным заданием(сама не проектировала) и очень многие части уже готовые. И времени мало.
Суть задачи такая - много приборов(ca. 20). Они постоянно опрашиваются через отдельную программу DatenSammler, которая запускается основной программой как отдельная программа. Основная программа и DatenSammler коммуницируют через vi, которая все хранит в шифт-регистрах. DatenSammler заносит данные, программа читает. Приборы подключены через COM-порты. Основная программа сама управляет несколькими приборами для выставления экспериментальных точек. Вызов драйверов происходит через Call By Reference Node. Подпрограмма, которая вызывает драйверы, еще и reentrant execution, т.к. вызывает параллельно до 8 драйверов. И еще несколько подпрограмм reentrant execution. И все так красиво - мне нравиться! Но - висит!
Заметила, что зависать начинает быстрее, если несколько раз запускать программу в режиме отладки.
В драйверах тоже подпрограммка инициализации порта сделана reentrant execution, чтобы параллельно все запускалось. Но это я переделаю для каждого прибора сделаю свою копию.
Мне кажется, что происходит переполнение памяти из-за клонов. А как с этим бороться? И как эти копии можно отследить? Сколько их. Почему они не закрываются при остановке программы. При Scare clones еще хуже.
Или вообще проблема не здесь? Если убрать reentrant execution тоже медлено все работает. При первом запуске с reentrant execution работает все превосходно! А потом может зависнуть, а может и не зависнуть. Но при последующих запусках зависает точно. Приходиться закрывать LabVIEW.
Есть аналог программы на С или дельфе( без кода) работает нормально. Отговорки, что так и должно быть - не проходят!
Есть ли у кого опыт работы с опцией reentrant execution? Помогите! :suicide:
Аватара пользователя
Konstantin Sumenko

Activity Bronze
expert
expert
Сообщения: 1439
Зарегистрирован: 17 июл 2008, 12:20
Награды: 2
Версия LabVIEW: 2010
Откуда: Moscow
Поблагодарили: 1 раз
Контактная информация:

Re: reentrant execution

Сообщение Konstantin Sumenko »

Очень сложно будет ответить на вопрос не видя саму программу. Share Clones тут лишний. Могут возникать проблемы из-за использования timed loop. Возможно что-то не правильно инициализируется при повторных запусках (раз при первом работает нормально)- проверяй неинициализированнные сдвиговые регистры, функции first call. Так же проверяй крупные блоки на предмет ресурсоемкости. Можешь подробнее описать программу, которая вызывает драйверы?
Helga
user
user
Сообщения: 89
Зарегистрирован: 14 мар 2010, 10:14
Версия LabVIEW: 9
Контактная информация:

Re: reentrant execution

Сообщение Helga »

Драйверы оформлены в виде библиотек "прибор.lvlib". Основной файл называется "прибор.vi". А через него вызывается уже подпрограммы, которые читают или пишут. СОМ-порт, VISA - все стандартно. Текст не могу привести по условию контракта.
Это позволяет формировать динамический вызов драйверов по массиву приборов. По названию прибора формируешь путь к файлу и запускаешь файл через Call By Reference Node. Получается простая подпрограммка, которая получает имя прибора, формирует путь к драйверу и запускает драйвер на считывание или подачу команды. Эта подпрограммка используется в нескольких местах и поэтому имеет опцию reentrant execution; preallocate clone. Причем она используется как в основной программе, так и в DatenSammler.
Мне непонятен термин "неинициализированнные сдвиговые регистры".
Как проверить "ресурсоемкость". Никаких больших массивов нет. Базы данных тоже нет. Файлы пишутся не очень большие и эта часть еще в процессе написания. Можно сказать что и не пишутся пока.
Не очень понимаю, что происходит, когда одновременно обращаешься к 8 СОМ-портам. СОМ-порты организованы через USB- переходник.
Helga
user
user
Сообщения: 89
Зарегистрирован: 14 мар 2010, 10:14
Версия LabVIEW: 9
Контактная информация:

Re: reentrant execution

Сообщение Helga »

Сдвиговый регистр - Shift register
В основном иннициализируется так
Изображение
Helga
user
user
Сообщения: 89
Зарегистрирован: 14 мар 2010, 10:14
Версия LabVIEW: 9
Контактная информация:

Re: reentrant execution

Сообщение Helga »

Никогда раньше не пыталась комуницировать одновременно с несколькими портами. Всегда последовательно. А последнее время вообще через микроконтролер. Собрать данные с приборов была задача микроконтролера. А я получала строку и разбивала ее в соответствии с протоколом.
А в этом проекте задумано так что возможно параллельное обращение к 16 СОМ-портам одновременно. Да, в LabVIEW нарисуем 16 квадратиков, а что Windows с этим будет делать? Так прямо одновременно все порты опросит? На сколько это все оправдано?
И что происходит, когда динамически вызываешь подпрограмму, которая в свою очередь использует подпрограмму с опцией reentrant execution? При каждом вызове новая копия? И старая не закрывается?
Аватара пользователя
Konstantin Sumenko

Activity Bronze
expert
expert
Сообщения: 1439
Зарегистрирован: 17 июл 2008, 12:20
Награды: 2
Версия LabVIEW: 2010
Откуда: Moscow
Поблагодарили: 1 раз
Контактная информация:

Re: reentrant execution

Сообщение Konstantin Sumenko »

Хотя бы через profile посмотреть как себя все приложение и отдельные куски ведут. То, что на приведенной картинке и есть неинициализированный сдвиговый регистр (в том смысле, что перед циклом не инициализируется). Modus ответственен за инициализацию при первом запуске данной VI или ее клона в рамках всего приложения.
Про параллелизм: при одном ядре строго одновременно не опросит, но ковеерное исполнение вещь отличная :D При наличии нескольких ядер ускорение выполнении программы может варьироваться от заметного до практически неразличимого (все зависит от компилятора, самой программы).
Каждый раз, когда вызывается reentant VI LV выделяет необходимое кол-во памяти и запускает эту VI не дожидаясь завершения предыдущих клонов. По завершению работы клона он не остается в памяти.
Между клонами есть какая-нибудь связь (Глобальные переменные общие очереди и прочее)? Я к тому, что еще может возникать коллизия чтения/записи (Race condition)..
Helga
user
user
Сообщения: 89
Зарегистрирован: 14 мар 2010, 10:14
Версия LabVIEW: 9
Контактная информация:

Re: reentrant execution

Сообщение Helga »

Ой, как это полезно с профессионалами общаться!
А то мы тут самоучки и варимся в "собственном соку".
А может тему открыть по методам продвинутой отладки. Там в тулсах еще чего-то есть про мемори и какие-то метрики! Завтра все опробую! :crazy:
Helga
user
user
Сообщения: 89
Зарегистрирован: 14 мар 2010, 10:14
Версия LabVIEW: 9
Контактная информация:

Re: reentrant execution

Сообщение Helga »

Клоны между собой не связаны. Никаких общих данных. Но я читала в хелпе, что при reentrant не стоит пользоваться Shift register. А они есть, но с нормальной инициализацией.
Изображение
Аватара пользователя
Konstantin Sumenko

Activity Bronze
expert
expert
Сообщения: 1439
Зарегистрирован: 17 июл 2008, 12:20
Награды: 2
Версия LabVIEW: 2010
Откуда: Moscow
Поблагодарили: 1 раз
Контактная информация:

Re: reentrant execution

Сообщение Konstantin Sumenko »

Ими стоит пользоваться, если они должным образом инициализируются, в противном случае, в них может находиться информация из "чужого" блока памяти. Посмотри любую VI в палитре point by point.
А каким образом клоны передают выходные данные?
Helga
user
user
Сообщения: 89
Зарегистрирован: 14 мар 2010, 10:14
Версия LabVIEW: 9
Контактная информация:

Re: Reentrant execution

Сообщение Helga »

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

DatenSammler устроен из двух одинаковых циклов. Просто чтобы можно было приборы поделить на группы, какие надо только опрашивать, а какими еще и управлять. Каждый цикл может вызывать одновременно до 16 приборов. Пока в работе 12. Подпрограммка примерно такая, быстро сляпала, не очень уверена в деталях
Изображение
Вызывает почти стандартные
Изображение
По profile все время уходит на write_device.vi, остальные не существенно. Но оно и понятно, программа только тем и занята, что приборы опрашивает. Все остальное - график, обработка данных - быстро. Получается, что если в цикле задержка 500 мсек, то работает, 100 - висит.
Время выполнения write_device.vi получается аж 2 сек. Причем, время тратиться самой программой, а подпрограммами 25%. Где тут подпрограммы, я не понимаю! Если та что вызывается, то на что идет время у основной программы?
2 сек - ну парочка приборов есть медленных, но не до такой же степени.
Аватара пользователя
Konstantin Sumenko

Activity Bronze
expert
expert
Сообщения: 1439
Зарегистрирован: 17 июл 2008, 12:20
Награды: 2
Версия LabVIEW: 2010
Откуда: Moscow
Поблагодарили: 1 раз
Контактная информация:

Re: Reentrant execution

Сообщение Konstantin Sumenko »

Подпрограмма скорее всего это клон BasicSerial. Она выполняется долго, так как в порт пишется много данных с маленькой скоростью, так? Кстати а за сколько времени прибор формирует ответ? Возможно проблема в таймауте в VISA READ.
Аватара пользователя
mzu2006

Professionalism Tutorials Black
doctor
doctor
Сообщения: 2456
Зарегистрирован: 16 авг 2008, 02:12
Награды: 3
Версия LabVIEW: 7.1 10 11 12
Откуда: St-Petersburg (RU), Phila, Boston, Washington DC
Контактная информация:

Re: Reentrant execution

Сообщение mzu2006 »

А приборы идентичные? И различаются только номером COM-порта?
Helga
user
user
Сообщения: 89
Зарегистрирован: 14 мар 2010, 10:14
Версия LabVIEW: 9
Контактная информация:

Re: Reentrant execution

Сообщение Helga »

Приборы все разные.
Пардон, write_device.vi работает в среднем около 40 мсек. Причем хоть в зависнутом состоянии, хоть нет. Драйверы приборов все протестированы.
Меня больше всего убивает нестабильность процесса. Сейчас зависает примерно в 30% стартов. Компьютер двухпроцессорный и еще dual core. Может потоки случайным образом то на разные процессоры попадают, то на один. Вот какая уже фантастика в голову лезет! На одном потоке у меня сейчас могут одновременно 4 прибора запроситься(всего 9), а на втором 3. В незавешенном состоянии первый цикл проходит за 4-5 сек, второй меньше 2-х. В завешенном 10-15 и 4-5. Но статистика показывает одно и то же среднее время для write_device.vi.
Helga
user
user
Сообщения: 89
Зарегистрирован: 14 мар 2010, 10:14
Версия LabVIEW: 9
Контактная информация:

Re: reentrant execution

Сообщение Helga »

Crowbar писал(а):Посмотри любую VI в палитре point by point.
Эти функции могут быть опасными?

Я не вижу, чтобы терялась или путалась информация. Каждый прибор показывает свое значение и оно проверяемо по табло на приборе.
Аватара пользователя
mzu2006

Professionalism Tutorials Black
doctor
doctor
Сообщения: 2456
Зарегистрирован: 16 авг 2008, 02:12
Награды: 3
Версия LabVIEW: 7.1 10 11 12
Откуда: St-Petersburg (RU), Phila, Boston, Washington DC
Контактная информация:

Re: Reentrant execution

Сообщение mzu2006 »

Всё что делается с каждым из этих приборов - это одинаковым образом отправляется 1 посылка (возможно разная, для разных приборов) и в ответ ждётся другая (тоже, возможно, разная)? Я почему спрашиваю: возможно можно сильно упростить архитектуру программы.
Ответить
  • Похожие темы
    Ответы
    Просмотры
    Последнее сообщение

Вернуться в «Модели программирования»