GUI для Pixilang 3 в процессе

Pixilang по русски
Post Reply
J3d1
Posts: 175
Joined: Wed Oct 15, 2008 4:49 am
Location: г. Абакан, Хакасия
Contact:

GUI для Pixilang 3 в процессе

Post by J3d1 »

Приветствую! Alex, я начал писать GUI. Сейчас более-менее готов поток обработки переменных событий (идет опрос системных переменных и на основании его задаются и вычисляются переменные программы, для вящего удобства). Переменные и функция потока записана в файле events.pixi. В файле winmanager_v01.pixi запускается сам поток и выводится на графич. экран текущее состояние переменных.
Исходники: http://narod.ru/disk/62482860001.bd349a ... 1.zip.html
Теперь, какие возникают вопросы:
1. На планшете (Android) всё это крутится быстро и выходит по нажатию экр. кнопки BACK без проблем, но на ПК (WinXP, 2 ядра) после выхода в консольке есть 2 сообщения о не отвечающих потоках: Thread 0 is not responding. Forcibly removed (via halt) и Thread 1 is not responding. Forcibly removed (via halt). Вот, не знаю как это победить. Сначала выход делал по EVT_QUIT (файл events.pixi), но поток зависал на Android. Затем, когда заменил EVT_QUIT на EVT_CLOSEREQUEST на планшете все ok, а на ПК вот так.
2. Еще один момент: если на планшете со скоростью работы этого примера все нормально, то на ПК он подтормаживает: попробуйте нажать кнопку мыши, провести по экрану со средней скоростью и отпустить. Текущие координаты мыши меняются какое-то время даже после отпускания, хотя не должны бы уже... Я думал, что это из-за графич. драйвера: положил в папку с pixilang_console.exe библиотечку gx.dll и конфиге рядом с pixilang_console.exe сделал videodriver gapi. Это не помогло - тормозит.
Alex, надеюсь на помощь, если будет время :)
J3d1
Posts: 175
Joined: Wed Oct 15, 2008 4:49 am
Location: г. Абакан, Хакасия
Contact:

Re: GUI для Pixilang 3 в процессе

Post by J3d1 »

"Thread ... is not responding" поборол выходом из бесконечного цикла в функции потока - добавил в функцию, в начале это:

Code: Select all

if EVT[EVT_TYPE] == EVT_QUIT {ev_exit = 1}
а в конце это:

Code: Select all

if ev_exit ==0 {go ev_start}
ret
А с производительностью на ПК пока не справился. Этот пример наглядно показывает, что с производительностью такого решения под WinXP не хорошо:

Code: Select all

include "events.pixi"
wm_exit = 1
t1 = thread_create(ev_main, 0)
loop1:
if ev_exit == 1 {wm_exit = thread_destroy(t1, 3000)}
if wm_exit == 0 {fputs("Thread destroyed\n"); halt}
if ev_mouseDown == 1
  {
    x = ev_mouse1_x
    y = ev_mouse1_y
    fbox(x, y, 2, 2, YELLOW)
  }
frame ()
goto loop1
J3d1
Posts: 175
Joined: Wed Oct 15, 2008 4:49 am
Location: г. Абакан, Хакасия
Contact:

Re: GUI для Pixilang 3 в процессе

Post by J3d1 »

наверное, это из-за совместного доступа к ресурсам (переменным группы ev_...)
User avatar
NightRadio
Site Admin
Posts: 3944
Joined: Fri Jan 23, 2004 12:28 am
Location: Ekaterinburg. Russia
Contact:

Re: GUI для Pixilang 3 в процессе

Post by NightRadio »

По поводу потоков - вроде в нужном направлении мыслишь ) Событие EVT_QUIT можно получить только в одном потоке. Все остальные потоки будут висеть себе дальше, если их не остановить вручную. То есть, любой поток, по идее должен представлять собой подобие такого цикла: while( global_exit_request == 0 ) { какие-то действия; небольшая пауза, если нужна; }

А по поводу событий, я немножко не понял ) Во-первых, у меня в Linux все работает нормально. Во-вторых, если речь про ПК, то при чем тут gx.dll и GAPI? :) Имеется в виду КПК?
J3d1
Posts: 175
Joined: Wed Oct 15, 2008 4:49 am
Location: г. Абакан, Хакасия
Contact:

Re: GUI для Pixilang 3 в процессе

Post by J3d1 »

С выходом понятно, спасибо. По поводу производительности: да, речь идет именно о ПК с WinXP - очень медленно работает и загружено только одно ядро из 2-х, зато на 100% (аналоничный пример paint.pixi без потоков - просто летает и проц не грузит почти). Дома на Win7 загружаются равномерно все 4 ядра в среднем на 80%. Кажется, это все-же многовато =). Может быть так происходит из-за совместного использования потоками одних и тех-же данных (переменных)? Я не использовал мьютексы - не умею :unknown:
User avatar
NightRadio
Site Admin
Posts: 3944
Joined: Fri Jan 23, 2004 12:28 am
Location: Ekaterinburg. Russia
Contact:

Re: GUI для Pixilang 3 в процессе

Post by NightRadio »

Так. Если речь о ПК, то gx.dll и gapi - это из другой темы ) Это для Windows Mobile.

По поводу нагрузки на проц. Сам раньше с этим сталкивался ) Попробую объяснить.
Чтобы код не грузил проц на 100%, нужно чтобы в этом коде были паузы (моменты ожидания), в которых проц отдыхает :)
В примере paint.pixi место отдыха - это функция frame(). Например, frame( 100 ) делает следующее: выводит кадр на экран и затем ждет 100 миллисекунд. Если длина паузы не указана - frame() - то маленькая пауза все равно будет, так как в движке SunDog задан максимальный FPS (на ПК он равен 60 кадрам в секунду).
Соответственно, точки, где проц может немного поспать - это frame() или sleep().
Если таких точек нет, и при этом имеется какой-то цикл, то вероятнее всего это приведет к 100% загрузке.
Могу предположить, что именно это и произошло в одном из потоков. Как решить проблему? Например, вставив где-нибудь в цикле потока sleep( 20 ).
J3d1
Posts: 175
Joined: Wed Oct 15, 2008 4:49 am
Location: г. Абакан, Хакасия
Contact:

Re: GUI для Pixilang 3 в процессе

Post by J3d1 »

sleep(20) помог снизить нагрузку на процы процентов на 30-40%, немного упала производительность. Попробую оптимизировать работу с событиями и уберу из нее "плюшки", прикрученные "навырост".
User avatar
NightRadio
Site Admin
Posts: 3944
Joined: Fri Jan 23, 2004 12:28 am
Location: Ekaterinburg. Russia
Contact:

Re: GUI для Pixilang 3 в процессе

Post by NightRadio »

Поставь sleep(50). Если все еще будет нагрузка на проц в холостом режиме, значит, что-то еще. Может, постоянно что-то рисуется?
J3d1
Posts: 175
Joined: Wed Oct 15, 2008 4:49 am
Location: г. Абакан, Хакасия
Contact:

Re: GUI для Pixilang 3 в процессе

Post by J3d1 »

Итак имеем 2 потока: в нулевом отрисовывается графика при помощи frame(); в первом читаются системные события и преобразуются к удобному виду. Путем вставки различных значений в frame(n) нулевого потока и в sleep (m) основного цикла первого потока выяснилось:
1. За 0 поток у меня отвечает 0 и 3 ядро, за 1 поток 1 и 2 ядра, причем это разделение очень заметно;
2. Нагрузка на процессор от сугубо вычислительного первого потока раза в 3-4 меньше, чем от графики;
Итак, выводы: необходимо сначала очень жестко оптимизировать и вычисления и порядок отрисовки и обновления картинки, затем вставлять sleep'ы и аргументы в frame снижая нагрузку на процессор. В идеале не плохо бы было, наверное, чтобы программа сама оценивала производительность и в особо критичных местах "поддавала жару" уменьшая аргументы в sleep и frame. И наоборот, при малоактивной работе давала бы процессору "выспаться" :)
User avatar
NightRadio
Site Admin
Posts: 3944
Joined: Fri Jan 23, 2004 12:28 am
Location: Ekaterinburg. Russia
Contact:

Re: GUI для Pixilang 3 в процессе

Post by NightRadio »

По поводу первого пункта. Мне кажется, это просто фишка WinXP. Каким образом распихать твои потоки по ядрам - решает операционка. В Linux, возможно, все будет иначе.

Далее. Графический поток сильно грузит проц. Но почему? Чем он отличается от потока в примере paint.pixi ? Или от других примеров? Мне не совсем понятно.
Как одно из предположений. Насколько часто перерисовывается интерфейс? По особым событиям, или постоянно? Я имею в виду не команду frame(), а то, что ей предшествует - всякие там графические функции.
J3d1
Posts: 175
Joined: Wed Oct 15, 2008 4:49 am
Location: г. Абакан, Хакасия
Contact:

Re: GUI для Pixilang 3 в процессе

Post by J3d1 »

Еще раз перепроверил - моя прожка в третьем листинге во второ посте этой темы. Отличие от paint.pixi - рисование напрямую в контейнер, а у меня fbox'ом и в паинте нет потока для опроса евентов. Различие по загрузке ядер не великое. Я просто, выделив опрос евентов в отдельный поток, ожидал какого-то драматического прироста производительности на многоядерных системах... Но из-за изначально малых затрат ресурсов на это + мои дополнительные вычисления при опросе евентов прироста в частоте отрисовки точек не получилось, а нагрузка на проц подросла немного. С этим помогли sleep(n) и frame(m). В общем мне нужно побольше писать и лучше оптимизировать, тогда с опытом и получаться должно лучше :) Спасибо за разьяснения. Alex, а для обновления экрана в Windows версии используется DirectX?
Last edited by J3d1 on Tue Oct 16, 2012 1:53 pm, edited 1 time in total.
User avatar
NightRadio
Site Admin
Posts: 3944
Joined: Fri Jan 23, 2004 12:28 am
Location: Ekaterinburg. Russia
Contact:

Re: GUI для Pixilang 3 в процессе

Post by NightRadio »

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

В своем GUI движке я выкручиваюсь вот как. Если пользователь ничего не делает, то поток отрисовки просто крутится в холостую c паузами. Даже frame() не вызывается. То есть нагрузка на проц почти нулевая. А как только приходит ивент и, скажем, нужно перерисовать окошко, я ствавлю какой-то глобальный флажок REDRAW_ALL = 1 и в нулевом потоке происходит перерисовка всего интерфейса, а затем опять цикл ожидания с паузами.

В текущей версии вся графика Pixilang идет через OpenGL. В том числе и перерисовка экрана. И это во всех версиях, за исключением Windows Mobile.
J3d1
Posts: 175
Joined: Wed Oct 15, 2008 4:49 am
Location: г. Абакан, Хакасия
Contact:

Re: GUI для Pixilang 3 в процессе

Post by J3d1 »

Попытался применить такой подход к опросу событий и обнаружил интересную штуку. При непрерывном опросе такой программкой:

Code: Select all

while (1)
{
	while get_event()
	{fputs("1")}
	sleep (100)
	fputs("0")
}
при простое (ничего не трогаем) периодически проскакивают единички - выдается ивент. Хуже, что при непрерывном движении мышкой вместо непрерывных единичек (что, вроде-бы, логично) периодически проскакивают нули.
Я поставил sleep (100) в своём потоке опроса событий в таком месте, чтобы, когда ничего не нажимаем, цикл крутится вокруг этого sleep. Но дело в том, что когда непрерывно ведешь мышей, то часто проскакивают нулевые ивенты и попадаю на эти самые sleep(100) и вот... :unknown:
User avatar
NightRadio
Site Admin
Posts: 3944
Joined: Fri Jan 23, 2004 12:28 am
Location: Ekaterinburg. Russia
Contact:

Re: GUI для Pixilang 3 в процессе

Post by NightRadio »

Думаю, что при простое проскакивают события - это нормально. Надо глянуть, что за код события.
И то, что при непрерывном ведении мышкой проскакивают нули - это тоже норма :) Ведь события от мышки сыплются далеко не непрерывно. Между ними приличные паузы. Иногда этого достаточно, чтобы цикл while get_event() выскочил.
Post Reply