Panel użytkownika
Nazwa użytkownika:
Hasło:
Nie masz jeszcze konta?

SFML - Problem z wydajnością

Ostatnio zmodyfikowano 2012-01-27 18:34
Autor Wiadomość
Dawidsoni
Temat założony przez niniejszego użytkownika
SFML - Problem z wydajnością
» 2012-01-24 19:06:02
Witam. Postanowiłem, że napiszę klasę, która będzie mi generowała odcienie w różnych kolorach danego obszaru ekranu. (np. w odcieniu szarości). Główna funkcja tej klasy wygląda tak:
C/C++
void odcien::zrob_obraz( unsigned int x1, unsigned int y1, unsigned int szerokosc, unsigned int wysokosc, RenderWindow & Okno_ ) {
    Okno = & Okno_;
    czy_okno = true;
    m = Okno_.Capture();
    Color stary;
    for( int i = y1; i < wysokosc; i++ ) {
        for( int ii = x1; ii < szerokosc; ii++ ) {
            stary = m.GetPixel( ii, i );
            int ile =( stary.r + stary.g + stary.b ) / 3;
            if( ile == 0 )
                 ile = 1;
           
            m.SetPixel( ii, i, Color( ile * w_r, ile * w_g, ile * w_b ) );
        }
    }
    sprajt.SetImage( m );
    sprajt.SetSubRect( IntRect( x1, y1, x1 + szerokosc, y1 + wysokosc ) );
    sprajt.SetPosition( x1, y1 );
}

Jak widać komputer musi wykonać około miliona operacji ustawienia piksela, czyli bardzo dużo. Zbadałem, więc wyniki pomiaru czasu od wykonania tej funkcji, do najbliższego wyświetlenia ekranu:
- najpierw czas wynosił 0.2 sekundy
- potem po 30 min. jeszcze raz włączyłem program i czas wynosił już 0.5 sekundy
- nie wiedziałem, dlaczego taka różnica i powyłączałem wszystkie programy, ale nadal 0.5 sekundy;/

Skąd taka wielka różnica? Jak mogę poprawić ten czas chociaż tak, aby za każdym razem było maksymalnie 0.2 sekundy?
P-49340
DejaVu
» 2012-01-25 00:37:15
1. Prawdopodobnie testujesz aplikację w trybie debug.
2. Wykonywanie operacji per-pixel na obrazie zawsze było jest i będzie czasochłonne.
3. Jeżeli masz rozdzielczość 1024x768x32bit to: 1024*768*4bajty = 3145728 bajtów. Te 3145728 bajtów musisz po pierwsze odczytać, po drugie przetworzyć, po trzecie zapisać. Jeżeli każdy odczyt i zapis wymaga przemnożenia 'indeksów' x*y i operacja na każdym kolorze wymaga dodatkowych operacji to nie masz co się dziwić, że czas wykonywania tej operacji jest długi.
P-49394
hincu
» 2012-01-25 14:59:38
zgaduje ze ta funkcje wykonujesz co kazdy obieg petli wiec
zrob jeden wielki sprite i powiekszaj go o kolejny pixel przez co wykonasz tylko 1 raz funkcje i bedziesz wyswietlal to jako 1 sprite
P-49411
Dawidsoni
Temat założony przez niniejszego użytkownika
» 2012-01-25 15:29:35
@Dejavu:
1. Nie, nie robię w trybie Debug. Kolega ma ode mnie wolniejszego kompa (2 rdzenie 1.8GH) i ma 0.3 sekundy, a ja mam 0.5 sekundy. (4 rdzenie 2.0GH) Jak to możliwe?
2. A da się to zrobić jakoś inaczej niż per-pixel? W call of duty jak masz mało życia to robią co klatkę czarno biały obraz i działa płynnie (ja nie robię co klatkę, ale nie chcę takiego opóźnienia mieć na przyszłość, kiedy tą klasę wykorzystam do innych celów niż teraz)
3. A jest na to jakiś lepszy algorytm?

@hincu:
1. Nie zgadłeś.
2. Operacja ma być wykonana na danym obszarze okna, a nie na Spricie.
P-49414
hincu
» 2012-01-25 15:51:11
no to wykonujesz tak samo tylko sprite ma mniejsza zawartosc : P
P-49415
Dawidsoni
Temat założony przez niniejszego użytkownika
» 2012-01-25 15:59:34
Na szybkości dzięki temu sprajtowi nie zyskam. (i tak muszę wszystkich wykonać tą operację na wszystkich sprajtach na ekranie) Raczej chciałbym się dowiedzieć, co zrobić, aby ten algorytm działał szybciej, albo poznać jakiś inny, szybszy algorytm.
P-49417
hincu
» 2012-01-25 16:04:56
wykonaj ta funkcje tylko raz za kazdym obiegiem petli wykonujesz ja i to wplywa na wydajnosc : P
zrob ja tylko raz a pozniej tylko rysuj tego sprajta
P-49419
Dawidsoni
Temat założony przez niniejszego użytkownika
» 2012-01-25 16:14:48
Napisałem ci już, ze nie zgadłeś z rysowaniem co obieg pętli. Robię dokładnie tak, jak teraz napisałeś, ale ja chcę i tak osiągnąć wynik około 0.2 sekundy.

edit;
Myliłeś się Dejavu. Te ustawienia pikseli trwają bardzo krótko: 0.08 sekundy. (zmierzyłem czas teraz dokładnie). Nie wiem, co bierze pozostałe 0.42 sekundy. Sprawdzę o 20:00 i napiszę, bo teraz muszę iść.

edit:
Dobra, zrobiłem to teraz na szybko i mam winowajcę. Okno.GetCapture() wykonuje się 0.32 sekundy!!!. Jest jakiś inny sposób na ustawienie pikseli bez wywoływania tej funkcji? Mogę w ostateczności ustawiać do każdego sprajta po kolei, ale to będzie czasochłonne, jak bd. miał dużo sprajtów i to nie w tablicy. To piszcie, jak nic nie ma innego w SFML to w ostateczności zreazlizuję to ze Spritem.
P-49420
« 1 » 2
  Strona 1 z 2 Następna strona