kategoria: Blitz
[#1] Vertical Wait, spory spadek wydajności, porównanie na wykresie, czy da się to obejść?
Hej,
Testuje sobie wydajność robiąc starfield w BlitzBasic2.1 na A1200 (na razie emulator) z góry na dół, porównuje rożne metody żeby przyśpieszyć ( np. cls w asemblerze zamiast zwykły cls) i spróbować wyświetlić jak największą ilość gwiazdek w sensownym FPS..

w momencie kiedy zacząłem używać timera żeby mieć dokładne pomiary, okazało się że to guzik daje, bo wydajność wraz ze wzrostem ilosci gwiazdek spada skokowo od 50 fps przez 25, 16, 9.. dopiero po chwili się kapnąłem ze to przez komendę VWait. Więc szlifowanie kodu czy nawet proba testu Blit z Block nic nie zmianiała (tylko zmiana na asemblerowy CLS bardzo duzo wniosła)

Zrobiłem kilka testów i porównań co najwiecej zajmuje, oczywiście VWait.. no ale jak go nie dam to mi ekran mryga.. ale to straszna strata fps-ów.. czy można to jakoś obejść, cos slyszalem ze trzeba się zsynchronizować z vertical beam i rysować jakoś po nim czy przed nim.. brzmi dość ciezko..

poniżej moje porównania: link




Ostatnia aktualizacja: 11.02.2020 19:36:59 przez mateusz_s
[#2] Re: Vertical Wait, spory spadek wydajności, porównanie na wykresie, czy da się to obejść?

@mateusz_s, post #1

Chyba trzeba z triple bufferingiem spróbować..
[wyróżniony] [#3] Re: Vertical Wait, spory spadek wydajności, porównanie na wykresie, czy da się to obejść?

@mateusz_s, post #2

Ogolnie takie rzeczy panie, to sie robi tylko w asemblerze.
Blitz Basic jest moze szybszy niz AMOS ale to zadna zaleta porownywac sie z mega zolwiem. Te jezyki sa za wolne.
[#4] Re: Vertical Wait, spory spadek wydajności, porównanie na wykresie, czy da się to obejść?

@selur, post #3

No niby tak, ale nie znam na razie, dopiero ledwo zachaczylem i zrozumiałem jak zadziałało wyczyszczenie bitmapy z asm, minus taki że zamiast na grze trzeba się skupić na samym języku, nie wiem tablice, struktury.. mało też źródeł.. ale powoli się zachęcam do asm, też by mi się ta wiedza przydała przy ogólnym programowaniu na pc
[wyróżniony] [#5] Re: Vertical Wait, spory spadek wydajności, porównanie na wykresie, czy da się to obejść?

@mateusz_s, post #4

VWait służy właśnie do synchronizacji z tzw. wygaszaniem pionowym (Vertical Blank), kiedy wiązka obrazu jest w pozycji 0 i przez moment nic nie wyświetla. To dzięki niemu Twoja animacja może być wyświetlana w stabilnym 50/60FPS.

Bez VWait ekran miga, ponieważ wiązka tworząca obraz wyświetla dane graficzne kiedy ekran jest wyczyszczony i zanim pojawią się elementy graficzne.

Jeżeli dajesz tak dużo elementów na ekranie, to nie musisz czyścić ekranu, bo te elementy nadpiszą dane graficzne na ekranie. Amigowa pamięć jest tak skonstruowana, że modyfikujesz sekwencję pikseli, najczęściej 8, 16 lub 32.

Jeżeli chcesz to solidnie zoptymalizować, polecam zainstalować przerwanie Coppera, który te elementy by rysował w synchronizacji z dokładnym położeniem wiązki obrazu. Jest to bardzo szybka metoda, ale procedura przerwania musi być rozsądnie krótka, np. rysować jedną linię obrazu. Wtedy nawet 68020 zdąży z narysowaniem wszystkiego.

Najlepiej skorzystać również z przeznaczonego do tego koprocesora - Blittera.

Polecam również optymalizować i skompresować animację w ten sposób, by modyfikować tylko te bitplany, które potrzeba oraz sortować paletę kolorów. Taka optymalizacja oraz kompresja daje dobre rezultaty.

Wszystko też zależy od rodzaju animacji, jaką chcesz wprowadzić. Do poruszających się gwiazd na wielu warstwach, może warto wykorzystać tryb dual-playfield?

W każdej bitplanie rysujesz wówczas odpowiedni zestaw gwiazd (np. ciemne, dalekie i wolno poruszające się gwiazdy w jednej bitplanie, zaś jasne, bliskie i szybko poruszające się - w drugiej bitplanie itd.). A w drugim Playfieldzie - jakieś tło z mgławicami itp.

Do rysowania takich elementów możesz też skorzystać z duszków (również do statku kosmicznego). W Amidze masz dużo sprzętowych możliwości. Nie trzeba stosować siłowych rozwiązań.
[wyróżniony] [#6] Re: Vertical Wait, spory spadek wydajności, porównanie na wykresie, czy da się to obejść?

@mateusz_s, post #4

Taki trochę offtop.

przy ogólnym programowaniu na pc


A w czym piszesz na pececie? Bo jak w czymś C-podobnym, to wiesz że możesz mniej się skupiać na języku używając czegoś Tobie znanego, np. C lub C++? Co prawda nie masz wtedy całego wachlarza funkcji blitzowych i "skazany" jesteś na funkcje systemowe albo niesystemowe tłuczenie po rejestrach chipów, ale będziesz w stanie zrobić prawie całą magię "asemblerowców", oczywiście z pewnym narzutem wydajności. Jak wiadomo kompilatory nie są doskonałe i oczywiście ręcznie pisany kod potrafi być szybszy, o ile masz zacięcie do asemblerowego sudoku. ;)
[wyróżniony] [#7] Re: Vertical Wait, spory spadek wydajności, porównanie na wykresie, czy da się to obejść?

@mateusz_s, post #1

To samo przecież się dzieje na PC, bez synchronizacji pionowej grafika potrafi być generowana szybciej, niż jest kreślona na monitorze, przez co powstaje tkzw. "tearing", a po jej włączeniu następują właśnie takie spadki jak odświeżanie monitora/2/3/4/5...

Jeśli chcesz rysować w najszybszym możliwym tempie, nie wciskając się z nowymi danymi na aktualnie kreślony obraz, to musisz użyć dwóch buforów. Do jednego z nich kreślisz obraz cały czas, tak szybko jak to możliwe, w przerwaniu ustawionym na wygaszanie pionowe zmieniasz adres bufora (od razu można zmienić nr bufora przy okazji), który ma być wyświetlony na ekranie, na ten, w którym akurat rysujesz, a sam po nakreśleniu klatki, przenosisz się do rysowania w buforze drugim. Ja bym tak zrobił, teoretycznie, jeśli rysujesz szybciej niż wiązka na ekranie, to nie powinno być glitch'y, w przeciwnym razie należałoby zastosować potrójny bufor, by do wyświetlania został podany adres bufora, który został już w pełni narysowany.
[#8] Re: Vertical Wait, spory spadek wydajności, porównanie na wykresie, czy da się to obejść?

@teh_KaiN, post #6

na PC robie zwykle bezpośrednio w WinApi w C++, ostatnio pracowałem tez nad pluginem do 3ds maxa tez w C++ pod winapi, z tym ze 3ds max narzuca swoje SDK..

teraz bawiąc się w Blitzu, potrzebowałem szybkiej funkcji czyszczącej bitmapę, jest tam załączony przykład, natomiast forumowy kolega @Don_Adan podpowiedział jak można ją jeszcze mocniej zoptymalizować, chwile mi zajęło zanim zrozumiałem, ale jak już zrozumiałem to byłem pod wrażeniem ze takie cuda można w asemblerze robić..

w powyższych przypadkach na PC tez często muszę coś zrobić jak najszybciej, i widze ze znajac asemblera moglbym robic znaczenie lepsze rzeczy, ale tu mowa raczej o "wstawkach" kodu niz pisaniu od zera..
[#9] Re: Vertical Wait, spory spadek wydajności, porównanie na wykresie, czy da się to obejść?

@sanjyuubi, post #7

Ok, udało mi się zrobić ten triple buffer, pomógł mi ten wątek, bo sam nie do końca jarzyłem o co chodzi.. http://eab.abime.net/showthread.php?t=98866

efekty są niezłe, widać spore przyspieszenie przy większej liczbie gwiazdek, VWait mi teraz nie blokuje wiec jakieś drobniejsze optymalizacje maja teraz więcej sensu..

kod ze zmianą:

; ustawienie przerwania VBLANK, ktore wybiera bitmape do pokazania

SetInt 5

  If frames_ready > 0
    If bmap = 0 Then frametodisplay = 2
    If bmap = 1 Then frametodisplay = 0
    If bmap = 2 Then frametodisplay = 1

    DisplayBitMap 0, frametodisplay
    frames_ready - 1
  EndIf

End SetInt

; petla
  For T = 0 To 300
    mycls{ btm_adr(bmap +1)\a08 }
    mycls{ btm_adr(bmap +1)\a12 }
    mycls{ btm_adr(bmap +1)\a16 }
    mycls{ btm_adr(bmap +1)\a20 }
    mycls{ btm_adr(bmap +1)\a24 }
    mycls{ btm_adr(bmap +1)\a28 }

   For i = 1 To #STARS
     stars(i)\y + stars(i)\ys

     If stars(i)\y > 252
        If stars_random_x_counter >= #STARS_RANDOM_X
        stars_random_x_counter = 1
      Else
        stars_random_x_counter + 1
      EndIf

      stars(i)\y = 0
      stars(i)\x = stars_random_x(stars_random_x_counter)
    EndIf

    Blit stars(i)\shp, stars(i)\x, stars(i)\y
  Next

  bmap + 1
  If bmap = 3 Then bmap = 0
   frames_ready + 1

   If frames_ready > 1
   Repeat
   Until frames_ready < 2
 EndIf

 Use BitMap bmap
Next


wykres: link



Ostatnia aktualizacja: 12.02.2020 00:42:54 przez mateusz_s
[wyróżniony] [#10] Re: Vertical Wait, spory spadek wydajności, porównanie na wykresie, czy da się to obejść?

@mateusz_s, post #9

Ja akurat tego dobrze nie rozumiem, czy w tym przykładzie i tak nie musisz czekać, gdy zepełnią się wszystkie trzy bufory?

Ja myślałem o tym, by ciągle rysować do buforów i gdy jest wyświetlany bufor 1, to kreślić ramki na przemian w buforze 2 i 3, gdy ramka nr1 skończy się kreślić na ekranie, to zmieniasz bufor na taki, który jest już narysowany, czyli jeśli akurat generujesz bufor nr 3, to zmieniasz wyświetlanie zawartości bufora nr 1 na bufor 2 i dalej kreślisz tak szybko jak to tylko możliwe, do buforów nr 1 i 3, wg mnie, powinieneś osiągnąć prędkość bliską samym obliczeniom, bo na nic nie czekasz prócz wykonania kilku instrukcji warunkowych.

Ostatnia aktualizacja: 12.02.2020 01:51:01 przez sanjyuubi
[#11] Re: Vertical Wait, spory spadek wydajności, porównanie na wykresie, czy da się to obejść?

@sanjyuubi, post #10

Do końca jeszcze nie rozkminialem tego kodu, wcześniej miałem "zwykły" double buffer, ale nie używałem przerwania, .. ten jest chyba dość dobry, bo nie dusi fpsow ale ma limit do max 50fps, ale to dobrze bo w innym wypadku też byś musiał mieć jakiś swój timer.. spróbuję potem zaimplementować to o czym powiedziałeś.. ale chyba wyjdzie to samo co tutaj,
[wyróżniony] [#12] Re: Vertical Wait, spory spadek wydajności, porównanie na wykresie, czy da się to obejść?

@mateusz_s, post #9

Repeat
   Until frames_ready < 2

Ten bloczek kodu to tzw. Busy Wait. Unikaj go w swoim kodzie, ponieważ blokuje on procesor, który wykonuje niepotrzebnie instrukcje czekając na zmianę stanu zmiennej w przerwaniu.

Najlepszym rozwiązaniem jest zastosować sygnały lub wiadomości.

W przerwaniu wysyłasz sygnał:

Signal(task, signal);

Zaś w pętli głównej czekasz na niego:

Wait(1L << signal);

Możesz też czekać równocześnie na wiele sygnałów - np. obsługę myszy, joysticka, klawiatury, liczniki czasu itd. i obsługiwać je. Przyda Ci się, jak będziesz rozbudowywać swój program. Sam z tego korzystam, bo narzut jest zerowy.

Ostatnia aktualizacja: 12.02.2020 10:52:20 przez Hexmage960
[#13] Re: Vertical Wait, spory spadek wydajności, porównanie na wykresie, czy da się to obejść?

@Hexmage960, post #12

dzięki, oblukam to, w blitzu bezpośrednio nie ma chyba takiej funkcji ale zdaje się ze można z biblioteki exec uzyc, jeszcze nie probowalem..
Na stronie www.PPA.pl, podobnie jak na wielu innych stronach internetowych, wykorzystywane są tzw. cookies (ciasteczka). Służą ona m.in. do tego, aby zalogować się na swoje konto, czy brać udział w ankietach. Ze względu na nowe regulacje prawne jesteśmy zobowiązani do poinformowania Cię o tym w wyraźniejszy niż dotychczas sposób. Dalsze korzystanie z naszej strony bez zmiany ustawień przeglądarki internetowej będzie oznaczać, że zgadzasz się na ich wykorzystywanie.
OK, rozumiem