PDA

Просмотр полной версии : Загрузка ЦП 100%



aaaSashaMGGU
15.02.2024, 16:04
Добрый
СПК107. Закончил писать проект, загрузил в панель
В секции Debug включил Enable Debug
И вижу Processor usage 100%

В основном коде программы стоит цикл 10мс (такой и нужен), но "Конфигурация задач" говорит, что время обсчёта ~5мс, т.е., всё в норме с двухкратным запасом
Внешне, по программе и выходам, всё работает как будто корректно, все выходы вовремя выдаются
Программа не сказать, что прям сложная, да и не сказать, что прям большая...

Как будто, проблема в визуализациях. Переход между экранами прям ощутимо долгий, любое нажатие прям чувствуется, что долгое
Но я пробовал циклы визуализаций (Web и Таргет) поднимать аж до 1000мс (больше уже совесть не позволяет), но загрузка всё равно 100%
Убирал сглаживание (думал, оно), но тоже ничего не изменилось

Или на эту загрузку вообще не нужно обращать внимание?
Спасибо

Cs-Cs
15.02.2024, 19:45
Ещё как обращать! Это очень плохо!
А заодно посмотреть (и нам ради интереса сказать):
1. Есть ли много работы со строками?
2. Есть ли строковые переменные для визуализации, которые в коде обновляются на лету каждый цикл программы (образно, strVal := Concat(REAL_TO_STRING(rValue), ' bar')?
3. Есть ли загруженные картинки в визуализации очень большого размера?

aaaSashaMGGU
15.02.2024, 20:15
Ещё как обращать! Это очень плохо!
А заодно посмотреть (и нам ради интереса сказать):
1. Есть ли много работы со строками?
2. Есть ли строковые переменные для визуализации, которые в коде обновляются на лету каждый цикл программы (образно, strVal := Concat(REAL_TO_STRING(rValue), ' bar')?
3. Есть ли загруженные картинки в визуализации очень большого размера?

1) Да
2) Да
3) Что считать "большими картинками"? Их у меня всего 3 JPG, но они (на мой взгляд) небольшие (~50кб), но вся эта мысль в голову мне приходила - и я их пробовал удалить. Оставались те же 100% загрузки

К слову таск визуализации из выделенных 250мс работает ~50мс. Так что, так я думал, это тоже не оно.
Или, всё-таки, оно?


Небольшой update по п.2
Переменные у меня "постоянно" не обновляются в том смысле, что их значение не меняется
Но прямые присвоения одного и того же я каждый цикл всё же делаю по типу
IF PrConc = true then
Sost = "Доехал до концевого"
ELSE
Sost = "Ещё не доехал до концевого"
END_IF

Сам PrConc при этом меняется редко
Ну а Sost - уже на мнемосхему

aaaSashaMGGU
15.02.2024, 20:26
На ПЛК200 я параллельно в другом проекте делаю как-то так же.
Зачастую просто копирую кусками, так что, можно сказать, что всё примерно одинаковое
Но там только Web-визуализация - и загрузка ну ~30%-40% (вот прям при запущенной web-визуализации)
А тут таргет - и такая беда

Cs-Cs
15.02.2024, 22:03
С чем сталкивался я:
1. Обычные ConCat и даже OSU грузили процессор жёстко. Я перешёл на работу по буферам и указателям через StringUtils, и загрузка процессора сразу упала на 20-30% по сравнению с той, что было.
2. Если переменная строки привязана к визуализации и её обновлять из кода, присваивая значение, то почему-то визуализация обновляется даже если переменная имеет то же значение. Я делал таймер BLINK, по нему дёргал R_TRIG и по R_TRIG обновлял раз в секунду. Тоже снизил на 10-20% загрузку проца.
Это было справедливо для CDS 3.5. SP14. Вдруг поправили уже.

Кстати, твой код с IFами можно круто через SEL записать так:
Sost := SEL(PrConc, "Ещё не доехал до концевого", "Доехал до концевого");
Это тот же IF, только красиво завёрнутый в одну строчку. Становится меньше строк и нагляднее код.

Попробуй всё же сделать, как Женя Кислов советует: поотключай лишние куски кода или визуализации и посмотри, что будет.

aaaSashaMGGU
16.02.2024, 09:24
Добрый день ещё раз
В общем, прошла ночь, утром на трезвую голову с 1 раза попал, куда надо. "Проблема" была здесь:

(*Собираем массив в кучу*)
FOR i := 0 TO 49 DO

Recept[0, i] := INT_TO_WSTRING(i + 1); (*Номер*)
Recept[1, i] := ReceptName[i]; (*Имя рецепта*)
Recept[2, i] := WCONCAT(STRING_TO_WSTRING(OSCAT_BASIC.REAL_TO_STRF (ReceptTimeKlapan1[i], 2, '.')), "сек"); (*Время первого клапана*)
Recept[3, i] := WCONCAT(STRING_TO_WSTRING(OSCAT_BASIC.REAL_TO_STRF (ReceptTimeKlapan2[i], 2, '.')), "сек"); (*Время второго клапана*)
Recept[4, i] := WCONCAT(STRING_TO_WSTRING(OSCAT_BASIC.REAL_TO_STRF (ReceptTimeShiberDozator[i], 2, '.')), "сек"); (*Время шибера дозатора*)
Recept[5, i] := WCONCAT(STRING_TO_WSTRING(OSCAT_BASIC.REAL_TO_STRF (ReceptTimeUkupor[i], 2, '.')), "сек"); (*Время укупоривания*)
Recept[6, i] := WCONCAT(STRING_TO_WSTRING(OSCAT_BASIC.REAL_TO_STRF (ReceptTimeShiber2Ukupor[i], 2, '.')), "сек"); (*Время шибера №2 укупора*)
END_FOR

И вот этот вот код - в 10мс цикле, сам Recept - на мнемосхему в комбинированное окно
Так как весь этот код нужен просто для красивого вывода на мнемосхему - убрал его в отдельный таск на 250мс - загрузка ЦП упала со 100% до 30%
Основной цикл теперь работает не 5мс из 10мс, а 1мс из 10мс
Таск вот этого кода - 4мс из 250мс

Слово "Проблема" взял в кавычки, т.к., несмотря на то, что код выглядит сложным - значения переменных там не меняются вообще почти никогда. Только когда человек вручную меняет значения
Всё равно всем спасибо за помощь!

Cs-Cs
16.02.2024, 09:45
ВОТ!! Это особенность работы со строками в CodeSys (Женя Кислов ждёт моей статьи, но я напишу её не скоро).
Этот код надо жёстко оптимизировать:
1. Уйти от WCONCAT вообще напрочь. Она ОЧЕНЬ тормозная!
Надо использовать библиотеку StringUtils (НЕ путай с OwenStringUtils). Она работает с указателями, и более быстрая. Переводи весь код на неё.
Я написал себе обёртки функциий такого вида:
73608
и пользуюсь ими.
2. Обновлять такие значения по таймеру, как я тебе писал. Реально, освобождает аж 10-20% времени процессора!