Pokaż wiadomości

Ta sekcja pozwala Ci zobaczyć wszystkie wiadomości wysłane przez tego użytkownika. Zwróć uwagę, że możesz widzieć tylko wiadomości wysłane w działach do których masz aktualnie dostęp.


Wiadomości - kibiC++

Strony: [1] 2 3
1
Ja również! :)

2
Design / Odp: Blog o projektowaniu gier
« dnia: Listopad 26, 2016, 16:01:23 »
Bez urazy, ale blog jest jakiś taki... bezjajeczny. O niczym.

Dla przykładu wpis O narzędziach.

Na początku wywnioskowałem, że kiedyś to było fajnie, bo wystarczył sam C i voila - gra już "się pisze" a teraz to
Cytuj
Dziś ciągle używa się silników, frameworków oraz innych zaawansowanych programów do ułatwiania sobie pracy.
Czyli gamedev to lenie bo ciągle używają czegoś co ułatwia pracę. Druga sprawa: czy silnik nie jest frameworkiem? I jakie to są te "inne zaawansowane narzędzia"?

Cytuj
edytory poziomów(...)Są to narzędzia, które oszczędzają pracę designerów
Chodziło chyba o oszczędzanie czasu? Dodatkowo, IMHO przykład o lamentach na brak 'kopiuj-wklej' nie  należy do najszczęśliwszych.

Cytuj
Jak widzicie, odpowiednie narzędzia potrafią zaoszczędzić wiele czasu, nerwów(...)Oczywiście nie zawsze opłaca się inwestować czas w takie rzeczy

Jestem za a nawet przeciw ;) Kiedy warto a kiedy nie warto?


3
Unity 3D / Odp: Organizacja danych
« dnia: Czerwiec 19, 2016, 14:05:20 »
AFAIK, Unity robi efektowne rozłożenie automatycznie, i to właśnie dzięki typom referencyjnym. Menadżer alokacji po prostu umieszcza obiekty tego samego typu w osobnych obszarach pamięci, jeden po drugim, w kolejności alokacji. Więc jeśli masz tysiąc klas Human, z których każda ma referencje na obiekt Gun, to pomimo że w konstruktorze Human tworzysz klasę Gun, w pamięci będziesz miał jedną "tablicę" obiektów Human i w innym miejscu tablicę obiektów Gun. I to niezależnie od tego, czy obiekty danego typu są u ciebie zadeklarowane jako np tablica, czy ich referencje i konstrukcje są porozrzucane w wielu niezależnych miejscach.
O taką odpowiedź mi chodziło :) Można gdzieś znaleźć więcej informacji o bebechach Unity?

tym, że zamiast wywoływać metody na stukturze, musisz mieć zestaw statycznych funkcji który przyjmuje strukturę. W ten sposób twój kod szybko staje się mniej czytelny. Poza tym wtedy strukturę przekazujesz przez referencje zawsze, żeby było szybciej, więc nie widzisz kiedy ta struktura jest przesyłana żeby coś odczytać, a kiedy żeby ją zmodyfikować. Normalnie przekazywanie przez ref odnosi się raczej do modyfikacji,a w takim designie nadmiarowo także do odczytu. Poza tym, jeśli stosujesz się do zasady immutable, to każda zmiana w strukturze wymusza stworzenie jej kopii, a to też nie jest czytelne ani miłe.
Faktycznie. Zapomniałem, że tu nie ma const z C++ :P

Podsumowując: słuchaj rady Arka :D
Na początek zapewne zastosuje się do rady ;) Ale, że nie zawsze w wolnych chwilach mam chęć na 'kodzenie' to zbieram info na co zwrócić uwagę i czego szukać po necie.

BTW spora część wydajności to rendering i fizyka, a te operacje są w unity napisane natywnie, i są zoptymalizowane pod kątem dd. Prawdopodobnie twój kod to tylko ~10% całości operacji, i choćbyś nawet napisał go w najwolniejszym języku to nie spowolni jakoś znacznie aplikacji. Przynajmniej dopóki czegoś nie zepsujesz :D
Pewnie dlatego Unity jest tak popularny. Ale czytałem ostatnio o IL2CPP który ponoć tłumaczy IL na C++ co daje dodatkowego kopa no i tak mnie naszło na rozmyślanie... :P

4
Unity 3D / Odp: Organizacja danych
« dnia: Czerwiec 09, 2016, 23:11:42 »
wydaje się, że jak już przystałeś na Unity oraz C#, to zgodziłeś się na takie a nie inne rozmieszczenie danych w pamięci :P
No tak. Tylko to trochę zaburzyło mój światopogląd i stąd cały ten wątek :)

Może powiedzmy sobie to że całe standardowe c# api(w tym linq) zostało napisane w większości wbrew strukturom(w tym Listy...).
Z C# wącham się od niecałego tygodnia, więc jeszcze sporo przede mną... Nadal np. nie widzę sensu w podziale na field/property :P

Polecam koncentracje na strukturach i tego rodzaju optymalizacjach w kluczowych momentach. Efekty będą wymierne.
Zapisałem.

Aleee....
Kod będzie wyglądał jak C++ dla ubogich. Wymaga to sporo doświadczenia i wiedzy.
Dopóty będzie to twór hobbystyczny i jednoosobowy dopóki brzydki kod nie będzie raczej stanowił problemu. Gorzej z doświadczeniem i wiedzą :D

Aktualnie zastanawiam się jak mógłbym zarządzać sceną i wszelakimi obiektami i ich zależnościami bez wszędobylskich managerów do których mam jakąś wrodzoną awersje. Nie wspominając już o singletonach które są chyba nieodłącznym elementem każdego tutoriala do Unity :P



5
Unity 3D / Odp: Organizacja danych
« dnia: Czerwiec 08, 2016, 14:51:28 »
Mógłbyś podać linka gdzie coś takiego wyczytałeś?

Z MSDN, dokładnie z drugiego linku podanego przez @strateg.

Wątków w stylu struct vs class jest bardzo dużo, więc polecam poczytać. Osobiście korzystam ze struktur głównie przy obsłudze kodu niezarządzanego.

Oczywiście czytałem :)

Głównie chodzi o mi o to, że skoro w C# nie mamy zbytniej kontroli nad tym gdzie obiekty są przechowywane to znaczy, że jest to jakoś optymalizowane 'wewnętrznie' i nie należy się tym zbytnio przejmować czy zwyczajnie świadomie zgadzamy się na siekanie cache'u w imię feature'ów języka :P

Ogółem wydawało mi się, że przejście z C++ na C# jest łagodniejsze. O ile składnia jest banalna to jednak człowiek wbił sobie do głowy pewne zachowania i przestawienie się nie jest takim hop-siup (value-semantic, const-correctness, etc. )

6
Unity 3D / Organizacja danych
« dnia: Czerwiec 07, 2016, 22:44:02 »
Witam.
Na wstępie chciałbym nadmienić, że zdaje sobie sprawę, iż premature optimization to zło wcielone i ogień piekielny, ale ciekawość jest jednak silniejsza i chciałbym się dowiedzieć paru rzeczy :)

1.) Sporo można poczytać o efektywnym rozłożeniu danych ( hot/cold, cache-friendly, etc. ). Jak to się ma do architektury Unity skoro klasy w C# to typy referencyjne i jakiekolwiek grupowanie ich(jeśli takowe występuje) w tablice/listy to jedynie grupowanie referencji a same obiekty latają sobie gdzieś swobodnie po zakamarkach heapu?

2.) Czy spotkaliście się, a może sami używacie jakiegoś niekonwencjonalnego sposobu na grupowanie danych( stricte danych, nie referencji)?  (punkt można ominąć, jeśli moje rozumowanie pkt.1 jest błędne :))

3.) W wielu miejscach można wyczytać, żeby struktury raczej omijać z daleka, a jeśli już jest taka potrzeba to:
  a.) powinny być nie większe niż 16b
  b.) powinny być niemutowalne

4.) Czy zalecany maksymalny rozmiar struktur z pkt. 3a jest związany wyłącznie z tym, że structy przekazywane są przez wartość? Jeśli tak, to w czym problem przekazywać strukture przez ref?

PS. Nie wiedziałem czy temat dać tutaj czy dziale C#, tak że z góry przepraszam za ewentualny bałagan :)

7
Szkółka / Odp: Queue/Vector - Multi-producer, single-consumer
« dnia: Luty 16, 2016, 21:28:20 »
Chyba nie tak - albo ja czegoś tu nie rozumiem.

Skąd ten pomysł, żeby wywoływać metodę push w pętli aż do skutku?
Powiedzmy, że to "skrót myślowy" - czyli przepisałem na pałę z przykładu boost'a :P

Cytuj
Co oznacza running? Chcesz uruchamiać wątek wykonujący Process przy okazji dodawania elementów do kolejki, a kończyć go kiedy tylko kolejka jest pusta? To może być bardzo wolne, bo uruchamianie nowego wątku jest wolne. Lepiej, żeby taki wątek startował na samym początku programu, działał przez cały czas i czekał aż w kolejce coś się pojawi.
Taki mam zamysł, żeby użyć thread pool i przy uruchamianiu odpalić ich rozsądną ilość. Tylko, że...
Powiedzmy, że mam 8 wątków i >16 obiektów:
1.) Metoda A::Process() działa non-stop, jakieś while( true ) na początku i jazda
2.) Metoda A::Process() jest odpalana tylko wtedy gdy coś pojawi się w jej kolejce i kończy się w momencie gdy wyczyści całą kolejkę - czyli while(!queue.empty())

Ad.1) W tym rozwiązaniu nie podoba mi się to, że nawet gdy przez dłuższy czas w danym obiekcie kolejka będzie pusta to i tak zawsze jeden z wątków będzie "przełączany" po to, żeby się dowiedzieć, że nic nie ma tutaj do roboty.

Ad.2) To rozwiązanie bardziej przypadło mi do gustu. Wątek wrzucający coś do kolejki danego obiektu w razie konieczności wysyła info do puli wątków, żeby się tym zajął. Po opróżnieniu kolejki metoda się kończy i nikt sobie nie zawraca głowy tym obiektem, dopóki ktoś znowu czegoś nie wrzuci do kolejki.

Cytuj
Ogólnie polecałbym nie używać lockfree ani atomic, jeśli nie musisz (czyli nie stwierdzisz, że to jest wąskie gardło dla wydajności Twojego programu, które trzeba zoptymalizować), tylko użył prostszych do skumania muteksów.
No tak, zdecydowanie. Ale kombinacje z atomic i sama idea lock-free jest cholernie pociągająca :P

8
Szkółka / Queue/Vector - Multi-producer, single-consumer
« dnia: Luty 16, 2016, 17:22:23 »
Czytam sobie o wielowątkowości i zakręciłem się jak świński ogon ;)

class Foo {
  boost::lockfree::queue< int > queue;
  std::atomic< bool > running; // ?
public:
  void Post( int value ) {
    while (!queue.push( value ) );
    // compare_and_exchange? load?
    if ( !running )
      // std::async, std::thread, thread pool albo inny diabeł wywołujący metodę Foo::Process
  }
  void Process() {
    while( !queue.empty() ) {
      // ...
    }
    running = false;
  }
};

wątek 1: wejście do Foo::Post -> wrzucenie wartości do kolejki -> sprawdzenie stanu obiektu: obiekt śpi -> uruchomienie metody Foo::Process w nowym wątku -> wyłazi z metody.
Wątek 2: wejście do Foo::Post -> wrzucenie wartości do kolejki -> sprawdzenie stanu obiektu: obiekt pracuje -> wyjście z metody

Tutaj moje pytanie: Jak to powinno wyglądać?



9
Szkółka / Odp: std function, std::bind i dziedziczenie
« dnia: Luty 11, 2016, 16:01:27 »
Mniej więcej kojarzyłem w czym jest problem, ale nie wiedziałem jak to się nazywa.

Dzięki wielkie za wyjaśnienia. Tak obszernych odpowiedzi się nie spodziewałem :)



10
Szkółka / std function, std::bind i dziedziczenie
« dnia: Luty 10, 2016, 02:48:51 »
#include <functional>
#include <vector>
using std::placeholders;

class ArgumentBase { };
class ArgumentDrv : ArgumentBase { }

class ClassBase {
public:
   void Method( ArgumentBase& arg ) { }
};

class ClassDrv : ClassBase {
public:
   void AnotherMethod( ArgumentDrv& arg ) { }
};

using Callback = std::function< void( ArgumentBase& ) >;

int main( int, char** ) {
  std::vector< Callback > callbacks;
  ClassBase base;
  ClassDrv drv;
  callbacks.emplace_back( std::bind( &ClassBase::Method, &base, _1 );
  //callbacks.emplace_back( std::bind( &ClassDrv::AnotherMethod, &drv, _1 );  <<<! ERROR !>>>
  return 0;
}

Czy w takim przypadku jest możliwość aby do tego samego wektora dodać metodę z klasy ClassDrv?
Kompilator oczywiście wyrzuca error, ale wiadomo jak to jest z ich czytelnością w przypadku szablonów...


11
C++ / Odp: DOD i C++ (z czym to się je żeby się nie porzygać)
« dnia: Grudzień 19, 2015, 15:36:20 »
Dzięki za wyjaśnienie!
Masz rację, w programie testowym https://www.dropbox.com/s/q4zbrvtxpymi8sk/dod_vector.cpp?dl=0 kod jest trochę zmodyfikowany i rzeczywiście pojawiła się specjalizacja "pustego elementu" access<>

12
C++ / Odp: DOD i C++ (z czym to się je żeby się nie porzygać)
« dnia: Grudzień 19, 2015, 01:42:50 »
@Xender: Co fakt to fakt. Variadic templates i dziedziczenie po klasach parametryzowanych przez ten te parametry... dla mnie to jakiś kosmos i nie mam pojęcia jakim cudem kompilator to ogarnia.

Jak takie coś jest tworzone przez kompilator?
using FourMembers = access< int, float, double, char >;
Czy to jest rozwijane w ten sposób?
class access< int > : access< float >, access< double >, access< char > { }







13
C++ / Odp: DOD i C++ (z czym to się je żeby się nie porzygać)
« dnia: Grudzień 18, 2015, 21:46:07 »

14
C++ / Odp: DOD - nie tylko dla gier?
« dnia: Czerwiec 16, 2015, 01:55:50 »
Zapomniałem w sumie o najważniejszej rzeczy. DOD jest generalnie mylącą nazwą, bo tak naprawdę chodzi o "cache-friendly programming" -- minimalizowanie ilości wycieczek do głównej pamięci, czyli unikanie dereferencji wskaźników (głównie vptr w celu wywołania funkcji wirtualnych, stąd ten rzekomy "anty-OOP").
Vptr można jako tako obejść korzystając z CRTP. ( teoretycznie, ponieważ nie praktykowałem, ale sama idea mi się spodobała )

Cytuj
Wszystko to bardzo chwalebne, ale problem w tym, że cache procesora są małe. L2 to teraz kilka-kilkanaście MB. Da się zmieścić np. wszystkie metadane obiektów na scenie w grze, przez co ich update może być błyskawiczny. Ale o jakichkolwiek "dużych ilościach danych", jak to sugerował OP, należy zapomnieć. "Duże ilości danych" to kwestia optymalizacji RAM vs. dysk (a dla bardzo dużych ilości nawet RAMy/dyski wielu maszyn + net między nimi), a nie cache vs. RAM.

Tak, tylko jakoś nikt się jeszcze nie znalazł, który by coś takiego zakodował :) Podobnie jest na przykład z dependency injection, które IMHO dałoby się zrobić w C++ zerowym kosztem wydajnościowym w sposób który pasowałby idealnie do gier/silników (ze scope'ami pojednycznej klatki, levelu, etc.).
Przyznam szczerze, że ciężko jest mi pojąć DI a co za tym idzie nie rozumiem jakie to rozwiązanie ma zalety i czym góruje nad resztą.

Cytuj
Oh puh-lease! "Taniej i szybciej" to zwykle mantra zarządzających projektem, więc rzadko to wina 'roboli'. Z drugiej strony cyzelowanie każdego kawałka kodu żeby był jak najwydajniejszy to druga najlepsza metoda proskrastynacji (*), zapewniająca że system nie będzie gotowy na czas :)
Patrzę przez pryzmat raczkującego hobbysty próbującego "coś" stworzyć, więc nie myślałem o tym w ten sposób. Nie chciałem nikogo obrazić, wiadomo jakie są realia. Nie na wszystko ma się wpływ i niestety często trzeba iść na skróty bo ktoś wyżej ma takie widzimisie.

3grosze
Jeśli potrzebujesz dostępu do wszystkich danych w jakiejś kolekcji, wtedy przechowujesz ją odpowiednio do dostępu (np. w tablicy), co innego jednak, gdy potrzebujesz dostępu do tylko niektórych rekordów i musisz jakoś je wybrać (i tu cały szereg możliwości: czy warunki opierające się na dostępie do jakichś danych, czy sortowanie, czy wybór dynamiczny). W bazach danych przypadki jak sortowanie wyszukiwanie optymalizuje się przez indeksy (czyli wcześniej dokonane obliczenia na danych dzięki którym wyszukanie konkretnego rekordu jest szybkie, bo wyszukanie tutaj jest problemem wydajności, nie samo kopiowanie z RAMu). I jak już zostało powiedziane, przypadek gdy wszystkie dane są Ci potrzebne i mieszczą się w KB lub niewielu MB, a przypadek gdy potrzebujesz tylko częsci danych z kolekcji znacznie większej, są dość rozbieżne..
Ano właśnie. Nawiązując do przykładu z pierwszego posta. Każda jednostka administracyjna ma swoje granice, które częściowo są także granicami innych jednostek.
Przypadek 1: Granice, rzadko bo rzadko, ale ulegają zmianom ( = dostęp do konkretnego obiektu ),
Przypadek 2: mogę chcieć sprawdzić do której jednostki należy dany punkt ( = 50/50, testowanie od najwyższego poziomu podziału i przechodzenie niżej. Wskazane uprzednio posortowanie danych wg poziomów które reprezentują )
Przypadek 3: wysyłka do GPU i wyświetlanie. Tutaj najlepszym wydaje się sortowanie wg lokalizacji.
Analogicznie w przypadku danych o jednostkach. Mogę chcieć je filtrować/wyszukiwać wg populacji, wg powierzchni, wg nazwy etc.
I bądź tu mądry jak to ugryźć :P

Cytuj
Co do optymalizacji ogólnie, znowu nie należy zapominać, że optymalizować należy tylko "krytyczne miejsca" odnalezione profilerem lub pomiarami. I tu może warto mieć przygotowany prototyp rozwiązania (znowu to agile), żeby nie okazało się za późno (tj po implementacji), że do wymiany jest cały algorytm i jego struktury ;p
Z tą zasadą zdążyłem się zapoznać ;) Mam to szczęście, że mogę sobie pozwolić na bliższe przyjrzenie się nie tylko krytycznym miejscom. Żadne terminy mnie nie gonią ;) a i człowiek przy okazji dowiaduje się czegoś coraz to nowszego.

15
C++ / Odp: DOD - nie tylko dla gier?
« dnia: Czerwiec 14, 2015, 15:03:28 »
Klasyka warsztatu, ale co tam, nudzi mi się to odpowiem, w końcu programiści są głównie od tego, żeby dyskutować na temat OOP vs reszta świata :P.

Byłem świadomy tego, że taka wypowiedź prędzej czy później się pojawi ;) Osobiście lubię czytać takie wątki, bo zawsze można z nich wyciągnąć coś wartościowego i samemu przekonać się które z przedstawianych rozwiązań będzie lepszym wyborem w danym przypadku.

Cytuj
Oprócz wydajności procesora istnieje jeszcze wydajność programisty, czyli człowieka. Jednemu człowiekowi łatwiej komunikować się z drugim poprzez OOP niż poprzez DOD. A jako komunikację uważam tutaj udostępnianie bibliotek, czy całych środowisk (np. Unity). No i oczywiście komunikację w jednym zespole, ale to wiadomo. Ogólnie - zrozumienie kodu OOP jest łatwiejsze, bo jest naturalne. Żartuję ;]. Ale tak już bardziej poważnie to rzeczywiście jest łatwiejsze, bo mamy podpowiadanie składni, a do DOD nie mamy (chyba, że o czymś nie wiem). Prawdopodobnie da się napisać kodDOD prostszy od tego, co zaprezentowałeś, ale akurat do tego Twojego sam przyznasz - potrzebna jest instrukcja (którą zresztą sam przedstawiłeś z tymi numerkami).

Śmiem twierdzić, że wydajność programisty jest ważniejsza od wydajności maszyny, stąd mój bardzo ostry wniosek: OOP prowadzi do szybszego rozwoju technologicznego.
Czyli najlepszym wyjściem byłoby połączenie DOD ( organizacja danych ) i OOP ( interfejs i enkapsulacja implementacji czyli "ładne opisowe metody ukrywające to 'maglowanie i znaczenie poszczególnych numerków  )

Cytuj
A co do Twojej aplikacji:
Zgadzam się z Xionem w sprawie wykorzystania bazy danych. Moim zdaniem nie musisz czekać, aż wyjdzie kupa - już teraz możesz przyznać mu rację i nie musisz tego jeszcze robić pokornie póki co ;p. Ale to nie znaczy, że masz nie zakodować swojego rozwiązania, wręcz przeciwnie :). Dużo pisałeś o sortowaniu w swoim poście. W takim razie przeczytaj jakieś rzeczy na temat "indeksowanie w bazach danych", żebyś miał chociaż jakieś szanse w starciu z nimi. Dopóki złożoność obliczeniowa podstawowych operacji na zbiorze danych (bazie danych) będzie gorsza w Twoim rozwiązaniu niż w rozwiązaniu w gotowych bazach danych, to żadne lepsze ułożenie danych w tablicach nic nie pomoże. Jest to optymalizacja niżej położona niż rozpatrywana złożoność obliczeniowa, przez co nie przyspieszy wyszukiwania, jeśli najpierw nie będziesz miał wygranej (a tak naprawdę remisu) na tym wyższym, ważniejszym polu.
Zabieram się za poszukiwania :)

Wielowątkowość jest trudna, więc większość programów jest jednowątkowa. Tak jest prościej i taniej.

DOD jest trudny, więc większość programów stosuje klasyczny OOP. Tak jest prościej i taniej.

Gdyby był jakiś język, który już na poziomie składniowym ma wsparcie dla DOD, gwarantuję ci że o wiele więcej osób by go stosowało.
A no właśnie. Ale na tej podstawie można odróżnić fachowców korzystających z najwydajniejszych rozwiązań od 'robola' uczepionego jednego rozwiązania bo taniej i szybciej. I to się powinno chyba tyczyć każdego zawodu ;)

Ogółem dziękuję za odpowiedzi. Będę sobie spokojnie klepał i testował to co wymyśliłem i jednocześnie przyjrzę się bliżej bazom danych ( bo i tak koniec końców od tego nie ucieknę :P )

Strony: [1] 2 3