• úvod
  • témata
  • události
  • tržiště
  • diskuze
  • nástěnka
  • přihlásit
    registrace
    ztracené heslo?
    XCHAOSANSI C/C99 (specifikace), GNU C (gcc, glibc), Tiny C (tcc) a POSIX - ne nutně C++,g++,libstdc++ nebo Win32 API
    DAVIDOWITCH
    DAVIDOWITCH --- ---
    XCHAOS: Ja neprogramuju akademicky. Ja delam doktorat. To je dost rozdil (typicky se lisi v tom jestli se bavim s panem ucitelem, nebo s researchem NVIDIA). Kazdopadne, ja sem ti navrhl upresneni terminologie. Rekl sem ti, nekolikrat, ze reference counting je jen a pouze pocitani referenci jakkoliv, a ze automaticke pak maji smartpointery. A pokazde sem se dozvedel ze nemam pravdu. Tak co bys chtel priste navrhovat jako upresneni? Nejakou uplne specialni terminologii, abychom uzavreli ferovy kompromis, kdyz jednoznacne nemas pravdu?
    XCHAOS
    XCHAOS --- ---
    DAVIDOWITCH: tak ano, bude to "manuální escape analysis" - přímo během psaní kódu :-) já si vůbec nehraju na automatickou garbage collection :-)
    XCHAOS
    XCHAOS --- ---
    DAVIDOWITCH: jako programátor momentálně pracuju pouze na free/open source softwareových projektech (resp. ta trocha bastleni pro firmu, kterou stejně spoluvlastním, nestojí za řeč).

    akademické programování asi bude hodně o "hraní se slovíčky", to je pochopitelné.

    a fakt nemyslím, že jsem byl "umlácen argumenty" - víceméně, ano, budu opatrnější než něco řeknu, že "něco v nějakém jazyce nejde" - je tím myšleno "jazyk pro to nemá podporu, muselo by se to v něm vždycky dělat ručně".

    popravdě, ať už je klub odborný nebo poloodborný - přínos takovéhle debaty mi přijde téměř nulový, sorry. lidi, co mají vůli ke spolupráci, a nestojí jen o to honit si ego, by situaci pochopili po prvních několika příspěvcích (za současného navržení upřesnění použité terminologie).

    máš asi opravdu velkou potřebu předvádět, že umíš použít některé termíny přesněji než někdo jiný - to ale fakt není můj problém a fakt to šlo celé pojmout stručněji.
    DAVIDOWITCH
    DAVIDOWITCH --- ---
    XCHAOS: Ale ta konverze bude manualni, ne automaticka (prekladacem, memory alokatorem), right?
    DAVIDOWITCH
    DAVIDOWITCH --- ---
    XCHAOS: No, takhle. Nevim kde pracujes. Tam kde ja (nemecka uni, delam doktorat) je technika hodne moc o "hrani si se slovicky". Protoze pokud se pouziva zavedenej termin spatne, nadela to spoustu paseky. Pouzivat refcount pro smartpointery je ten lepsi pripad. Protoze, v mem oboru, je napriklad opravdu velkej rozdil mezi stochastic progressive photon mapping a probabilistic progressive photon mapping. Prestoze to je v anglictine skoro synonymum.

    A protoze ty tuhle naprosto zasadni zasadu v odbornem klubu (ac svem) neuznavas a kdyz se nekdo zdesi ze pouzivas termin blbe, tak se zacnes hadat, tak si myslim ze ten flamewar za to stal. Byls umlacen k tomu, abys uznal ze refcount je neco jinyho a ze to co chces ty je automaticky reference counting. (A tady zase ustoupim ja, nemusi to bejt nezbytne smart pointer, muzes mit reference treba na disky, a kdyz uz ho nikdo nepotrebuje, tak ho zacnes zalohovat nebo co ja vim.)
    XCHAOS
    XCHAOS --- ---
    jinak ta strategie alokace kterou tu od začátku tlačím (a tedy ta makra remember/forget ) je podle mě blízká tomuhle: http://en.wikipedia.org/wiki/Garbage_collection_%28computer_science%29#Escape_analysis - akorát jsem pochopitelně nevěděl, že se tomu tak říká :-)
    XCHAOS
    XCHAOS --- ---
    DAVIDOWITCH: tedy, víceméně je to to, co jsem tvrdil na začátku, akorát si hrajeme se slovíčky: každý jazyk, ve kterém lze implementovat Turingův stroj samozřejmě umí VŠECHNO co ostatní jazyky, ano :-) akorát se tedy shodneme, že "C nemá nativní podporu pro refcounty", ok ?

    bylo kvůli tomu nutné napsat 50 příspěvků flamwar ?
    XCHAOS
    XCHAOS --- ---
    REDGUY: tak o vzájemné interakci přemýšlet FAKT nemusíš: buď si to alokoval jedním způsobem, nebo druhým

    musíš jen přemýšlet, jestli to za tebe někdo řeší, nebo ne - což ale není o tolik horší situace, než když musíš přemýšlet o všech pointerech: takhle ti zbudou jen jeden-dva speciální případy pointerů, u kterých si musíš pamatovat, že je musíš ručně uvolnit - a ostatní můžeš pustit z hlavy. to mi nepřijde jako že jsi na tom "hůř".

    (a rozhodně si na tom líp, než u té "manuální automatické správy", kdy si po každém přiřazení nové reference musíš ručně udělat další čárku na účet a jinde pak zase musíš ty čárky ručně škrtnout - aby bylo vidět, že už je účet zaplacený :-)
    XCHAOS
    XCHAOS --- ---
    REDGUY: mno taky otázka je, jak moc "automaticky" - zda se ten seznam počítadel prochází při každé alokaci dalšího objektu, nebo jak...

    každopádně z mého hlediska se to označení "automatické" fakt vztahuje na automatické udržování toho počítadla - a jako takové to pokládám za relativně dobrou, i když v případě existence velkého počtu objektů ne nutně extra výkonnou strategii.

    manuálně udržované refcounty budou jistě perfektně fungovat do doby, než programátor někam zapomene nakopírovat to volání inkrementace či dekrementace counteru :-)

    a pořád si myslím, že může nastat situace, kdy hlídat ten počet odkazů manuálně bude přinejmenším nepraktické (co když v nějakém výrazu vznikne objekt odkazující na jiný objekt ?). ale ok, pokud je tedy zvyk, že se tomu tak říká i v případě, že se "automatická" správa paměti používá manuálně, tak jsem fakt asi "prohrál".... každopádně tato "manuální automatická správa paměti" asi zůstane na okraji mého zájmu, co se týče metod správy paměti, bohužel.

    (ale pokud se tady někdo učí programovat v C, kdo sleduje tenhle klub, tak ho jistě potěší, že by tedy po každém vytvoření odkazu na alokovanou paměť měl cosi někde volat, a a pak by místo free(..) měl volat zase cosi jiného... a celé by to pak fungovalo "automaticky"...)
    REDGUY
    REDGUY --- ---
    XCHAOS: no... v takovém případě jsi na tom úplně stejně, jako kdybys ty moje makra neměl - to neni pravda, jsem na tom _hur_, protoze musim kombinovat dva ruzne systemy alokace pameti (malloc/free a tvuj bastl), musim premyslet o jejich vzajemne interakci, zvazovat kdy mam kterej pouzit, v pripade ze nekde budu delat vetsi modifikace kodu hlidat jestli nahodou nemusim prepsat alokaci pameti siroko daleko kvuli zmene logiky - proste vic prace a mnohem vic sanci k chybam.

    zavoláš free() na všechno kromě toho - ty jednotlive kousky pameti se stejne budou za oponou alokovat pres malloc? A stejne tak jednotlive uvolnovat?


    V cem konkretne si myslis, ze je zasadni vyhoda tveho systemu?
    XCHAOS
    XCHAOS --- ---
    JACHYMKO: ano... ale definici dle wiki, tedy "automatic memory management" to potom nesplňuje :-)
    XCHAOS
    XCHAOS --- ---
    REDGUY: no... v takovém případě jsi na tom úplně stejně, jako kdybys ty moje makra neměl :-)

    ale je to pochopitelně dobrý příklad: máš v podstatě dvě možnosti: buď na konci explicitně zahodíš všechny dílčí kusy paměti, co potřebuješ zahodit (tedy: zavoláš free() na všechno kromě toho, co si chceš zapamatovat - tím pádem si ale musíš pamatovat nějaký "seznam všeho, co chceš zapomenout" a nakonci ještě i zahodit tento seznam!) - a nebo můžeš vysloveně okopírovat konkrétní výsledek do jiného memory poolu, který nezahodíš.

    myslím, že se shodneme, že v případě, že zapamatovaný objekt má třeba řádově 10 bajtů a ty ho vybíráš z nějaké dočasné datové struktury o deseti tisíc položkách, tak je "moje strategie" v podstatě výhodná. A naopak - pokud jde o objekt velikosti řádu kilobajtů, a vybíráš ho třeba z deseti položek: tak je ovšem zavolání dealokace deseti položek zřejmě efektivnější, než kopírování kilobajtového objektu do jiného kontextu.

    vymyslet opravdu univerzální řešení podle mě fakt nejde: vždy najdeš nějaký protipříklad, v rámci kterého ta která strategie bude pomalá/neefektivní.

    já jsem uvažoval k tomu svému get(...) udělat ještě alternativu the(...), což by byl v podstatě malloc ("v podstatě" říkám proto, že tam mám nějaké syntaktické vychytávky okolo, které samotný malloc() nemá... ale v podstatě by se na pointery vzniklé pomocí the(....) volalo normálně free(...) - to už ani nemá smysl přejmenovávat :-) a pouze pointery vzniklé pomocí get(...) by se uvolňovaly tím remember/forget mechanismem.

    jako jo - je to asi krkolomné - ale všechno ostatní mě přijde taky krkolomné...
    REDGUY
    REDGUY --- ---
    XCHAOS: Ale prdlajs. To "automatic" se vztahuje na to, ze pamet je automaticky uvolnena kdyz refcount dojede na nulu, ne na to jestli refcount udrzujes automaticky nebo manualne.

    A uz po nekolikate: podivej se na iOS. Tam perfektne funguje to, o cem tvrdis ze neni mozne, memory management zalozeny na manualne udrzovanych refcountech.
    DAVIDOWITCH
    DAVIDOWITCH --- ---
    XCHAOS: Jop, neda se docilit toho, aby se refcount pouzival automaticky. Ccko neumi pouzivat automaticky refcount (respektive, ne defaultne, je nejakej gcc hack co se pouziva tusim na FF kterej nejakou takovou magii dela na urovni prekladu, ale to neni dobrej argument). Neznamena to ze jazyk neumim refcount. Aby neumel refcount, tak by musel mit nejakej zasadni problem s tim ze objekt maze nekdo jinej nez jeho tvurce, nebo tak neco.

    A s tim "syntax sugar" si ted vesmes prohlasil, ze kdo nema garbage collection, neumi refcounty? Chapu to dobre?
    XCHAOS
    XCHAOS --- ---
    Garbage collection (computer science) - Wikipedia, the free encyclopedia
    http://en.wikipedia.org/wiki/Garbage_collection_%28computer_science%29#Reference_counting
    Reference counting is a form of automatic memory management where each object has a count of the number of references to it....

    ... tedy není to "manual memory management", kde by se programátor podíval na nějaký výraz, a zamyslel se nad tím, kterým objektům vzniklým v rámci toho výrazu se asi tak zvýšil počet referencí a pak ručně zavolal nějakou metodu co ten počet zvyšuje. fakt ne.

    (nápověda: na objekt vzniklý v rámci vyhodnocení nějakého výrazu do té doby mohlo odkazovat právě 0 referencí, a přirazením vznikla právě první reference: jak asi v takovém případě reference counting provedete manuálně ? opravdu je "syntaktický cukr" když ten jazyk za vás sám udělá něco, co ani ručně udělat nelze ? :-)
    REDGUY
    REDGUY --- ---
    XCHAOS: Prima. A ted mi prosim vysvetli, jak budes resit nasledujici situaci:

    - funkce postupne buduje nejakou velkou strukturu (pocita, cte z disku, neco takoveho)
    - v okamziku kdy je struktura hotova se vyhodnoti nejaka podminka X, kterou lze spocitat az v okamziku, kdy je hotova cela struktura, ne drive.
    - pokud plati X, vratim vytvorenou strukturu, pokud X neplati, vratim neco jineho (null, jinou strukturu, tak neco)
    XCHAOS
    XCHAOS --- ---
    REDGUY: no vidíš, že se dokážeme konstruktivně bavit a nemusíme si jen nadávat...

    je to prosté, milý Watsone: samotné volání té funkce bylo přece uvnitř nějaké jiné struktury remember { } nebo forget { } - remember prostě jen vloží data "o úroveň výše", forget naopak založí nový, "zahoditelný" kontext. resp. nejvyšší úroveň programu (funkce main(), resp. v terminologii mých syntakticky přeslazených maker makro program { }) je pak logicky ekvivalentní jednom velkému forget{ } (tedy na začátku programu máš k dispozici základní kontext paměti, která se na konci zahodí)

    doufám teď už tušíš, o čem jsem mluvil, když jsem říkal, že "pojmenované paměťové kontexty" by byly něco jako "goto" :-) nic proti ním - ať si někdo používá pojmenované memory pooly, pokud chce - ale mě se to líbí takhle anonymně.

    ve většině případů dočasné pomocné proměnné, do kterých budeš cpát ta "zapomenutelná" data, budeš deklarovat až uvnitř daného jednoprůchodového scope - tedy bude to slušně bezpečné. ale samozřejmě - budeš to moci udělat tak, že budeš mít pořád deklarovaný pointer, který bude ukazovat na v tu chvíli uvolněnou paměť. bude ti to dávat prostor k tomu udělat chybu - bude to pořád Céčko, ne nějaký hypotetický super-hyper-bezpečný jazyk, ve kterém by vůbec neměla existovat reference na již (nebo ještě) nealokovaný kus paměti...
    XCHAOS
    XCHAOS --- ---
    DAVIDOWITCH: já sice chápu, že se o tom dá mluvit obecně, a nikdy jsem neříkal, že ne: ale prohlásit o něčem, že "to v daném jazyce lze použít, ale musí se to dělat ručně" je pro mě naprosto ekvivalentní výroku "v tomto jazyce nelze docílit toho, aby se taková věc prováděla automaticky".

    a fakt trvám na tom, že "syntaktický cukr" je název pro případ, kdy napíšeš "něco navíc" - ne pro případ, kdy ti jazyk umožní něco vůbec nenapsat, protože to dělá za tebe.

    např. moje navržená (a jistě diskutabilní) makra remember { } a forget { } (vymezující nějaké hranice toho, jakým způsobem se bude s alokovanou pamětí dále zacházet, navzájem vnořovatelné, apod.) jsou typickým případem "syntaktického cukru" - je to snaha zapsat srozumitelněji a přehledněji něco, co by se jinak muselo zapisovat dost možná nepřehledně a složitě (minimálně tedy v čistém Céčku, při použití malloc() a free()).

    Ovšem za syntaktický cukr prostě nemůžeš označit, když za tebe runtime udělá sám něco, co ty ani v daném jazyce nemůžeš zapsat jinak :-)
    REDGUY
    REDGUY --- ---
    XCHAOS: Aha. Takze v podstate forget prepne do veskere alokace do kontextu ktery se na konci bloku komplete zahodi a remember je prehodi do bloku kterej se nezahodi. je to tak? Takze prvni otazka: zavolal jsem funkci nejakafunkce, dostal jsem vracena data, zpracoval jsem je, nepotrebuju je. Jak uvolnim jimi zabranou pamet?
    REDGUY
    REDGUY --- ---
    XCHAOS:
    NějakýTyp nějakáfunkce(parametry)
    {
        NějakýTyp returnValue;
        forget
        {
            NěcoDočasného tmp=get(...něco...);
            if(neošetřenNějakýZvláštníPřípad(NěcoDočasného))
            {
                return NULL;
            }
    
        remember
        {
            returnValue=get(...něco...);
            returnValue->NějakáPodstruktura=get(...něco...); 
            atd.
        }
        NěcoJinéhoDočasného tmp2=get(...něco...); 
        atd.
        }
        return returnValue;
    }
    
    Kliknutím sem můžete změnit nastavení reklam