Autor Wątek: Niski fps we własnym frameworku DX  (Przeczytany 3793 razy)

Offline Grelo

  • Użytkownik

# Grudzień 30, 2007, 11:02:55
Witam wszystkich ;-)

Chciałem sobie napisać małego frameworka do interfejsu D3DXSPRITE, żeby nie musieć za każdym razem jak piszę prostą gierkę 2D kopiować kilkuset linii kodu i generalnie, żeby kod był bardziej uporządkowany. Napisałem klasę obrazka i napisu, kilka pomocniczych funkcji, żeby nie zaśmiecać funkcji głównej, przystąpiłem do pierwszych testów fps i ku mojemu zdziwieniu fps wyniosło około 60. Pewnie powiecie, że nie jest jeszcze tak źle, ale IMO powinno być więcej szczególnie, że w głównej pętli jest tylko wyczyszczenie ekranu na czarno, aktualizacja danych od klawiatury i myszki oraz policzenie i wyświetlenie fps i dt. Moim zdaniem to troche za mało (co będzie jak będę chciał renderować 100 obiektów?) . Kod głównej pętli zapewne niewiele wam pomozę, ale cóż :     while (msg.message != WM_QUIT)
        {
            if (PeekMessage(&msg, 0, 0, 0, PM_REMOVE))
              {
                 TranslateMessage (&msg);
                 DispatchMessage (&msg);
              }
            else
              {
                 CountFPS();
                 GetInputData();     
                 Begin_Drawing();
                 DrawData();
                 End_Drawing();
                 if(KEY(DIK_ESCAPE))break;
              }
        }

funkcja Count FPS liczy fps i dt tak jak jest to pokazane w artykule Xiona pt. "Pętla czasu rzeczywistego, funkcja GetInputData  aktualizuje dane od myszki i klawiatury, DrawData wyświetla FPS i dt, reszty chyba nie trzeba tłumaczyć.

Macie jakieś pomysły jak to zoptymalizować/poprawić?

Z góry dziękuję za pomoc ;-)
« Ostatnia zmiana: Grudzień 30, 2007, 11:04:52 wysłana przez Grelo »

Offline Mr. Spam

  • Miłośnik przetworów mięsnych

Offline Złośliwiec

  • Użytkownik
    • Dark Cult

# Grudzień 30, 2007, 11:06:47
W takich sytuacjach używa się narzędzia zwanego profilerem :).

//EDIT
Polecam ten:
http://www.freedownloadscenter.com/Programming/C_and_C++_Tools_and_Components/HWProf_Download.html
« Ostatnia zmiana: Grudzień 30, 2007, 11:09:49 wysłana przez Złośliwiec »

Offline Grelo

  • Użytkownik

# Grudzień 30, 2007, 11:10:23
Gogle i wikipedia milczą na temat profilera, więc zapytam : co to jest? jak się tego używa? do czego służy? skąd można to wziąć?

Offline Złośliwiec

  • Użytkownik
    • Dark Cult

# Grudzień 30, 2007, 11:20:32
Angielska Wikipedia bynajmniej nie milczy, a linka już masz powyżej.

Offline Moriturius

  • Użytkownik

# Grudzień 30, 2007, 11:37:09
Napisałem klasę obrazka i napisu, kilka pomocniczych funkcji, żeby nie zaśmiecać funkcji głównej, przystąpiłem do pierwszych testów fps i ku mojemu zdziwieniu fps wyniosło około 60. Pewnie powiecie, że nie jest jeszcze tak źle, ale IMO powinno być więcej szczególnie, że w głównej pętli jest tylko wyczyszczenie ekranu na czarno

Wyłącz synchronizację z ekranem i powinno być więcej ;)

przy tworzeniu urządzenia DX do D3DPRESENT_PARAMETERS dodaj to:
Kod: (cpp) [Zaznacz]
d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE;

Offline krajek

  • Użytkownik

# Grudzień 30, 2007, 11:57:34
@Grelo: Bardzo prosty ale bardzo pożyteczny profiler. Kiedyś Reg go podawał  :) : http://developer.amd.com/cawin.jsp.
Raczej nie będziesz miał problemów obsługą.

Offline Xion

  • Redaktor
    • xion.log

# Grudzień 30, 2007, 12:01:06
Profiler profilerem, a ja tu czuję nosem niewyłączoną synchronizację pionową :) Skorzystaj z rady Morituriusa. Aha, o ile pamiętam, to wspominam o tym w swoim artykule ;P

Offline Reg

  • Administrator
    • Adam Sawicki - Home Page

# Grudzień 30, 2007, 13:38:54
Jest jeszcze taki problem, że profiler tak łatwo prawdy nie powie. Karta graficzna działa asynchronicznie z procesorem CPU i tego co widać w wynikach profilera nie można interpretować tak łatwo jak by się nieraz chciało. Na przykład może wyjść, że najwięcej czasu program spędza na wywołaniu metody Present urządzenia D3D i to wcale nie znaczy, że trzeba jej nie wywoływać :) tylko że ona czeka na dokończenie przez kartę graficzną rysowania tego co zostało wcześniej wysłane. Gra może się ogólnie okazać CPU Bound (wydajność ograniczają obliczenia na procesorze) albo GPU Bound (wydajność ogranicza kupa roboty zlecana do karty graficznej).

Temat można roztrząsać dalej, ale na początek, tak jak napisali przedmówcy, wyłącz pionową synchronizację. Potem ewentualnie poszukaj w swoim kodzie czegoś co zabiera zbyt dużo czasu i wywołuje się co klatkę - jakieś pętle i wszelkie algorytmy o złożoności kwadratowej albo wykładniczej, jakieś wielokrotne alokacje i zwalnianie pamięci, tworzenia jakis zasobów albo wczytywanie jakiś plików itp.

Offline Grelo

  • Użytkownik

# Grudzień 30, 2007, 14:38:05
Już wszystko w porządku - na takim samym teście przy wyłączonej synchronizacji pionowej wyciąga jakieś 800 - 850 fps (512 MB RAM, CPU  Athlon 1.4 GHz). Wielkie dzięki za pomoc ;-D

Offline Grelo

  • Użytkownik

# Grudzień 30, 2007, 18:23:00
Przeprowadziłem amatorskie (nigdy wcześniej czegośtakiego nie robiłem) testy frameworka. Oto wyniki :

1.Test na texturze jpg o wymiarach 65x65, CPU - Athlon 1,5 GHz; 512 MB RAM; GeForce 5200 128 MB; synchronizacja pionowa wyłączona;

   100 obiektów - 120 fps
   200 obiektów - 65 fps
   300 obiektów - 43 fps
   500 obiektów - 26 fps
   1000 obiektów - 13 fps

2.Test na texturze jpg o wymiarach 32x32, CPU - Athlon 1,5 GHz; 512 MB RAM; GeForce 5200 128 MB; synchronizacja pionowa wyłączona;

   100 obiektów - 590 fps
   200 obiektów - 450 fps
   300 obiektów - 360 fps
   500 obiektów - 260 fps
   1000 obiektów - 160 fps

IMO całkiem niezłe i na pewno w zupełności wystarczające dla tworzenia prostych gierek 2D ;-D

Offline Xion

  • Redaktor
    • xion.log

# Grudzień 30, 2007, 19:51:53
Hmm, a myślałem, że karty graficzne już całkiem dobrze radzą sobie z teksturami o wymiarach niebędących potęgami dwójki. Widać niezupełnie :)

Offline k_b

  • Użytkownik
    • Blog

# Grudzień 30, 2007, 20:02:18
Hmm, a myślałem, że karty graficzne już całkiem dobrze radzą sobie z teksturami o wymiarach niebędących potęgami dwójki. Widać niezupełnie :)

To przy okazji, Grelo, jakbyś mógł, zrób jeszcze testy do bitmapy 33x33 - można by to skonfrontować z obecnym 32x32 :)

Offline Kurak

  • Użytkownik

# Grudzień 30, 2007, 20:07:23
Zawsze wydawało mi się, że tekstury "non-power-of-two" obsługują GeForce'y od 6xxx w górę :)
« Ostatnia zmiana: Grudzień 30, 2007, 20:17:22 wysłana przez Kurak »

Offline Krzysiek K.

  • Redaktor
    • DevKK.net

# Grudzień 30, 2007, 20:31:56
Zawsze wydawało mi się, że tekstury "non-power-of-two" obsługują GeForce'y od 6xxx w górę :)
Tekstury "conditional-non-power-of-two" obsługują GeForce'y od 2 w górę. :)

Offline Kurak

  • Użytkownik

# Grudzień 30, 2007, 20:41:37
Zawsze wydawało mi się, że tekstury "non-power-of-two" obsługują GeForce'y od 6xxx w górę :)
Tekstury "conditional-non-power-of-two" obsługują GeForce'y od 2 w górę. :)
Myślałem o teksturach o wymiarach nie będących potęgami 2 bez wymagań typu niekorzystanie z mipmap :)