Vyplatí se učit C++?

zboj

  • *****
  • 1 507
    • Zobrazit profil
    • E-mail
Re:Vyplatí se učit C++?
« Odpověď #180 kdy: 31. 12. 2015, 21:01:04 »
Nechci bejt pedant, ale počítaní referencí JE GC ... A to že je pomalejší je podobná blbost jako to že to není GC. Když naivní implementaci RC porovnáváš s super hyper generačním tracing GC, je jasný kdo vyhraje. Když ale misto naivni implementace RC použiješ nějakou silně optimalizovanou implementaci, a že takový sou, vykon bude stejný, s tím rozdílem že RC bude mít minimální latenci.
jistě, správně mělo být něco jako "tracing GC"


zboj

  • *****
  • 1 507
    • Zobrazit profil
    • E-mail
Re:Vyplatí se učit C++?
« Odpověď #181 kdy: 31. 12. 2015, 21:03:39 »
To jo, ale to RC v podání MS je docela tragédie. Ono celé WinRT je dost podivné, knihovny jsou nativní, ale s overheadem se volají z .NET nebo dokonce JS. Už aby byl na Windows Swift :)
Já jsem měl právě pocit, že WinRT jde udělat krom .NET i nativně v Cx nebo v C++ a pak je to normální binární EXE volající DLL a COM, jako hra pro DirectX. Je to ale jen pocit. Přiznám ale, že jsem to zatím prakticky neověřoval a možná ani nebudu. Protože po hrubém prostudování API jsem došel k závěru, že pro mou aplikaci stačí Win32 + DirectX s targetováním Windows 7 a speciální port pro Windows 8 nic extra nepřinese.
Jen upřesním, že žádné Cx neexistuje, jen C++/CX, což je C++ s rozšířenou syntaxí z C++/CLI. Jinak ano, překládá se do nativního kódu.

Re:Vyplatí se učit C++?
« Odpověď #182 kdy: 31. 12. 2015, 21:07:57 »
No oni klasické GC navíc defragmentují paměť. Je to možné hlavně proto, že mají pod kontrolou všechny pointery. Měl jsem v C++ napsaný jednoduchý GC který dynamicky udržoval kostru v grafech referencí a tedy fungoval i s cykly (spouštěl se, jen když někdo zrušil referenci, která byla označena jako kostra grafu, a tehdy se snažil sestavit novou kostru a uvolnit všechny objekty, které se ocitly z kostry nedosažitelné), ale nepřišlo mi, že by byl rychlejší. Ony to totiž zdržují zejména alokace, tedy hledání volného místa ve fragmentované paměti a dealokace, tedy update tabulky volného místa.

V čistem C++ nejde moc dobře pod rukama programu defragmentovat paměť. Díky existenci raw pointerů nemám jistotu, že s pamětí zrovna někdo nepracuje (a i přes chytré ukazatele se raw pointery používaji, takovým nejtypičtějším raw pointerem je this)

zboj

  • *****
  • 1 507
    • Zobrazit profil
    • E-mail
Re:Vyplatí se učit C++?
« Odpověď #183 kdy: 31. 12. 2015, 21:08:10 »
Nechci bejt pedant, ale počítaní referencí JE GC ... A to že je pomalejší je podobná blbost jako to že to není GC. Když naivní implementaci RC porovnáváš s super hyper generačním tracing GC, je jasný kdo vyhraje. Když ale misto naivni implementace RC použiješ nějakou silně optimalizovanou implementaci, a že takový sou, vykon bude stejný, s tím rozdílem že RC bude mít minimální latenci.

Jak jsem psal, dobrá statická analýza zrychlí RC natolik, že si člověk overheadu správy paměti ani nevšimne. Latence je samozřejmě nižší a hlavně se hodně snižuje "high water mark". Ideální pro embedded apod. Jinak GC je i žádný úklid paměti, jak se lze (se vší vážností) dočíst na Wikipedii. To jen tak pro usmání. Jinak já taky občas zapomenu napsat "tracing" a píšu jen "GC". Snad si přesto rozumíme.

zboj

  • *****
  • 1 507
    • Zobrazit profil
    • E-mail
Re:Vyplatí se učit C++?
« Odpověď #184 kdy: 31. 12. 2015, 21:10:06 »
No oni klasické GC navíc defragmentují paměť. Je to možné hlavně proto, že mají pod kontrolou všechny pointery. Měl jsem v C++ napsaný jednoduchý GC který dynamicky udržoval kostru v grafech referencí a tedy fungoval i s cykly (spouštěl se, jen když někdo zrušil referenci, která byla označena jako kostra grafu, a tehdy se snažil sestavit novou kostru a uvolnit všechny objekty, které se ocitly z kostry nedosažitelné), ale nepřišlo mi, že by byl rychlejší. Ony to totiž zdržují zejména alokace, tedy hledání volného místa ve fragmentované paměti a dealokace, tedy update tabulky volného místa.

V čistem C++ nejde moc dobře pod rukama programu defragmentovat paměť. Díky existenci raw pointerů nemám jistotu, že s pamětí zrovna někdo nepracuje (a i přes chytré ukazatele se raw pointery používaji, takovým nejtypičtějším raw pointerem je this)
To je sice pravda, ale týká se to jen konzervativních GC. Ty asi nebyly myšleny (protože je jasné, že jsou pomalejší).


zboj

  • *****
  • 1 507
    • Zobrazit profil
    • E-mail
Re:Vyplatí se učit C++?
« Odpověď #185 kdy: 31. 12. 2015, 21:23:17 »
V širším kontextu se ukazuje, že jazyky s VM jsou slepou uličkou vývoje a připravily nás o celou jednu dekádu.
Microsoft už na to asi přišel, protože v jeho novém jazyce Cx pro WinRT je GC nahrazen počítáním referencí, kompiluje se do strojového kódu a hlavní API je stařičký COM.

Počítání referencí bývá obecně pomalejší než tracing GC. Viz třeba Taking Off the Gloves with Reference Counting Immix.

Nicméně Microsoft kromě RyuJITu pracuje i na projektu LLILC (LLVM based MSIL Compiler).
Ten článek je nádherná názorná ukázka, proč nedělat věci složitě, když to jde mnohem jednodušeji. Pro RC připadá v úvahu několik úrovní optimalizace a i bez "deferred RC" a podobných podivností lze dosáhnout téměř úplné eliminace. Což ovšem neznamená, že to tak každá implementace má (např. Swift má co dohánět). Je to hodně low-level magie, ale celkem poučná (když to člověk pochopí).

Radek Miček

Re:Vyplatí se učit C++?
« Odpověď #186 kdy: 31. 12. 2015, 21:25:47 »
Když ale misto naivni implementace RC použiješ nějakou silně optimalizovanou implementaci, a že takový sou, vykon bude stejný, s tím rozdílem že RC bude mít minimální latenci.

V tom článku pochopitelně porovnávají ty nejlepší implementace RC (k roku 2013) a výkon není stejný.

Pokud znáte nějaký novější článek, kde už RC dohnalo tracing kolektory, tak můžete dát odkaz.

zboj

  • *****
  • 1 507
    • Zobrazit profil
    • E-mail
Re:Vyplatí se učit C++?
« Odpověď #187 kdy: 31. 12. 2015, 21:46:16 »
Když ale misto naivni implementace RC použiješ nějakou silně optimalizovanou implementaci, a že takový sou, vykon bude stejný, s tím rozdílem že RC bude mít minimální latenci.

V tom článku pochopitelně porovnávají ty nejlepší implementace RC (k roku 2013) a výkon není stejný.

Pokud znáte nějaký novější článek, kde už RC dohnalo tracing kolektory, tak můžete dát odkaz.
Článek ne, ale zdroják překladače ObjC. Když to shrnu:
1. Dělá se escape analýza a co nezdrhne, jde na stack (Go to tak dělá standardně, čímž dost ulehčuje svému (tracing) kolektoru).
2. Dělá se statická analýza nepotřebných Xrementů (X=ink|dek), ty se vyhodí. Tímto se ušetří nejvíc.
3. Runtime optimalizace na stacku eliminuje Xrementy. Doporučuji vyhledat autoreleaseReturnValue a retainAutoreleasedReturnValue. Tímto se optimalizuje předávání objektů po stacku nahoru (po stacku dolů se triviálně nic aktualizovat nemusí).

Autoři onoho článku trochu zaspali dobu, deferred RC je přes dvacet let stará technika určená pro algebraické datové struktury. A o statické analýze asi nikdy neslyšeli.

Stačí si napsat kód vytvářející hodně objektů v cyklu a něco s nimi dělat. Neoptimalizovaný překlad do LLVM IR má na polovině řádků aktualizaci čítače referencí. To by opravdu zdržovalo (a právě odtud pramení ten nešťastný mýtus, že RC je pomalé). Po optimalizaci nebude aktualizace skoro nikde, jen u přiřazení do nějakého vnějšího objektu, typicky kolekce.

Re:Vyplatí se učit C++?
« Odpověď #188 kdy: 31. 12. 2015, 22:04:04 »
Největší problém reference countingu je obecně sdílení jedné proměnné mezi jádry procesoru. Je třeba používat interlocked increment/decrement. Ve svém kódu jsem to řešil tím, že objekt si eviduje, zda je sdílený mezi vlákny nebo ne, a pokud ne, pak se použije normální přičítání, které je rychlejší. Ale když v tom člověk udělá chybu, pak crash.

Teď testuju jiný způsob, kdy místo počítání referencí loguju to thread-local bufferu seznam všech pointerů, kde se mění reference. Jakmile buffer dojde, vezmu globální zámek, projdu buffer, upravím všechny countery, ty které dosáhnou nuly uvolním, vrátím globální zámek. Totéž se udělá před ukončení threadu. Ale nemám ještě žádné testy. Mělo by to mít výhodu, že evidování referencí si provádí každý vlákno samo, nevýhodu, že uvolnění objektu může dojít mnohem později, jestli vůbec (když při běhu nedojde k naplnění bufferu a thread nikdy neskončí)

zboj

  • *****
  • 1 507
    • Zobrazit profil
    • E-mail
Re:Vyplatí se učit C++?
« Odpověď #189 kdy: 31. 12. 2015, 22:18:52 »
Největší problém reference countingu je obecně sdílení jedné proměnné mezi jádry procesoru. Je třeba používat interlocked increment/decrement. Ve svém kódu jsem to řešil tím, že objekt si eviduje, zda je sdílený mezi vlákny nebo ne, a pokud ne, pak se použije normální přičítání, které je rychlejší. Ale když v tom člověk udělá chybu, pak crash.

Teď testuju jiný způsob, kdy místo počítání referencí loguju to thread-local bufferu seznam všech pointerů, kde se mění reference. Jakmile buffer dojde, vezmu globální zámek, projdu buffer, upravím všechny countery, ty které dosáhnou nuly uvolním, vrátím globální zámek. Totéž se udělá před ukončení threadu. Ale nemám ještě žádné testy. Mělo by to mít výhodu, že evidování referencí si provádí každý vlákno samo, nevýhodu, že uvolnění objektu může dojít mnohem později, jestli vůbec (když při běhu nedojde k naplnění bufferu a thread nikdy neskončí)
To vypadá jako objevení dvou kol. Stařičký NeXTstep měl flag single-/multithreaded. A OpenStep zavedl vláknově lokální autorelease pooly. Obé už je bohužel legacy technology.

Radek Miček

Re:Vyplatí se učit C++?
« Odpověď #190 kdy: 31. 12. 2015, 22:22:48 »
1. Dělá se escape analýza a co nezdrhne, jde na stack (Go to tak dělá standardně, čímž dost ulehčuje svému (tracing) kolektoru).

Tohle JVM běžně dělají, myslím, že i Jikes RVM to umí - tj. očekával bych, že pokud to nevypnuli, tak to dělají.

Citace
2. Dělá se statická analýza nepotřebných Xrementů (X=ink|dek), ty se vyhodí. Tímto se ušetří nejvíc.

Pro haldu toto implementují (říká se tomu update coalescing) a stack vůbec nepočítají.

Re:Vyplatí se učit C++?
« Odpověď #191 kdy: 31. 12. 2015, 22:34:35 »
To vypadá jako objevení dvou kol. Stařičký NeXTstep měl flag single-/multithreaded. A OpenStep zavedl vláknově lokální autorelease pooly. Obé už je bohužel legacy technology.
Vsadim se, že každý mluví o něčem jiném. Jestli ten flag měl per object, pak možná, ale neberu to jako vymýšlení kola, spíš jako řešení problému. Autorelease pool se obávám, že je něco jiného. Log změn referencí si přestav jako dva statické buffery pointerů, do jednoho píšu pointery u kterých se zvýšila reference do druhého u kterých se snížila reference. Jakmile jeden z nich je přeplněn, pak s jedním zámkem aktualizuju všechny reference a buffery resetuju. Mělo by to doufám snížit množství LOCKů sběrnice. Změna reference by měla být stejně rychlá jako singlethread reference counting a přitom MT safe.

PS: nenárokuju si patent, určitě to už někdo vymyslel a používá, já řeším pouze určitý problém

Lama

Re:Vyplatí se učit C++?
« Odpověď #192 kdy: 31. 12. 2015, 22:39:12 »
Teda pánové, to nemáte na Silvestra lepší zábavu? Ale když už, měl bych jen takový lama dotaz. Když je tedy C++ rychlejší než Java, jak na vývoj tak rychlost výsledné apky, jak tu dokazuje Zboj, proč se tedy tak hojně Java používá? Je to tím, že je pro ni více knihoven na vše možné, než pro C++ a tím pádem je vývoj na ni přeci jen rychlejší, nebo je Java jen takový omyl, takové Cimrmanovské "tudy ne, přátelé"? Jinak já mám Javu rád. Neptejte se proč, když máte něco/někoho rádi, nehledejte v tom logiku..

zboj

  • *****
  • 1 507
    • Zobrazit profil
    • E-mail
Re:Vyplatí se učit C++?
« Odpověď #193 kdy: 31. 12. 2015, 22:41:29 »
To vypadá jako objevení dvou kol. Stařičký NeXTstep měl flag single-/multithreaded. A OpenStep zavedl vláknově lokální autorelease pooly. Obé už je bohužel legacy technology.
Vsadim se, že každý mluví o něčem jiném. Jestli ten flag měl per object, pak možná, ale neberu to jako vymýšlení kola, spíš jako řešení problému. Autorelease pool se obávám, že je něco jiného. Log změn referencí si přestav jako dva statické buffery pointerů, do jednoho píšu pointery u kterých se zvýšila reference do druhého u kterých se snížila reference. Jakmile jeden z nich je přeplněn, pak s jedním zámkem aktualizuju všechny reference a buffery resetuju. Mělo by to doufám snížit množství LOCKů sběrnice. Změna reference by měla být stejně rychlá jako singlethread reference counting a přitom MT safe.

PS: nenárokuju si patent, určitě to už někdo vymyslel a používá, já řeším pouze určitý problém
Jasně, není to úplně to samé, autorelease pool je jen pro dekrementy a není to buffer, nýbrž spojový seznam. Ale podobnost není čistě náhodná :)

zboj

  • *****
  • 1 507
    • Zobrazit profil
    • E-mail
Re:Vyplatí se učit C++?
« Odpověď #194 kdy: 31. 12. 2015, 22:43:02 »
Teda pánové, to nemáte na Silvestra lepší zábavu? Ale když už, měl bych jen takový lama dotaz. Když je tedy C++ rychlejší než Java, jak na vývoj tak rychlost výsledné apky, jak tu dokazuje Zboj, proč se tedy tak hojně Java používá? Je to tím, že je pro ni více knihoven na vše možné, než pro C++ a tím pádem je vývoj na ni přeci jen rychlejší, nebo je Java jen takový omyl, takové Cimrmanovské "tudy ne, přátelé"? Jinak já mám Javu rád. Neptejte se proč, když máte něco/někoho rádi, nehledejte v tom logiku..
Všechny jazyky s VM jsou cimrmanovské "tudy ne" ;)