Autor Wątek:  Exe - konwersja na C++  (Przeczytany 698626 razy)

0 użytkowników i 1 Gość przegląda ten wątek.

Offline firleju

  • Zasłużony dla Symulatora
  • Wiadomości: 1588
  • bawię się (w) exe...
    • Zobacz profil
  • Otrzymane polubienia: 120
Odp: Odp: Exe - konwersja na C++
« Odpowiedź #60 dnia: 11 Listopada 2016, 09:55:55 »
Walczę z hamulcami narazie. Loga nie będę ruszał. Cały czas jest tak jak był - w zasadzie po każdym zdarzeniu następuje zapisanie od pliku.

  Dodano: 14 Listopada 2016, 08:48:13
Do d... Zafiksowałem się na jednym rozwiązaniu co mi utrudniło robotę. Sprawdziłem alternatywę i wyszło, że trafienie w std::map przy 12 pozycjach wynosi O(1,07) zamiast O(1) przy zwykłej tablicy. Natomiast przy 8 pozycjach (dla kranu FV4aM) wynosi O(0,9) ;) A użycie std::map rozwiązuje większość problemów i jest "kompatybilne" z ujemnymi indeksacjami tablic w Pascalu.

  Dodano: 14 Listopada 2016, 23:33:09
Coś jest ostro zwalone. Hamulec pomocniczy sam się zaciąga i za ChRL nie chce ustawić się w innej pozycji. Główny w ogóle nie reaguje. A Hasler pokazuje jakąś losową wartość około 18 i lekko drga. Czyli cały mover jest do solidnego przejrzenia. Najpierw to wszystko uruchomić, potem dopiero zabawa w optymalizację.
« Ostatnia zmiana: 14 Listopada 2016, 23:33:09 wysłana przez firleju »
Skrypty do Blendera dostępne tutaj
W miarę aktualne wiki EXE wiki.eu07.es

Offline tmj

  • Deweloper
  • Wiadomości: 3808
    • Zobacz profil
  • Otrzymane polubienia: 2351
Odp: Odp: Exe - konwersja na C++
« Odpowiedź #61 dnia: 15 Listopada 2016, 07:25:39 »
Do d... Zafiksowałem się na jednym rozwiązaniu co mi utrudniło robotę. Sprawdziłem alternatywę i wyszło, że trafienie w std::map przy 12 pozycjach wynosi O(1,07) zamiast O(1) przy zwykłej tablicy. Natomiast przy 8 pozycjach (dla kranu FV4aM) wynosi O(0,9) ;) A użycie std::map rozwiązuje większość problemów i jest "kompatybilne" z ujemnymi indeksacjami tablic w Pascalu.
std::map jest implementowana z uzyciem red-black tree, stad jest wolniejsza. Jesli potrzebujesz O(1) uzyj std::unordered_map (http://en.cppreference.com/w/cpp/container/unordered_map)  Interface jest o ile dobrze pamietam taki sam, wiec to tylko zmiana kontenera, a unordered_map jest oparta o hash, wiec z reguly da ci linearny czas dostepu.

(poza tym najpierw robi sie implementacje, a optymalizacje to ewentualnie i po testach ktore wykaza ze jest tu w ogole problem do usuniecia ;)
« Ostatnia zmiana: 15 Listopada 2016, 07:29:18 wysłana przez tmj »

Offline firleju

  • Zasłużony dla Symulatora
  • Wiadomości: 1588
  • bawię się (w) exe...
    • Zobacz profil
  • Otrzymane polubienia: 120
Odp: Odp: Exe - konwersja na C++
« Odpowiedź #62 dnia: 16 Listopada 2016, 07:52:22 »
Panie, Panie. Kompiluje na Borlandzie 5.02 (rok. prod. 2000). Nie na VS2013. Żadnego unordered_map nie ma.

  Dodano: 16 Listopada 2016, 08:02:38
P.S.
W tej chwili nie ma żadnego profilera, na którym można sprawdzić jak się kod zachowuje. Mam nadzieję, że jak się uwolnimy od Borlanda to uda się takie narzędzie wprowadzić i zobaczymy co zajmuje nam dużo czasu, a co nie jest problemem.
« Ostatnia zmiana: 16 Listopada 2016, 08:02:38 wysłana przez firleju »
Skrypty do Blendera dostępne tutaj
W miarę aktualne wiki EXE wiki.eu07.es

Offline tmj

  • Deweloper
  • Wiadomości: 3808
    • Zobacz profil
  • Otrzymane polubienia: 2351
Odp: Odp: Exe - konwersja na C++
« Odpowiedź #63 dnia: 16 Listopada 2016, 16:38:43 »
A to ja przepraszam :)  Myslalem, ze wszystkie zaleglosci z Borlanda juz sa wyprute.

Offline firleju

  • Zasłużony dla Symulatora
  • Wiadomości: 1588
  • bawię się (w) exe...
    • Zobacz profil
  • Otrzymane polubienia: 120
Odp: Odp: Exe - konwersja na C++
« Odpowiedź #64 dnia: 16 Listopada 2016, 21:42:13 »
Sprawdzam co się porobiło z moverem, że nie chce toto działać. Potem zostaje już "tylko" główny parser QueryParserComp. Jak on pójdzie to będzie już z górki.
Skrypty do Blendera dostępne tutaj
W miarę aktualne wiki EXE wiki.eu07.es

Offline tmj

  • Deweloper
  • Wiadomości: 3808
    • Zobacz profil
  • Otrzymane polubienia: 2351
Odp: Odp: Exe - konwersja na C++
« Odpowiedź #65 dnia: 16 Listopada 2016, 22:08:11 »
A nie da sie zastapic Query na cParser, zamiast przepisywac Query? W sumie oba robia to samo, tyle ze jeden sie kompiluje poza Borlandem a drugi nie ;) Z tego co widze w kodzie to Query jest uzywany tylko do wyciagania tokenow jeden po drugim ze stringa, wiec nawet nic dopisywac nie trzeba, co najwyzej pozmieniac odwolania.

troche czytelniej by sie tez zrobilo. np. zamiast
(w geom.cpp)
        tf = Parser->GetNextSymbol().ToDouble();
        TempVerts[i].Point.x = tf;
        tf = Parser->GetNextSymbol().ToDouble();
        TempVerts[i].Point.y = tf;
        tf = Parser->GetNextSymbol().ToDouble();
        TempVerts[i].Point.z = tf;
        tf = Parser->GetNextSymbol().ToDouble();
        TempVerts[i].Normal.x = tf;
        tf = Parser->GetNextSymbol().ToDouble();
        TempVerts[i].Normal.y = tf;
        tf = Parser->GetNextSymbol().ToDouble();
        TempVerts[i].Normal.z = tf;

moglo by wejsc
Parser->getTokens( 6, false );
*Parser
>> TempVerts[i].Point.x
>> TempVerts[i].Point.y
>> TempVerts[i].Point.z
>> TempVerts[i].Normal.x
>> TempVerts[i].Normal.y
>> TempVerts[i].Normal.z;

itp. Latwiej wtedy wylapac literowki i inne pluskwy.
« Ostatnia zmiana: 17 Listopada 2016, 01:40:47 wysłana przez tmj »

Offline firleju

  • Zasłużony dla Symulatora
  • Wiadomości: 1588
  • bawię się (w) exe...
    • Zobacz profil
  • Otrzymane polubienia: 120
Odp: Odp: Exe - konwersja na C++
« Odpowiedź #66 dnia: 17 Listopada 2016, 08:22:19 »
Byłbym bardzo wdzięczny jeśli byś chciał się tym zająć. Ta zmiana powinna być możliwa do zrobienia niezależnie od moich prac nad konwersją. Ogólnie sam cParser jest określony jako mniej wydajny niż Query. Da się to zoptymalizować, gdyż w tej chwili robi alokację stringa z każdym pobraniem znaku. Jeśliby robić tą alokację na każdym słowie myślę, że byłoby zdecydowanie szybciej.
Skrypty do Blendera dostępne tutaj
W miarę aktualne wiki EXE wiki.eu07.es

Offline tmj

  • Deweloper
  • Wiadomości: 3808
    • Zobacz profil
  • Otrzymane polubienia: 2351
Odp: Odp: Exe - konwersja na C++
« Odpowiedź #67 dnia: 17 Listopada 2016, 16:59:36 »
Da się to zoptymalizować, gdyż w tej chwili robi alokację stringa z każdym pobraniem znaku. Jeśliby robić tą alokację na każdym słowie myślę, że byłoby zdecydowanie szybciej.
Hmm? Moze ja zle patrze, ale w zrodlach tego nie widze... alokacja jest robiona raz na slowo:

std::string cParser::readToken(bool ToLower, const char *Break)
{
    std::string token = "";

(...)

    char c;
    do
    {
        while (mStream->peek() != EOF && strchr(Break, c = mStream->get()) == NULL)
        {
            if (ToLower)
                c = tolower(c);
            token += c;
            if (trimComments(token)) // don't glue together words separated with comment
                break;
        }
    } while (token == "" && mStream->peek() != EOF); // double check to deal with trailing spaces
edit: jesli masz na mysli, ze bedzie miala miejsce re-alokacja przy token += c, to wiekszosci mozna uniknac przez dodanie
    std::string token = "";
    token.reserve(16); // should be enough in most cases
a jeszcze lepiej wrzucic token do naglowka jako member, i tylko kasowac zawartosc w readToken().

Ogolnie rzecz biorac akurat tutaj wydajnoscia bym sie specjalnie nie przejmowal -- parser jest uzywany glownie do wczytywania konfiguracji podczas ladowania itp, wiec waskim gardlem i tak bedzie przede wszystkim odczyt z dysku.

Co do zajecia sie, nie mam niestety Borlanda wiec raczej nie jestem w stanie -- poprawki musialbym robic "na sucho" bez mozliwosci sprawdzenia czegokolwiek. Ale z tego co widze, to prowizorycznie wystaczyloby dopisac do cParsera:
std::string GetNextSymbol() {

std::string token;
getToken( token );
return token;
}
I tak z 90% istniejacego kodu lyknie zwykla zamiane "TQueryParserComp" na "cParser" (nie bedzie to najbardziej optymalne, ale bedzie dzialac)
edit 2: a nie, czekaj, nie bedzie, bo chyba nie masz zamiennikow ToDouble() itp dla zwyklego std::string? czyli i tak trzeba bedzie pozmieniac odwolania do konwersji, bleh.

Pozostale 10% to zmiana wywolan typu
    TQueryParserComp *Parser;
    Parser = new TQueryParserComp(NULL);
    Parser->TextToParse = str;
    Parser->First();
na
    cParser *Parser;
    Parser = new cParser( str );
i juz. Jak sie skompiluje i pojdzie, to wtedy mozna sie bawic w zastapienie istniejacych odwolan do GetNextSymbol() na bardziej eleganckie itp.
« Ostatnia zmiana: 17 Listopada 2016, 17:18:53 wysłana przez tmj »

Offline firleju

  • Zasłużony dla Symulatora
  • Wiadomości: 1588
  • bawię się (w) exe...
    • Zobacz profil
  • Otrzymane polubienia: 120
Odp: Odp: Exe - konwersja na C++
« Odpowiedź #68 dnia: 17 Listopada 2016, 20:41:35 »
Tak, chodziło mi właśnie o token += c. To jest kod jaki został podany za przykład na realokację za każdym wywołaniem. Wiesz, niektórzy tutaj napisali własne formaty plików, żeby przyspieszyć ładowanie. Masz różnice między 10min a 5min. Odwołaniami do ToDouble() nie ma co się przejmować. Albo zrobię klasę potomną do std::stringa z samymi funkcjami inline, albo po prostu pozmieniam. W końcu już w tylu miejscach pozmieniałem, że to nie problem jest.
Skrypty do Blendera dostępne tutaj
W miarę aktualne wiki EXE wiki.eu07.es

Offline tmj

  • Deweloper
  • Wiadomości: 3808
    • Zobacz profil
  • Otrzymane polubienia: 2351
Odp: Odp: Exe - konwersja na C++
« Odpowiedź #69 dnia: 18 Listopada 2016, 00:59:31 »
Tak, chodziło mi właśnie o token += c. To jest kod jaki został podany za przykład na realokację za każdym wywołaniem.
Ah, ok. Akurat z tym to roznie bywa (dlatego nie rzucilo mi sie w oczy od razu), bo co prawda w standardzie tego nie ma, ale nowsze implementacje czesto stosuja cos, co nazywaja "Small String Optimisation", taki prywatny maly bufor wbudowany w string, na ktorym operuja najpierw, zeby uniknac alokacji. A przy wiekszych stringach re-alokacja tez jest wiekszymi kawalkami, zamiast co znak. Tak czy owak, z dodanym reserve() nie powinno byc tutaj problemow, nawet przy starszym kompilatorze.

edit: tutaj jest fajny artykul pokazujacy jak wyglada SSO w roznych kompilatorach: http://info.prelert.com/blog/cpp-stdstring-implementations
« Ostatnia zmiana: 18 Listopada 2016, 01:47:12 wysłana przez tmj »

Offline firleju

  • Zasłużony dla Symulatora
  • Wiadomości: 1588
  • bawię się (w) exe...
    • Zobacz profil
  • Otrzymane polubienia: 120
Odp: Odp: Exe - konwersja na C++
« Odpowiedź #70 dnia: 22 Listopada 2016, 09:31:29 »
Z tego co poczytałem to Borland powinien mieć zaimplementowane Copy-on-Write wraz z powiększaniem stringa o troszkę więcej niż alokacja. Więc teoretycznie im dłuższy string tym mniej powinno być do niego alokacji przy kolejnym dodawaniu znaków. Ale nawet patrząc teoretycznie to przy mnożniku 1.5 i średniej liczbie znaków koło 6 to liczba alokacji wynosi: 1 - alokowanie pustego stringa, 2 - pierwszy znak + drugi znak, 3 - 3,4,5 znak, 4 - 6 - 9 znak. To chyba niezbyt wydajne, żeby robić alokację 4-krotnie przy liczbie znaków 6-9? To reserve faktycznie powinno pomóc.
Skrypty do Blendera dostępne tutaj
W miarę aktualne wiki EXE wiki.eu07.es

Offline HTD

  • Wiadomości: 689
  • "Twoja stara mieszka w Boldach" xD
    • Zobacz profil
    • I like trains
  • Otrzymane polubienia: 26
Odp: Odp: Exe - konwersja na C++
« Odpowiedź #71 dnia: 22 Listopada 2016, 12:43:13 »
Włos mi się zjeżył na głowie jak przeczytałem o przydzielaniu pamięci dla pojedynczych znaków. Zgroza. (No chyba, że czegoś tu nie wiem).

Od jakiegoś czasu używam prywatnie parsera formatu MaSzyny do swoich celów (robię nowy, lepszy starter) - działa na zasadzie FSM-Lexer/Parser. Na razie wszystko mu jedno co jest w tych plikach, działa jako iterator, czyli od podpiętego modułu zależy, co do czego będzie parsował. Starter interesuje tylko niewielki podzbiór, więc ten podzbiór jest czytany, cała reszta jest ignorowana, w momencie jak przestanę ją ignorować, nie będą mnie obchodzić stringi w skryptach - dostanę gotowe obiekty. Przypuśćmy, że mam obiekt składający się po prostu ze współrzędnych X, Y, Z. Czyli strukturę z 3 double. Funkcja parsera "ParseVector()" pobierze 3 tokeny, sparsuje 3 stringi jako double i zapisze w strukturze. Do tego jest jeszcze parsowanie kolorów RGB, ścieżek do plików i czasów.

Jak tam to działa? Masz jeden blok pamięci z całym skryptem. Lexer analizuje za każdym krokiem 1 do 2 znaków skryptu. Znaczenie znaku jest interpretowane w zależności od stanu (int). Stan zmienia się w zależności od napotkanych znaków. Szybciej się nie da. Pierwsza faza (analiza leksykalna) rozdziela logicznie skrypt na "encje" (powiedzmy znaczące słowa), znaki rozdzielające i komentarze. Wynikiem tej fazy są wyłącznie offsety i długości w skrypcie. Biorąc "string" z takiego tokena z góry znasz jego długość. Dodatkowo każdy taki string możesz praktycznie zapisać dokładnie w tym samym przydzielonym 1KB (dałbym nawet 64KB, żeby zapas był). Oczywiście nie unikniesz "ToDouble()", ale przynajmniej nie będzie to zużywać bez porównania większego czasu na przydzielanie pamięci. Z doświadczenia wiem, że mało rzeczy jest wolniejszych od przydzielania. Jak pętla ma przejść po 100MB danych, w środku nie może być praktycznie żadnego przydzielania.

Gdybym potrzebował wydajności (optymalizacja czasu ładowania) - zapisałbym wynikowe obiekty jako binarki. Przykładowo "nazwa.scm => nazwa.bin", albo "katalog/nazwa.scm => "cache/nazwa.bin". I po krzyku. Pierwsze uruchomienie - ładowanie 5 minut, drugie uruchomienie ładowanie 10 sekund. Zastanowiłbym się nawet nad przepuszczeniem strumienia cache przez kompresor. Być może byłoby to szybsze niż ładowanie dłuższych plików nieskompresowanych.

Do tego nie trzeba n "własnych formatów". Dokładnie jeden ogólny. Wynikający ze struktury binarnej obiektu. Format definiuje struktura. Serializację gotowy serializer. Broń boziu pisać własny, szkoda czasu. Pierwsza faza ładuje, parsuje i cache-uje pliki. Dalej w kodzie nie powinno być już kompletnie nic związanego z parsowaniem. Koniecznie osobne przebiegi. Nie "parsuj linię, załaduj teksturę, parsuj kolejną", tylko "załaduj wszystkie skrypty (łącznie z include), przejdź do ładowania pozostałych zasobów". Mam nadzieję, że rozkłady jazdy mają wewnętrznie jakąś sensowną binarną reprezentację, bo parsowanie tych koszmarków "na żywca" musi być bardzo wolne.

Dla optymizacji można by pokusić się o własną wersję "ToDouble" - ignorującą masę przypadków brzegowych jak różne formaty liczb. Ale to słaba opcja, lepiej dopuścić w skryptach bardziej "poluzowaną" notację kosztem wydajności, a zapisywać binarki w cache. Do zrobienia: 1 ogólny format cache, testowanie aktualności przez porównanie dat plików.

Offline tmj

  • Deweloper
  • Wiadomości: 3808
    • Zobacz profil
  • Otrzymane polubienia: 2351
Odp: Odp: Exe - konwersja na C++
« Odpowiedź #72 dnia: 22 Listopada 2016, 14:51:53 »
Włos mi się zjeżył na głowie jak przeczytałem o przydzielaniu pamięci dla pojedynczych znaków. Zgroza. (No chyba, że czegoś tu nie wiem).
Raczej niezrozumienie jak dziala std::string. Zadna normalna/rozsadna implementacja nie przydziela pamieci dla pojedynczych znakow z osobna, nie ma co panikowac.

Dla zaspokojenia ciekawosci zrobilem sobie nastepujacy test:
// start
cParser parser( scenefile, cParser::buffer_FILE, subpath );
std::string token;
do {
token = "";
parser.getTokens();
parser >> token;

} while(token != "" );
// stop
i przepuscilem przez niego scenery/quarkmce.scn (w sumie na oko jakies 10mb tekstu) Calosc zajela ok. 1.7 sek, przy odczycie z normalnego, starego HDD. Wiec akurat nad wydajnoscia parsera bym sie nie spinal -- raczej nie jest on odpowiedzialny za ladowanie scen w 5-10 minut, i naweg gdyby Borland byl jakims sposobem kilka razy szybszy (nie moge skompilowac/sprawdzic) to i tak mowimy tu o roznicy wielkosci ulamka sekundy, w procesie ktory wykonuje sie raz na uruchomienie.

(zeby bylo smieszniej, przeniesienie zmiennej do naglowka itp nie ma realnego wplywu na predkosci testu; podejrzewam ze najwolniejszym elementem jest, tak jak mozna bylo sie spodziewac, samo ladowanie zawartosci plikow z dysku)
« Ostatnia zmiana: 22 Listopada 2016, 14:59:34 wysłana przez tmj »

Offline El Mecánico

  • Wiadomości: 1067
  • Dawniej El Driver
    • Zobacz profil
    • Stowarzyszenie POLARIS - OPP
  • Otrzymane polubienia: 2
Odp: Odp: Exe - konwersja na C++
« Odpowiedź #73 dnia: 22 Listopada 2016, 16:24:31 »
A czy aby wąskim gardłem tutaj nie będzie przeskakiwanie do funkcji ładujących elementy scenerii i czekanie za każdym razem na ich zakończenie? IMO, ładowanie elementów mogło by spokojnie latać w osobnych wątkach i operować na obiektach przygotowywanych z już określonym rozmiarem i zarezerwowaną pamięcią przed wywołaniem funkcji ładującej. Komunikacja przez semafory.
www.polaris.org.pl
www.ciemneniebo.pl
MaSzyna_LD w trakcie tworzenia...

Offline tmj

  • Deweloper
  • Wiadomości: 3808
    • Zobacz profil
  • Otrzymane polubienia: 2351
Odp: Odp: Exe - konwersja na C++
« Odpowiedź #74 dnia: 22 Listopada 2016, 18:55:28 »
Jak najbardziej, z tym ze przy programowaniu wielowatkowym znacznie latwiej cos schrzanic niz zwykle, wiec troche trzeba przy tym uwazac. Dobrze byloby pewnie najpierw naprawic i uporzadkowac to, co jest, rozdzielic na jakies sensowne moduly i takie tam.

Offline firleju

  • Zasłużony dla Symulatora
  • Wiadomości: 1588
  • bawię się (w) exe...
    • Zobacz profil
  • Otrzymane polubienia: 120
Odp: Odp: Exe - konwersja na C++
« Odpowiedź #75 dnia: 22 Listopada 2016, 19:32:52 »
Większym problemem przy parsowaniu pliku scenerii jest to, ze mamy mnóstwo braku trafień w cache, a związane z brakiem parsowania całego pliku naraz  a dopiero potem inicjacja obiektów. W tej chwili ładujesz plik tekstowy do zmiennej, coś na niej czytasz, robisz mnóstwo innych operacji przy okazji i co chwila nie trafiasz w cache procesora. Jak wracasz do parsowanego tekstu to już go w cache znowu nie ma i musisz go ściągać z pamięci głównej. Tylko, że nie wiem czy jest sens rozgrzebywać ładowanie scenerii kiedy działa. Chociaż z drugiej strony ładowanie kaliskiej na moim kompie to jakieś 20 min, więc może jest o co walczyć.
Skrypty do Blendera dostępne tutaj
W miarę aktualne wiki EXE wiki.eu07.es

Offline HTD

  • Wiadomości: 689
  • "Twoja stara mieszka w Boldach" xD
    • Zobacz profil
    • I like trains
  • Otrzymane polubienia: 26
Odp: Odp: Exe - konwersja na C++
« Odpowiedź #76 dnia: 22 Listopada 2016, 20:02:02 »
IMHO jest sens, ale nie teraz. Na początek potrzebna byłaby wersja exe identyczna z bieżącą oficjalną, tyle, że już bez Borlanda. To byłby dobry punkt wyjścia. Gdyby robić optymalizację exe przedtem - ten etap, kamień milowy pewnie mocno by się opóźnił w czasie. A tak, zanim się ruszy optymalizacje - można by poprawić bugi, czy dodać kilka mocno usprawniających symulację usprawnień. No i zawsze lepiej chyba optymalizować już co w 100% działa, nie?

Offline El Mecánico

  • Wiadomości: 1067
  • Dawniej El Driver
    • Zobacz profil
    • Stowarzyszenie POLARIS - OPP
  • Otrzymane polubienia: 2
Odp: Odp: Exe - konwersja na C++
« Odpowiedź #77 dnia: 22 Listopada 2016, 20:14:40 »
Oczywiście, że jest o co walczyć. Sama konwersja z jednego systemu programistycznego do innego już sporo bałaganu narobiła, więc równolegle montowanie novum to tego (nowy branch) jest odpowiednim momentem.

Zastanawiam się nad jeszcze jednym rozwiązaniem problema: dla ładowania jako tako nie jest problemem zapis jednego elementu skryptu scenerii w jednej linii, więc... "zwijamy" wiersze, tniemy plik przy ładowaniu linijka po linijce, i w takiej kolejce popychamy do parsera. Kolejki obiektów na ogół nie są w całości cofane z cache, przynajmniej trochę z góry powinno zostać. Teraz dopiero przystępujemy do zasadniczej obróbki materiału. Rezerwujemy pamięć pod obiekt i zasadniczego konstruktora albo puszczamy w odrębny wątek, albo jeśli nie chcemy się w wielowątkowość bawić (shame!) czekamy aż konstruktor skończy i zgłosi gotowość.
www.polaris.org.pl
www.ciemneniebo.pl
MaSzyna_LD w trakcie tworzenia...

Offline tmj

  • Deweloper
  • Wiadomości: 3808
    • Zobacz profil
  • Otrzymane polubienia: 2351
Odp: Odp: Exe - konwersja na C++
« Odpowiedź #78 dnia: 22 Listopada 2016, 21:45:17 »
IMHO jest sens, ale nie teraz. Na początek potrzebna byłaby wersja exe identyczna z bieżącą oficjalną, tyle, że już bez Borlanda. To byłby dobry punkt wyjścia.
Tez wydaje mi sie, ze najrozsadniej chyba byloby skupic sie najpierw na wykopaniu Borlanda do konca, a jak juz sie da skompilowac rezultat gdzie indziej, to mozna go puscic przez profiler i na podstawie tego robic optymalizacje tego, co faktycznie obciaza proces.

Offline HTD

  • Wiadomości: 689
  • "Twoja stara mieszka w Boldach" xD
    • Zobacz profil
    • I like trains
  • Otrzymane polubienia: 26
Odp: Odp: Exe - konwersja na C++
« Odpowiedź #79 dnia: 23 Listopada 2016, 00:01:05 »
Z mojego doświadczenia wrzucanie czasochłonnych rzeczy do konstruktorów jest średnim pomysłem. Nie, żeby się nie dało, ale w C# przykładowo standardem jest puszczanie takich rzeczy jako dajmy na to LoadAsync, co oczywiście odpala się w równoległych wątkach, a potem można poczekać aż wszystkie skończą, czy też dowolnie pokolejkować przykładowo semaforami.
Ale to daleki strzał, i wg mnie dość prosta rzecz do zrobienia. Nie ma się co bawić przy tym formacie w linie, dla formatu EOL, spacja, tab czy średnik znaczą dokładnie to samo. To powinien (jak ma być naprawdę szybko) robić lexer, od tego jest. Oczywiście może sobie chodzić szeregowo w łańcuszku z parserem, a może nawet równolegle, ale to już trochę zabawy z synchronizacją. Ważne, żeby dane były sparsowane ZANIM symulacja w ogóle odpali, parsowanie podczas symulacji jest oddawaniem cykli CPU za darmo. Warto je przeznaczyć na ciekawsze zadania.

ALE: z tego co widziałem, przy ładowaniu scenerii i tak 99% czasu wydaje się zajmować ładowanie tekstur. Reszta się u mnie ładuje w kilka sekund. No chyba, że zielone okienko kłamie. Tekstury ładują się tak długo, bo na długiej trasie może być ich naprawdę sporo. Może i nawet musi. Im więcej tym lepiej. Im większe tym lepiej. Może tylko niekoniecznie powinny ładować się wszystkie na raz. Co się stanie z silnikiem Fallout 4 gdy spróbujemy załadować kilka kilometrów kwadratowych na raz? Albo chociaż spróbujemy przemieścić się z prędkością maksymalną EP09? Wysypie się. Tzn nie do Windowsa, po prostu się okrutnie przytnie, zawiesi na chwilę, bo musi sobie dograć tekstury. Tego normalnie podczas gry nie widać (dogrywają się dynamicznie).

I prędzej czy później to będzie w MaSzynie też potrzebne. Sprawdzanie jakie obiekty są powiedzmy w promieniu 2km, i te mają się dograć. OK, na początek i tak będą się musiały wgrać wszystkie co wyświetlają się przy starcie, ale potem będzie dość czasu na dogranie. To musi być rzecz jasna opcja, bo na muzealnym sprzęcie by zacinało. Ale na współczesnych komputerach spokojnie wszystko nadąży.

Tylko oczywiście nie teraz. Teraz wylatuje Borland, potem będzie parę szybkich bugów do usunięcia. I parę potrzebnych ficzerów do dodania. Optymalizacja ładowania to będzie wisienka na torcie ;)

Offline firleju

  • Zasłużony dla Symulatora
  • Wiadomości: 1588
  • bawię się (w) exe...
    • Zobacz profil
  • Otrzymane polubienia: 120
Odp: Odp: Exe - konwersja na C++
« Odpowiedź #80 dnia: 23 Listopada 2016, 13:12:25 »
Z mojego doświadczenia brak inicjacji w konstruktorze zmiennych, do których odwołanie odbywa się przez wskaźnik prowadzi wprost do wysypów w dziwnych i nieoczekiwanych okolicznościach.
Skrypty do Blendera dostępne tutaj
W miarę aktualne wiki EXE wiki.eu07.es

Offline tmj

  • Deweloper
  • Wiadomości: 3808
    • Zobacz profil
  • Otrzymane polubienia: 2351
Odp: Odp: Exe - konwersja na C++
« Odpowiedź #81 dnia: 23 Listopada 2016, 14:06:54 »
Z mojego doświadczenia brak inicjacji w konstruktorze zmiennych, do których odwołanie odbywa się przez wskaźnik prowadzi wprost do wysypów w dziwnych i nieoczekiwanych okolicznościach.
No, tak sie konczy proba odwolania do czegos co nie jest gotowe :)  Ale to nie znaczy ze trzeba caly process przygotowania modelu robic w konstruktorze. Konstruktor moze np oznaczyc obiekt jako 'niegotowy' (I albo odpalic proces ladowania/obrobki albo zostawic to dla managera) a reszta kodu jest wtedy tresowana zeby tego nie tykac dopoki flaga gotowosci nie jest przestawiona.

Offline HTD

  • Wiadomości: 689
  • "Twoja stara mieszka w Boldach" xD
    • Zobacz profil
    • I like trains
  • Otrzymane polubienia: 26
Odp: Odp: Exe - konwersja na C++
« Odpowiedź #82 dnia: 23 Listopada 2016, 18:42:03 »
I to mi się podoba. Konstruktor powinien inicjować wszystko co da się zrobić natychmiast. Czyli wszystkie zmienne, ale już nie obiekty większe od 1kB, te powinny być ustawione na jakieś null-e i być inicjowane kiedy są potrzebne, względnie w jakimś osobnym wątku inicjacyjnym.

Te rzeczy można nawet robić od razu, tzn bez kombinowania z wątkami na początku, niech będą sobie w osobnej funkcji typu Init lub Load, i niech to się odpala zaraz po konstruktorze. Jak zabangla, to można wtedy kombinować z przeniesieniem tych wywołań w bardziej optymalne miejsce.

Gorzej, jeśli przy tworzeniu obiektów nie wszystko jest sparsowane, to już jest węzeł do rozplątania.

Offline firleju

  • Zasłużony dla Symulatora
  • Wiadomości: 1588
  • bawię się (w) exe...
    • Zobacz profil
  • Otrzymane polubienia: 120
Odp: Odp: Exe - konwersja na C++
« Odpowiedź #83 dnia: 24 Listopada 2016, 10:05:48 »
Tylko powiedz mi czym różni się Kontruktor(); Init(); od wrzucenie wszystkiego do Konstruktor() ? Ja miałem wysypy bo konstruktor nie tworzył jakichś obiektów i wskaźniki były na NULL (gdyż autor poprawki nie wywołał nigdzie Init() ). Wole stworzyć nowy obiekt z domyślnymi wartościami, ale nie bawić się w jego obróbkę, gdyż jeśli ktoś coś potem zawali to nie mamy niespodziewanych wysypów w dziwnych miejscach. Już nie mówiąc, o całej klasie TMoverParameters, którą trzeba rozbić na wszystkie występujące przypadki, a nie wrzucać do jednego worka wszystkich możliwych fizyk i potem mamy if-y włącznie z takimi kwiatkami jak if(dt_et22) coś tam coś tam else coś tam dla reszty.
Ale wracając do inicjacji obiektów, to w tej chwili ja wolę to mieć w konstruktorze i być pewnym, że się coś nie sypnie, aczkolwiek większość obiektów ma wydzieloną funkcję Init() tylko, że jest to dalsza część konstruktora tak naprawdę i nie można używać tych obiektów dopóki ona nie zostanie wywołana. Używać rozumiem pod pojęciem, że wywołanie zwróci błędne dane, ale nie wysypie programu na odwołaniu do NULL.
Skrypty do Blendera dostępne tutaj
W miarę aktualne wiki EXE wiki.eu07.es

Offline HTD

  • Wiadomości: 689
  • "Twoja stara mieszka w Boldach" xD
    • Zobacz profil
    • I like trains
  • Otrzymane polubienia: 26
Odp: Odp: Exe - konwersja na C++
« Odpowiedź #84 dnia: 24 Listopada 2016, 15:52:30 »
Powinno wyglądać docelowo tak: if (krowa.dane != null) krowa.Init(); Brak null-checka w miejscu, gdzie obiekt może być jeszcze niezaładowany to po prostu bug. Tzn na razie może zostać, ale lepiej to później poprawić.

Przy czym jestem przeciwnikiem wszelkich technik "ukrywania błędów". Ludzie poświęcają zadziwiająco dużo energii, żeby nie dopuścić do sypania się apki podczas działania, ale omijają szerokim łukiem rzeczywiste programowanie defensywne, czyli takie, gdzie sama poprawność konstrukcji uniemożliwia sypanie kodu.

Mało tego, jestem za taką konstrukcją, która jak najbardziej wywali wyjątek, zamiast po cichu obejdzie czy zignoruje. Masz twardy wysyp - to widzisz gdzie jest bug i możesz go poprawić. Ale możesz to ukryć w ten sposób, że część rzeczy będzie śmigać, a część kiedyś tam się wysypie, jak już wszyscy zapomną od czego. Myślę, że niektóre zmienne powinny być wręcz jawnie ustawione na null, żeby posypało się wszystko co tylko może. Dzięki temu można wyłapać te miejsca i poprawić. Jasne, że nie ma sensu dawać null-checka w jakiejś pętli mielącej coś pierdyliard razy, ale domyślam się, że problem jest wyłącznie przy uruchamianiu, jak symulator startuje wszystko jest wgrane i gotowe. Swoją drogą byłoby fajnie też, żeby do wersji dla userów dać kilka try / catch w kluczowych miejscach i wysyłać wyjątki do logu. Jak ktoś zaliczy wysyp, to będzie mógł przynajmniej wysłać co się złożyło.

Offline firleju

  • Zasłużony dla Symulatora
  • Wiadomości: 1588
  • bawię się (w) exe...
    • Zobacz profil
  • Otrzymane polubienia: 120
Odp: Odp: Exe - konwersja na C++
« Odpowiedź #85 dnia: 25 Listopada 2016, 07:27:53 »
Yyyy.... Wiesz, raz mi się sypało na braku kabiny. Tylko nikt nie wie czemu kabina usunięta i załadowana w tej samej funkcji i przypisana do wskaźnika w następnym cyklu wskaźnik był ustawiony na null a w następnym już był przypisany. W innym przypadku sypało na braku przypisania nazwy do PowerSource w funkcji logowania przeciążenia stacji. Okazało się, że nazwa była przypisywana ręcznie do klasy (do zmiennej public) i w jednym miejscu tworzenia klasy to było zrobione a w innym nie. I teraz mi powiedz, że nie zrobienie tego w konstruktorze (kiedy mamy te dane) jest normalne i logiczne. Za to zgadzam się, że ładowanie pliku przez konstruktor to nie jest najlepszy pomysł.

  Dodano: 25 Listopada 2016, 07:32:22
Ahhh... A miałem coś powiedzieć z ciekawostek fizyki. Otóż w funkcji getVDc() mamy trzy bloki if-a. W ostatnim liczy różnicę przepływów przez połączenia do pojazdów. Cała funkcja obliczająca różnicę jest zestawem kolejnych mnożeń. Po środku nawet wołana jest funkcja klasy hamulca, jakieś sprawdzania maksimów. Po wyliczeniu wywoływane funkcje zmiany przepływów w pojazdach obok. Super prawda?
Szkoda tylko, że na końcu funkcji obliczającej różnicę jest wielkie * 0. Ktoś mi powie po co to wszystko wyliczać kiedy żadnych zmian nie będzie?
« Ostatnia zmiana: 25 Listopada 2016, 07:32:22 wysłana przez firleju »
Skrypty do Blendera dostępne tutaj
W miarę aktualne wiki EXE wiki.eu07.es

Offline tmj

  • Deweloper
  • Wiadomości: 3808
    • Zobacz profil
  • Otrzymane polubienia: 2351
Odp: Odp: Exe - konwersja na C++
« Odpowiedź #86 dnia: 25 Listopada 2016, 13:18:02 »
I teraz mi powiedz, że nie zrobienie tego w konstruktorze (kiedy mamy te dane) jest normalne i logiczne. Za to zgadzam się, że ładowanie pliku przez konstruktor to nie jest najlepszy pomysł.
Ale chyba nikt nie sugeruje, zeby w konstruktorze w ogole nic nie robic? Tylko zeby rozdzielic takie rzeczy jak np proste ustawienie wartosci dla stringa z nazwa (konstruktor) z jednej strony, a ladowanie i obrobka siatki 3d powiazanej z modelem (init/load/whathaveyou)

Ale tak przy okazji, to jesli chodzi o te przyklady, to 1) z kabina, to wlasnie jest raczej przyklad tego, ze nie ma co na slepo odwolywac sie do obiektu bez sprawdzenia czy nie jest on czasem ustawiony na null -- tutaj taki test albo kontrolowany wysyp duzo latwiej byloby wysledzic 2) to oczywiscie powinno byc zrobione w konstruktorze; ale nawet jesli nie bylo, to wysyp mial raczej miejsce dlatego, ze domyslnie  w ogole nie bylo tam nic przypisane, a na zdrowy rozum powinno to byc cos jak "unspecified class" albo nawet pusty string, ale /jakis/ string a nie dziura do pamieci, ktorej glupi komputer od stringa nie odroznia :)

Offline HTD

  • Wiadomości: 689
  • "Twoja stara mieszka w Boldach" xD
    • Zobacz profil
    • I like trains
  • Otrzymane polubienia: 26
Odp: Odp: Exe - konwersja na C++
« Odpowiedź #87 dnia: 25 Listopada 2016, 20:34:40 »
Ja w konstruktorach ustawiam zmienne, ale nie robię następujących rzeczy: operacji wejścia / wyjścia, iteracji dużych zbiorów.
Te rzeczy zostawiam dla funkcji asynchronicznych. Sprawdzałem przed chwilą: w C++ jest w miarę sensowna obsługa tego.
Jak wielowątkowość może przyśpieszyć program to wiesz. A nie ma specjalnie dużo więcej pisania. Potem masz swobodę poukładania sobie, co się musi wgrać pierwsze, co musi poczekać, a co może się inicjować jednocześnie. Oczywiście to wymaga porządku w kodzie. Zawsze musisz sprawdzić, czy dane w konkretnym punkcie są już dostępne. Albo wołać operację na danych, kiedy masz pewność że masz dane (bo poczekałeś na wątek inicjujący). No i masz potem czasem przypadek, że nie musisz nawet czekać, bo wątek zdążył skończyć. Czysty zysk w takim przypadku.

Offline youBy

  • Deweloper
  • Wiadomości: 6132
  • Co tam?
    • Zobacz profil
    • Automat Weryfikujący Regulację i Lambdę
  • Otrzymane polubienia: 814
Odp: Odp: Exe - konwersja na C++
« Odpowiedź #88 dnia: 25 Listopada 2016, 23:02:57 »
Ahhh... A miałem coś powiedzieć z ciekawostek fizyki. Otóż w funkcji getVDc() mamy trzy bloki if-a. W ostatnim liczy różnicę przepływów przez połączenia do pojazdów. Cała funkcja obliczająca różnicę jest zestawem kolejnych mnożeń. Po środku nawet wołana jest funkcja klasy hamulca, jakieś sprawdzania maksimów. Po wyliczeniu wywoływane funkcje zmiany przepływów w pojazdach obok. Super prawda?
Szkoda tylko, że na końcu funkcji obliczającej różnicę jest wielkie * 0. Ktoś mi powie po co to wszystko wyliczać kiedy żadnych zmian nie będzie?
Trzeci blok ifa został z czasów kalibracji przepływów. Koniec końców okazało się, że bez tej części symulator działa najlepiej – nie posprzątałem po sobie.
Xoov
Powyższy post wyraża jedynie opinię autora w chwili publikacji. Autor zastrzega sobie prawo do zmiany poglądów bez podawania przyczyny, jak również informowania o tym.

Offline El Mecánico

  • Wiadomości: 1067
  • Dawniej El Driver
    • Zobacz profil
    • Stowarzyszenie POLARIS - OPP
  • Otrzymane polubienia: 2
Odp: Odp: Exe - konwersja na C++
« Odpowiedź #89 dnia: 26 Listopada 2016, 14:20:54 »
IMO konstruktor powinien skończyć robotę jak najszybciej i tylko przygotować zestaw zmiennych dla kolejnych funkcji ładujących, czyli poinicjalizować wskaźniki na null, powpisywać nazwy plików (bez ich otwierania) i wrócić do miejsca wywołania. Tak wstępnie powstałe obiekty wypadało by posortować pod względem istotności dla _rozpoczęcia_ symulacji i w takiej kolejności ładować grube dane. Pierwsza pewnie komórka (komórki) scenerii na której znajduje się nasz pojazd/skład, potem w odległości wyświetlania, uzależnienia/sterowanie w tej lokalnej komórce. Całą resztę scenerii można załadować w tak minimalnej postaci jak tylko to możliwe i konieczne do obliczenia dynamiki i interakcji pojazdów, czyli pomijając całe modelowanie. Na to czas będzie nawet już w czasie symulacji. Generalnie fizyka i grafika powinny być w zależności podległej (grafika wyświetla dopiero jak fizyka policzy), bez pobierania z grafiki jakichkolwiek danych, nawet synchronizacji. Grafika powinna liczyć na _kopii_ danych otrzymanych od fizyki, żeby nie było, że między początkiem a końcem tworzenia klatki fizyka podmieni dane.
www.polaris.org.pl
www.ciemneniebo.pl
MaSzyna_LD w trakcie tworzenia...