Portál AbcLinuxu, 2. května 2025 17:26
Zásadní roli hraje škodolibost přírody vyjádřená Amdahlovým zákonem. To je naprosto zásadní a se zvětšujícím se počtem jader fatální. Dříve nebo později s tím bude třeba bojovat asymetrickou/hybridní architekturou (pár velmi výkonných jader + stádo slabších jader).Tohle mi nedává smysl. Ty slabší jádra místo menšího počtu silnějších totiž přece pouze zhorší projevy Amdahlova zákona, protože bude třeba zátěž rozložit mezi ještě víc threadů. Takže tomuhle nevěřím, IMHO MT výkon bude pořád lepší s velkými jádry (ale používajícími SMT). BTW se némlich tohle teď zrovna řešilo na RWT. Příšerně velká diskuze a hodně těch diskutujících je IMHO dost mimo (zrovna asi zastánci těch "kurníků" malých jader). https://www.realworldtech.com/forum/?threadid=178719&curpostid=179096 https://www.realworldtech.com/forum/?threadid=178719&curpostid=179094
třeba gcc, spouštění přes make –j N je suboptimální, velmi zvětšuje neparalelizovatelnou část Amdahlova zákona
O jakém počtu procesorů se tu bavíme? Nevšiml jsem si, že by u dostatečně rozsáhlého (a "košatého" projektu s rozumnou organizací Makefiles (což bohužel není automatické, viz třeba LibreOffice) byl problém se škálováním na 64 jader. Tedy aspoň ne při samotném buildu, když chci vyrobit RPM, to už je smutnější příběh.
když chci vyrobit RPM, to už je smutnější příběh.To je asi hlavně vlivem neškálovatelnosti toho kompresního algoritmu, ne?
O jakém počtu procesorů se tu bavíme? Nevšiml jsem si, že by u dostatečně rozsáhlého (a "košatého" projektu s rozumnou organizací Makefiles (což bohužel není automatické, viz třeba LibreOffice) byl problém se škálováním na 64 jader. Tedy aspoň ne při samotném buildu, když chci vyrobit RPM, to už je smutnější příběh.Tak problém může být linkování... U jednoho projektu jsem tohle nedávno zkoušel a zjistil jsem, že 8, 16 nebo 32 jader není moc velký rozdíl, protože tam je několik na sobě závislých linkovacích kroků, které zabírají 80% času...
:-/
Z těch výjimek bych jmenoval Rust a Elixir. Mimochodem, na Rust jsi nedávno hrozně nadával, což mi přijde ironické, vzhledem k tomu, že dobrá podpora paralelizace byl jedním z hlavních motivů pro použití ve FF. No nicméně ty praktické problémy, které to způsobuje, chápu. Na Elixir bych se v ideálním světě už dávno podíval, vypadá pěkně, v reálném světě ale na to bohužel moc nemám čas...
Mimochodem, na Rust jsi nedávno hrozně nadával, což mi přijde ironické
Já jsem nadával na Rust, ale na
Já jsem nadával na Rust, ale na
…nenadával…
Představu, že nějaká nová zázračná Cool Language of the Year bude tou kouzelnou hůlkou, jíž mávnutím zmizí problémy vývoje softwaru vývoje a i mizerní programátoři začnou produkovat efektivní a bezchybný kód.Bylo by přesnější říkat Cool Language of the Decade spíše než Cool Language of the Year vzhledem ke stáří obou jazyků. Oba zmiňované jazyky nejsou žádnou obecnou kouzelnou hůlkou a nikdy nebyly tak prezentovány. Řeší konkrétní poměrně jasně definované problémy. V případě Rustu to je paměťová bezpečnost a race conditions, což, jak si sám můžeš ověřit, opravdu řeší celkem dobře a to řešení je v zásadě na poli programovacích jazyků pomerně nové. Ty myšlenky už samozřejmě existovaly, ale nebyly nikdy předtím implementovány právě tímto způsobem a v kombinaci s dalšími vlastnostmi jazyka, tj. není divu, že X předchozích jazyků to nevyřešilo.
Rozhodnutí vývojářů (nebo spíš manažerů) Firefoxu nechat (stále ještě) tak rozšířenou aplikaci záviset na jazyku, který je v tak syrovém stavu, že se vydává "stable" verze každých šest týdnů. S tím, že se dokonce ani nezafixuje konkrétní verze, ale prostě se bude používat to, co je zrovna nejnovější. Uživatelé a balíkáři ať se v tom vykoupou, co je nám po nich.Chápu tvou frusraci z tohoto plynoucí a souhlasím, že by měli fixovat konkrétní verzi rustc ke konkrétní verzi FF, to je jasné. Chybí mi tam ale informace: Jde ti o ESR verze FF nebo pravidelné verze FF? U těch pravidelných krátkodobých verzí mě nepřijde až tak divný, že se posunují po nejnovějším rustc stable. U ESR bych očekával nějakou jasně danou ne-nejnovější verzi. Jinak pokud máš pocit, že s tím máš težký život, pak nejspíše vůbec nevíš, jakou práci s tím mají vývojáři (ne, opravdu to není rozhodnutí vzešlé od manažerů - jak musí být člověk ignorantský k zúčastněným jazykům, aby si tohle myslel?). Zajímalo by mě totiž, jak by sis představoval lepší řešení. Mně přijde, že v podstatě moc neexistuje. Jasně, můžeš si nový jazyk vyvíjet někde v koutě do šuplíku a čekat 20 let, než bude hotový a perfektně stabilní, nicméně tímhle způsobem status quo nikdy nezměníš, protože jednak nikdo ten tvůj jazyk nebude brát vážně vzhledem k nedostatku praktického nasazení a jednak bez praktického nasazení nemáš šanci nasbírat potřebný feedback pro skutečné dotažení toho jazyka. Nebo jsi ten druh člověka, co chce, aby všichni psali všechno v C/C++ na věky věků? Mně přijde, že psát multi-threaded kód v aktuálním C/C++ je něco jako psát single-threaded kód bez funkcí, jen s
goto
(ačkoli existují pomůcky, které to zlepšují, třeba TBB). Multithreading podporu mají až od verze C11/C++11, což je podle tvé časové osy tak rok zpátky, a stejně to je jen kodifikování existujících používaných primitiv, které považuju za ekvivalent goto
. C++ má dostat transactional memory, ale není to hotový (komise nezvládá) a jsem zvědav, kolik to bude obsahovat footguns, až to hotové bude.
Suma sumárum, z činností stěžování si na nové cool jazyky a stěžování si na programátory nevyužívají dobře vícejádrové stroje bych doporučil si vybrat jednu Chápu tvou frusraci z tohoto plynoucí a souhlasím, že by měli fixovat konkrétní verzi rustc ke konkrétní verzi FF, to je jasné. Chybí mi tam ale informace: Jde ti o ESR verze FF nebo pravidelné verze FF? U těch pravidelných krátkodobých verzí mě nepřijde až tak divný, že se posunují po nejnovějším rustc stable. U ESR bych očekával nějakou jasně danou ne-nejnovější verzi.Mne to tak nejak jasne nie je. Rust vychadza kazdych par tyzdnov ale s garanciou backwards compatibility. Takze nejak nevidim vyznam fixovat na konkretnu verziu pokial idu na rust-stable. Inak mimochodom fixovat na konkretnu verziu sa da, ale realne by som to pouzival iba ak z nejakeho dovodu potrebujes unstable verziu.
Mne to tak nejak jasne nie je. Rust vychadza kazdych par tyzdnov ale s garanciou backwards compatibility. Takze nejak nevidim vyznam fixovat na konkretnu verziu pokial idu na rust-stable.Je zpětně kompatibilní ale ne dopředně. Jde o to, že vývojáři FF chtějí používat funkce z nového stable z různých důvodů (mimo jiné také proto, aby na tyto funkce existoval feedback). Takže když si chceš sestavit nový FF, potřebuješ i (relativně) nový rustc.
Inak mimochodom fixovat na konkretnu verziu sa da, ale realne by som to pouzival iba ak z nejakeho dovodu potrebujes unstable verziu.To je něco jiného, nejde o to, jakou verzi si nastavíš u sebe, ale jakou vyžaduje ta která verze FF.
Takže když si chceš sestavit nový FF, potřebuješ i (relativně) nový rustc.Toto je presne ten problem ktory nechapem. Aky je problem mat aktualny kompiler? cargo ho uplne v pohode aktualizuje za teba.
To je něco jiného, nejde o to, jakou verzi si nastavíš u sebe, ale jakou vyžaduje ta která verze FF.Ale to je presne to na co ten rust-toolchain subor je. Normalne ho commitnes do repozitara a ked nad takym kodom spustis cargo build, cargo sa postara o to, aby kod zostavilo s pozadovanou verziou. Je to per-project nastavenie.
Nic tak nepředstavitelného, jen jsem chtěl pokračovat v tom, co jsem dělal už několik let: jednou za čas si udělat RPM balíček s aktuálním snapshotem z Mercurialu. To je věc, kterou z různých důvodů dělám i s jinými programy a bez problémů to funguje a dokud si nezačali hrát s Rustem, fungovalo to i s firefoxem.
Žádná normální a příčetně vyvíjená aplikace po mně nevyžaduje, abych měl superaktuální toolchain. Ano, jsou programy, které nejdou přeložit s gcc 4.8 a musím použít třeba gcc6, ale abych musel aktualizovat gcc nebo binutils každých pár týdnů, to nehrozí. To přišlo až s těmito módními jazyky, které obcházejí a/nebo sabotují distribuční package management.
Ale budiž, řekl jsem si, že si holt vždycky zabalím i aktuální snapshot rustu, ať je nějaká zábava. A tam jsem narazil podruhé, protože defaultní gcc v distribuci je 4.8 a Rust vyžadoval aspoň verzi 5. Za normálních okolností to není problém, v distribuci byly i balíčky s gcc6 a možná i gcc7. Ale ouha, Rust ignoruje (nebo tehdy aspoň ignoroval) proměnnou CC a bez nějaké hlubší inspekce jsem nenašel (a ani v dokumentaci nebyl popsán) způsob, jak ho donutit, aby vzal na vědomí, že má jako překladač použít "gcc-6
".
Mezitím se začaly objevovat zvěsti o blížícím se Firefoxu 57 a přechodu na WebExtensions only model, takže jsem se na to vykašlal úplně, protože sledovat další vývoj Firefoxu už pro mne ztratilo smysl.
Ale podle mne je už ta samotná myšlenka naprosto pochybná. S toolchainem, který mám v openSUSE 42.3, bez problémů přeložím nejnovější jádro z gitu, nejnovější glibc, LibreOffice a tisíce dalších projektů, včetně takových, které si velikostí a komplexitou s Firefoxem nijak nezadají. Stejně tak to šlo i s Firefoxem, dokud se nevrhli do toho rustového dobrodružství. Bohužel zrovna Firefox je navíc jeden z mála, kde se moc nedá uplatňovat tradiční distribuční model, kdy se backportují jen opravy; sice existuje ESR, ale jeho lifetime je většinou kratší, než by bylo pro distribuci potřeba.
Rust je ale este stale mlady projekt a nema celkom zmysel brzdit vyvoj viazanim sa na nejake LTS verzie, to pride casom.
A právě proto jsem hned na začátku vlákna zdůraznil, že mi nevadí Rust jako takový, ale (v tomto kontextu) především rozhodnutí týmu kolem Firefoxu nechat jejich projekt záviset na jazyku, který je v takovém stavu. Firefox už totiž dávno není "ještě mladý projekt". Je to prohlížeč, který je tady už 14-15 let, je stále jeden z nejpoužívanějších a není to tak dávno, co byl úplně nejpoužívanějším.
A právě proto jsem hned na začátku vlákna zdůraznil, že mi nevadí Rust jako takový, ale (v tomto kontextu) především rozhodnutí týmu kolem Firefoxu nechat jejich projekt záviset na jazyku, který je v takovém stavu.No jo, ale co teda měli podle tebe udělat? Věděli, že svůj nový jazyk chtějí nasadit a využít. V podstatě věděli, že když ho nenasadí hned nebo v blízké době, ztíží to vývoj jazyka a zvýší rizko neúspěchu, což by znamenalo jednak zmařenou investici a také nutnost pokračovat ve vývoji v C++ s problémy, které to přináší. Mohli FF forknout, nicméně jak by se to lišilo od aktuální situace? IMHO v podstatě nijak.
Vy pořád stavíte na axiomu, že vývoj něčeho takového v C++ není principiálně možný a že Rust je ta spása, která to celé zachrání a jako bonus vyřeší sucho, hladomor v Africe a zajistí světový mír. Už několikrát jsem napsal, že s tou představou nesouhlasím. Nemyslím si, že C++ je pro daný účel nepoužitelné a stejně tak si nemyslím, že Rust je tak geniální, že v něm ti samí programátoři budou najednou psát o třídu lepší kód.
Takže se prostě nemůžeme shodnout. Vy vycházíte z premisy, že přechod na Rust byl absolutní nutnost a všechny problémy, které to přineslo, byly nevyhnutelné. Já tento předpoklad nesdílím a rozhodnutí přepsat podstatnou část projektu do jazyka v tomto stavu vývoje považuji za hrubou chybu.
Vy pořád stavíte na axiomu, že vývoj něčeho takového v C++ není principiálně možný a že Rust je ta spása, která to celé zachrání a jako bonus vyřeší sucho, hladomor v Africe a zajistí světový mír. Už několikrát jsem napsal, že s tou představou nesouhlasím.To je především tvoje představa a s mým názorem nemá moc společného. O C++ jsem nikdy neřekl, že v něm není "principiálně možné" tyhle věci psát (jsem vývojář v C++ a MT věci také píšu), napsal jsem pouze, že to je za trest, za čímž si stojím. O Rustu jsem napsal dva konkrétní problémy, které řeším nic víc, nic míň. Jestli se ti to nezdá, napiš, který konkrétní problém podle tebe neřeší a konkrétně proč. Případně kdo konkrétně někde tvrdí, že údajně řeší i nějaký jiný problém*. Mávat rukama o spáse a hladomoru v Africe je zceal o ničem. *) Což se občas skutečně stává, semtam má někdo pocit, že kromě race conditions řeší i deadlocky, což není pravda.
Já tento předpoklad nesdílím a rozhodnutí přepsat podstatnou část projektu do jazyka v tomto stavu vývoje považuji za hrubou chybu.A můžu se zeptat, v čem přesně se ta hrubá chyba projevuje? Je to v tom, že FF má teď CSS engine, který je rychlý, paralelní a se staticky prokázanou absencí race conditions a buffer overruns? Jestli se takhle projevuje hrubá chyba, pak prosím více hrubých chyb ve vývoji software.
A můžu se zeptat, v čem přesně se ta hrubá chyba projevuje?
Můžete, ale vzhledem k tomu, že už jsem to dost podrobně rozepsal (a ne jednou), nemám v úmyslu to opakovat. Pokud ty problémy nevidíte nebo považujete za zanedbatelné, s tím nic nenadělám.
A můžu se zeptat, v čem přesně se ta hrubá chyba projevuje?Na to ti rad odpovim. Rozhodl jsem se zkusit Arch Linux, protoze Debian je pry co se tyce desktopu sto let za vopicema. Tedy, ze obsahuje prilis stare verze programu, ktere jsou, jak kazdej dneska vi, rozbite a zabugovane. Tudiz je potreba pouzivat co nejcerstvjejsi. Dalsi aspekt Archu, ktery by asi bylo dobre zminit je, ze se snazi v balickach programy moc nemodifikovat. No doslo i na browser, a zkusil jsem ten uzasny Firefox napsany v uzasnem Rustu a s uzasne paralelizovanym CSS. Vysledkem tehle uzasne kombinace bylo, ze neslo mit soucasne pusteny video na YT a zaroven si prohlizet 3D GoogleMaps. Rikal jsem, ze je to problem nekde v 3D akceleraci ci v cem, jenze Chromium to davalo uplne v pohode. V Ubuntu to kupodivu take funguje. Vysledkem vsech tech uzasnych technologii tedy bylo akorat opusteni Firefoxu. To ze to v Ubuntu funguje, pak ukazuje akorat na to, ze tu hromadu uzasnejch zrezlejch sracek musi dokopat do pouzitelnyho stavu nebozi maintaineri z jednotlivych distribuci. Ono o dokonalosti Rustu by spis lidi presvedcilo to, ze by vubec nevedeli, ze v nem je FF napsanej. Jinak predstava, jak je cool stale updatovat toolchain. K tomu muzu snad jen tolik, ze vzhledem k tomu, ze si prubezne prochazim spravou ruznych cross-enviromentu: Nasrat! Prakticky to znamena, ze si ke kazde aplikaci v Rustu budes muset drzet i toolchain, kterym jsi ji prelozil. Mladi nadsenci muzou slibovat co chtej, ale na pohadky o backwards compatability a o tom, jak se nic nerozbiji jsem uz starej.
Ale je fakt, ze Mozilla 2x zlyhala, ked sa pokusila paralelizovat css system v C++.V cem meli problem? Pokud to jde paralelizovat v Rust, jde to i C++, takze je spise problem na strane jejich programatoru.
takze je spise problem na strane jejich programatoruPresne tak. Problem bol, ze to za 7 rokov nedokazal nikto v C++ napisat. SAMOZREJME ze sa to da, ale prakticky to nikto nedokazal. Na rozdiel od Rustu s ktorym je to uz skoro rok v produkcnom nasadeni.
To je věc, kterou z různých důvodů dělám i s jinými programy a bez problémů to funguje a dokud si nezačali hrát s Rustem, fungovalo to i s firefoxem.Přijde mi, že to je celkem běžný problém s distribucí. Čerstvé nové verze programů mají čerstvé nové dependence, včetně build-time dependencí, které konzervativní distribuce nemusí nabízet. Nevidím na tom celkem nic Firefox- nebo Rust- specifického, toolchain je prostě jen další build-time dependence. Je to celkem běžný problém, na který narážim občas na konzervativních distribucích taky (v mém případě hlavně Debian) u všelijakého softwaru. Balíčkovací systém konzervativní distribuce není určtěný k tomuhle účelu. Proto se to řeší mimo balíčkovací systém, anebo se použije distribuce, kde na to balíčkovací systém určený je (Arch, Gentoo, ...).
A tam jsem narazil podruhé, protože defaultní gcc v distribuci je 4.8 a Rust vyžadoval aspoň verzi 5.To je divné, deklarovaná verze potřebná rustem je gcc 4.7.
Ale ouha, Rust ignoruje (nebo tehdy aspoň ignoroval) proměnnou CC a bez nějaké hlubší inspekce jsem nenašel (a ani v dokumentaci nebyl popsán) způsob, jak ho donutit, aby vzal na vědomí, že má jako překladač použít "gcc-6
".
To mi zní, jako že to dost možná vůbec nebyl problém s kompilací, ale s linkováním. rustc build zahrnuje minimum C kódu (když už tak spíš C++ kvůli LLVM). Zato ale používá by-default na Linuxu gcc na linkování.
Já jsem na podobný problém narazil při cross-kompilaci programu v rustu pro arm, bylo potřeba nastavit správnou verzi gcc jako linker, nikoli jako kompilátor C.
Čerstvé nové verze programů mají čerstvé nové dependence, včetně build-time dependencí, které konzervativní distribuce nemusí nabízet.
Vidím zcela zásadní rozdíl mezi závislostí na nějaké knihovně (pokud to zrovna není něco jako glibc) a závislostí na pár týdnů staré verzi toolchainu. Toolchain v distribuci rozhodně nechcete mít jako moving target.
K tomu ostatnímu: prostě tam ten problém byl a rozhodně nešel nějak snadno vyřešit. Teď už je to stejně jedno, protože je pro mne Firefox mrtvý i z jiných důvodů (WebExtensions), takže balit jeho snapshoty už stejně nebudu potřebovat.
Toolchain v distribuci rozhodně nechcete mít jako moving target.Ano, ale jediný, kdo se ho tam snažil nacpat, jsi byl ty. Já tomu popravdě nerozumim, proč jsi se o to snažil. Ta závislost se vázala, jestli tomu dobře rozumím, na krátkodobou, nikoli ESR, verzi Firefoxu, kterej sis sestavoval nad rámec toho, co nabízela tvá distribuce. Čiliže do té distribuce by především v první řadě nemohl přijít ten Firefox jako takový vzhledem k jeho jepičí době podpory, o toolchainu, který vyžaduje, vůbec nemluvě.
K tomu ostatnímu: prostě tam ten problém byl a rozhodně nešel nějak snadno vyřešit.No jasně. Chyba je prostě vždycky v někom jiném.
Jak už jsem napsal, Firefox je bohužel projekt, u kterého pro distribuci s ESR verzí nevystačíte. Takže vám i u distribučního balíčku nezbývá než přecházet na nové verze. Věřte nebo ne, maintainer Firefoxu v openSUSE před časem zmiňoval přesně tytéž problémy, na které jsem narážel já - jen na ně s tím distribučním balíčkem narážel o něco málo později. Takže to není jen nějaký můj výmysl.
No jasně. Chyba je prostě vždycky v někom jiném.
Tohle nemám zapotřebí. Pokud si nejste schopen nebo ochoten zachovat aspoň nějakou elementární úroveň, bude lepší, když se o tom nebudeme bavit vůbec.
Takže vám i u distribučního balíčku nezbývá než přecházet na nové verze.Ok, jestliže tedy máš takový požadavek, proč je tak divné přecházet i na nové verze toho toolchainu? Případně distribuovat Firefox bez toho toolchainu? (AFAIK tam není runtime závislost, ale můžu se mýlit.)
Věřte nebo ne, maintainer Firefoxu v openSUSE před časem zmiňoval přesně tytéž problémy, na které jsem narážel já - jen na ně s tím distribučním balíčkem narážel o něco málo později. Takže to není jen nějaký můj výmysl.Nikdy jsem si nemyslel, že by to měl být výmysl. Věřím, že jste s tím měli problémy. Taky jsem párkrát kompiloval rustc včetně (pokusy o) cross kompilace na sparc a arm, vím, že to nemusí být úplně triviální. Mám dojem, že v té první diskusi, kde jsme se o tom bavili, jsem i nabídl pomoc s tím problémem. Mně pouze vadil ten závěr "mně se to tehdá nepovedlo => nemělo to řešení". Ten maintainer to zřejmě vyřešil, ne?
Tohle nemám zapotřebí. Pokud si nejste schopen nebo ochoten zachovat aspoň nějakou elementární úroveň, bude lepší, když se o tom nebudeme bavit vůbec.Snažím se si ji zachovat i přes tvou obecnou agresi vůči vývojářům a snahu nacpat mi opakovaně směšné názory, které nemám.
Ok, jestliže tedy máš takový požadavek, proč je tak divné přecházet i na nové verze toho toolchainu?
Protože toolchain se používá na všechny balíčky a upgrade toolchainu nezřídka znamená nekompatibilitu ABI. Třeba v (rolling) Tumbleweedu je přechod na novou verzi gcc věc, která se řeší měsíce ve staging projektech. A i tak jsou s tím potom často problémy.
Jediné štěstí je, že toho v Rustu napsaného moc není. Pokud by se tak jako Firefox zachovalo víc projektů (nebo dokonce nezanedbatelná část distribuce), byla by to katastrofa.
Ten maintainer to zřejmě vyřešil, ne?
Co se týká openSUSE 42.3, tak vlastně spíš odložil tím, že přešel na ESR 52. Ale to je jen dočasné řešení a jak to bude dál, to je ve hvězdách.
Protože toolchain se používá na všechny balíčky a upgrade toolchainu nezřídka znamená nekompatibilitu ABI. Třeba v (rolling) Tumbleweedu je přechod na novou verzi gcc věc, která se řeší měsíce ve staging projektech. A i tak jsou s tím potom často problémy. Jediné štěstí je, že toho v Rustu napsaného moc není. Pokud by se tak jako Firefox zachovalo víc projektů (nebo dokonce nezanedbatelná část distribuce), byla by to katastrofa.Problémy s upgradem gcc/libc jsem už taky měl. Nepochopil jsem ale, proč/jak se mají aplikovat na Rust. Jak to spolu souvisí? Vždyť to jsou jiné jazyky jejichž building funguje jinak. Pokud vím, Firefox na rust toolchainu po buildu nezávisí (protože statická kompilace). Mám v systému nainstalovaný FF a nějaké další programy v Rustu, nemám globálně nainstalovaný žádný toolchain, problémy nepozoruju.
Co se týká openSUSE 42.3, tak vlastně spíš odložil tím, že přešel na ESR 52. Ale to je jen dočasné řešení a jak to bude dál, to je ve hvězdách.Při pohledu do balíčků na webu openSUSE vidím ve verzi 42 rust 1.24 a v Tumbleweed rust 1.26. Podle Mozilla Rust Update Policy for Firefox pro aktuální verzi FF 61 je potřeba rust 1.24. Možná jsem retardovaná místní verbež, ale zatím tu Katastrofu a Hrubou Chybu opravdu nechápu...
Problémy s upgradem gcc/libc jsem už taky měl. Nepochopil jsem ale, proč/jak se mají aplikovat na Rust.
Jak říkám, dokud je takový balíček jeden, tak se to nakonec nějak zaonačit dá. Vy ale tady tvrdíte, že psát multithreadové aplikace v C++ (nebo dokonce C) je - cituji - "za trest" a nepřímo naznačujete, že jediná rozumná cesta je přejít na Rust nebo něco podobného. Jiní šli ještě dál, takže jsem se tu dočetl i že "…ma Firefox nejaku nadej na buducnost prave vdaka Rustu" (jinak řečeno, kdyby zůstal u C++, neměl by ji). Vzhledem k tomu je IMHO naprosto na místě zamyslet se nad tím, jaká radost by byla udržovat distribuci, kdyby v Rustu nebyl jeden balíček, ale nezanedbatelná část distribuce. Naštěstí to v dohledné době nehrozí a já osobně doufám, že ani v delším časovém horizontu - přinejmenším do doby, než se Rust "uklidní".
Při pohledu do balíčků na webu openSUSE vidím ve verzi 42 rust 1.24 a v Tumbleweed rust 1.26. Podle Mozilla Rust Update Policy for Firefox pro aktuální verzi FF 61 je potřeba rust 1.24.
Tak se podívejte také sem, jaká verze byla ve 42.3 před rokem, kdy vyšla. Já tam vidím 1.17, která by na ten dnešní Firefox ani zdaleka nestačila. Zkuste hádat, proč je tam asi dnes 1.24.
Oproti tomu defaultní gcc v době vydání bylo 4.8.5 a je tam pořád 4.8.5 a s největší pravděpodobností to tak zůstane, dokud 42.3 neskončí podpora; pokud by se to náhodou změnilo, bude to na nějakou další 4.8.x. A dokonce i v původním SLE12 GA vydaném v říjnu 2014 (Leap 42.3 je založen na SLE12 SP3) byste našel gcc 4.8.3.
A to je právě to, o čem celou dobu mluvím. Kdyby se všichni zbláznili a začali hromadně přecházet na Rust (a ještě pokud možno co nejnovější verzi), myslíte, že by bylo možné takhle bezhlavě upgradovat překladač, kterým se překládá nezanedbatelná část distribuce? (Mimochodem, ten komentář, na který vede link, považuji za jednu z nejděsivějších věci, jaké jsem kdy v mozillí bugzille četl - a to už ve zločineckých kruzích něco znamená. Zbytek toho bugu není o moc lepší.)
Asi nemá smysl opakovat pořád dokola diskuse, které už několikrát proběhly, zvlášť když je to tu zcela off-topic. Vy si stejně budete stát na svém, že Rust je tak skvěle navržen, že je s ním multithreadové programování mnohem jednodušší, efektivnější a bezpečnější. Já si podržím svůj skeptický názor, že takových jazyků, které díky geniálním změnám přístupu měly úžasně řešit zásadní problémy programování, už jsem viděl tolik, že nevidím jediný důvod, proč by to zrovna tentokrát měla být (poprvé) pravda. A uzavřu to Rumcajsovým "Však ono se ještě uvidí." (Zkušenost ovšem napovídá, že až se uvidí, věrozvěstové nových pořádků už stejně budou mít zase nějakého nového koně.)
Jak říkám, dokud je takový balíček jeden, tak se to nakonec nějak zaonačit dá.Jak říkám já, mám těch programů v systému několik a problémy nepozoruju. V čem by to podle tebe bylo jiné od té situace s FF? Pokud by bylo víc takových programů jako FF, zjistilo by se, který z nich vyžaduje nejnovější rustc a tato verze by se použila, jelikož by byla schopna sestavit všechny ty prorgamy. V čem je problém?
Vy ale tady tvrdíte, že psát multithreadové aplikace v C++ (nebo dokonce C) je - cituji - "za trest"Ano, myslím si to. Je to zakázaná myšlenka?
a nepřímo naznačujete, že jediná rozumná cesta je přejít na Rust nebo něco podobnéhoTo se uvidí. Rust je jedna z možností. Další možnost je, že se třeba C++ komise vzpamatuje, bylo by to fajn, ale bohužel to na to aktuálně nevypadá...
Tak se podívejte také sem, jaká verze byla ve 42.3 před rokem, kdy vyšla. Já tam vidím 1.17, která by na ten dnešní Firefox ani zdaleka nestačila. Zkuste hádat, proč je tam asi dnes 1.24.Protože pro Firefox aplikují rolling release postup? Jestli tomu dobře rozumim, tak v té verzi před rokem byl FF sestavitelný tou verzí rustu, která tam byla...
A to je právě to, o čem celou dobu mluvím. Kdyby se všichni zbláznili a začali hromadně přecházet na Rust (a ještě pokud možno co nejnovější verzi), myslíte, že by bylo možné takhle bezhlavě upgradovat překladač, kterým se překládá nezanedbatelná část distribuce?To je dosti fantastická představa, není v sílách už jen vývojářů něco takového udělat v krátkém čase. A pokud by se to skutečně mělo stát, musel by na to být nějaký postup, v rámci něhož by se ty případné problémy řešily. Já mám někdy pocit, že lidi zapomínají, kolik problému bylo po dlouhá léta s C/C++. Jako kdyby C/C++ byl dar od primordiálních bytostí, který je dokonalý, neměnný, byl tu s námi byl vždycky a bude i nadále na věky věků. Přitom stabilně a relativně dobře to funguje teprve relativně (ke stáří jazyka) krátkou dobu a pouze díky úsilí množství lidí, kteří řeší ty problémy. Jak se říká, Řím taky nepostavili za den.
Vy si stejně budete stát na svém, že Rust je tak skvěle navržen, že je s ním multithreadové programování mnohem jednodušší, efektivnější a bezpečnější.Ano, ale to má svůj technický důvod. Ten jazyk je specificky navržen s tím záměrem být vhodný pro bezpečné MT programování. Jestliže jazyk staticky garantuje absenci race conditions, pak celkem oprávněně můžeme říct, že je jednodušší, efektivnější a bezpečnější pro MT programování v porovnání s jazykem bez těchto garancí, nesnad? Zejména v kombinaci s dalšími vlastnostmi, které tomu pomáhají, jako paměťová bezpečnost a move semantics (skutečná podpora move semantics, ne jako v C++, kde máš pouze r-value references a zbytek, včetně bezpečnosti/korektnosti, si musí vyřešit programátor ručně). Čiliže tady nejde ani tak o nějakou víru nebo přesvědčení o novém cool jazyce (jak si asi myslíš), ale o konkrétní technické vlastnosti, které byly do toho jazyke specificky s tímto účelem implementovány. FTR: Jsou věci na Rustu, které se mi nelíbí, některé vlastnosti považuju za špatné nebo nedotažené, ale to výše zmiňované a zrovna specificky ten usecase ve FF mi přijdou jako poměrně velmi slušný technický výdobytek. Jinak byly i situace (např. v zaměstnání), kdy třeba i někdo jiný navrhl Rust a já byl (po nějaké evaluaci) pro to zůstat u C/C++, protože na daném usecase prostě ty výhody nepřevážily nevýhody. Ty MT aspekty mi přijdou v této diskusi on-topic.
Já si podržím svůj skeptický názorTo není skeptický názor, to je úplně normální FUD. Za celou dobu jsem od tebe nezaznamenal jediný skutečně technický argument, pouze samé mávání rukama, "katastrofy", "hrubé chyby", zcela zbytečné posměšky a tak dále, z 90% čirý FUD. Doteď jsme se nedobrali toho, v čem byl ten tvůj problém se sestavováním rustc ("prostě to nešlo"), v čem je problém v openSUSE (pokud vim, tak tam žádný není) a nebo v čem je ta "hrubá chyba", atd. Proto pokračuju v diskusi, chovám naději, že třeba se třeba k nějakým technickým důvodům jednou dostanem...
Celý váš příspěvek v podstatě jen potvrzuje marnost této diskuse, takže doplním jen jeden detail, který jsem asi nevysvětlil dost jasně:
Ten jazyk je specificky navržen s tím záměrem být vhodný pro bezpečné MT programování. Jestliže jazyk staticky garantuje absenci race conditions, pak celkem oprávněně můžeme říct, že je jednodušší, efektivnější a bezpečnější pro MT programování v porovnání s jazykem bez těchto garancí, nesnad?
Právě že ne nutně. Protože v reálném světě nic není zadarmo. Takže návrh jazyka sice může vylučovat jeden izolovaný problém (nebo několik), ale druhá strana mince je, že je to za cenu omezení, která znemožní použití určitých konstrukcí a postupů, která v C nebo C++ použít můžu. Takže nakonec kvůli obcházení těch omezení může být programování méně komfortní (a je příliš laciné mávnout rukou, že je to chyba zkostnatělých vývojářů neochotných opustit přežitá schémata) a výsledný kód neefektivní. Jsou samozřejmě situace, kdy ani jedno nevadí (nebo nevadí dost), ale pohled "řeší to tohle a tohle, takže je to pro multithreadové programování automaticky vhodnější" je příliš jednostranný.
Vzpomínám si třeba, jak dopadl projekt NTS (nástupce TeXu), který (podle tvrzení samotných vývojářů) z velké části zabilo rozhodnutí použít Javu. Ta byla sice byla teoreticky skvělá, protože návrh řešil některé problémy starších jazyků, ale právě ta praktická omezení a nutnost vtěsnat se do povolených škatulek se ukázaly zcela zásadním problémem. Nakonec se jim to sice podařilo dotáhnout do stavu, kdy dělá co má (nebo spíš co na začátku chtěli), ale výsledek je příliš neefektivní na to, aby šel použít v praxi.
Jak už jsem napsal, za těch ~30 let jsem o mnoha jazycích slyšel, jak jsou úžasně navržené a jak řeší ty či ony problémy. Jediný z nich, který se skutečně dočkal vážnějšího rozšíření, byla Java a ani ta zdaleka neovládla svět způsobem, jaký jí byl předpovídán. Klidně si tomu říkejte FUD (a klidně si mne i zároveň jedním dechem obviňujte z posměšků, když vám ta ironie uniká), já tomu budu říkat zdravý skepticismus a v klidu si počkám, jak to dopadne s Rustem.
Takže návrh jazyka sice může vylučovat jeden izolovaný problém (nebo několik), ale druhá strana mince je, že je to za cenu omezení, která znemožní použití určitých konstrukcí a postupů, která v C nebo C++ použít můžu.Prave pre tieto pripady mas k dispozicii
unsafe
.
Právě že ne nutně. Protože v reálném světě nic není zadarmo. Takže návrh jazyka sice může vylučovat jeden izolovaný problém (nebo několik), ale druhá strana mince je, že je to za cenu omezení, která znemožní použití určitých konstrukcí a postupů, která v C nebo C++ použít můžu. Takže nakonec kvůli obcházení těch omezení může být programování méně komfortní (a je příliš laciné mávnout rukou, že je to chyba zkostnatělých vývojářů neochotných opustit přežitá schémata) a výsledný kód neefektivní. Jsou samozřejmě situace, kdy ani jedno nevadí (nebo nevadí dost), ale pohled "řeší to tohle a tohle, takže je to pro multithreadové programování automaticky vhodnější" je příliš jednostranný.S tím souhlasím na obecné úrovni. V téhle diskusi jde o rozdílnost přístupu, kde já jsem se k tomu dostal zájmově, mám s tím jazykem >5 let zkušeností + vím o mnoha zkušenostech komunity, viděl jsem např. benchmarky atd., tj. tyhle úvahy, které zmiňuješ, už do značné míry existují, není to úplně na začátku. Takže se cítím v zásadě kvalifikován vyhodnotit, že např. pro ten FF je ta cena za ty garance poměrně velmi nízká. Chápu ale, že zřejmé "navenek" to není. Kdežto ty ses k tomu dostal z pozice "debilní manažeři mozilly se mi snaží vnutit nějaký nový cool jazyk". O těch případných limitacích se klidně můžeme nějak bavit, pokud by tě to zajímalo (hádám ale, že spíš ne). Ta cena obecně není vysoká, ale jak říkám, záleží na použití a měl jsem případy, kdy použití Rustu bylo nevhodné oproti C. Komfort programování v Rustu mi přijde obecně v porovnání s C/C++ vysoký, je ale celkem těžké tohle nějak kvantifikovat/konkretizovat, protože to je do značné míry subjektivní. Porovnání s Javou není moc na místě, Java je jazyk běžící ve VM a má GC, má o hodně jiné zaměření, čili to je hodně něco jiného. Rust nemá ani zdaleka tak vysoké nároky, runtime charakteristika je podobná C++. S Javou je IMHO na místě porovnávat spíše Go.
Klidně si tomu říkejte FUDTomuhle příspěvku FUD neříkám, ten je rozumný. Škoda, že až ve chvíli, kdy jsme oba diskusí znechuceni...
v klidu si počkám, jak to dopadne s RustemTo my všichni. Jde o to, jak jsem se snažil vysvětlit, že má-li to dopadnout jinak než negativně, pak ty reálný nasazení, kde je možné nasbírat nějaký praktický zkušnosti, prostě jsou potřeba...
Další možnost je, že se třeba C++ komise vzpamatuje, bylo by to fajn, ale bohužel to na to aktuálně nevypadá...Uvidime. Je dost mozne ze nakonec budeme mit restriktivni subset C++, ktery bude schopen pres kompilator vynucovat pouziti bezpecnych konstrukci a bez UB.
pak celkem oprávněně můžeme říct, že je jednodušší, efektivnější a bezpečnější pro MT programování v porovnání s jazykem bez těchto garancí, nesnad?Nemuzem. Jazyk je jedna cast rovnice a Rust prinasi celou radu restrikci, ktere programovani nezjednodusuji, zejmena kdyz v tom nelze nekostrbate snadno psat ani tak zakladni veci jako je linked list.
Uvidime. Je dost mozne ze nakonec budeme mit restriktivni subset C++, ktery bude schopen pres kompilator vynucovat pouziti bezpecnych konstrukci a bez UB.To jsem zvědav, vzhledem k tomu, že bohužel i v moderním C++ je velmi snadné narazit na paměťovou nebezpečnost. Jeden z mých "oblíbených" problémů je např. invalidace iterátorů. Úplně nevidím, jak by se něco takového udělalo jinak než postupem podobným Rustu...
Nemuzem. Jazyk je jedna cast rovnice a Rust prinasi celou radu restrikci, ktere programovani nezjednodusuji, zejmena kdyz v tom nelze nekostrbate snadno psat ani tak zakladni veci jako je linked list.
Jinak linked list pro praktické použití by se nesjspíše stejně jako jiné základní datové struktury implenetoval s pomocí unsafe, tak je to naimplementováno i ve standardní knihovně.No prave. Pokud je v Rustu nejjednodussi k efektivni implementaci zakladnich datovych struktur zahodit podstatne bezpecnostni featury se kterymi se kazdy rustard chlubi a jit do unsafe modu, tak to popira jak jednoduchost, tak castecne i bezpecnost, protoze v praxi se vam na to programatori vykaslou a rovnou pujdou do unsafe modu.
v praxi se vam na to programatori vykaslou a rovnou pujdou do unsafe moduV praxi aktuálně to je tak, že unsafe kódu obsahuje většina populárních knihoven minum, obvykle čím populárnější knihovna, tím větší tlak na minimalizaci unsafe kódu ze strany komunity...
Představu, že nějaká nová zázračná Cool Language of the Year bude tou kouzelnou hůlkou, jíž mávnutím zmizí problémy vývoje softwaru vývoje a i mizerní programátoři začnou produkovat efektivní a bezchybný kód.Tohle je spise zalezitost poloblaznive fanboy komunity, ktera se vytvorila kolem Rustu a ktera vedla ke vzniku zkratek jako RIIR (Rewrite It In Rust), RESF (Rust Evangelism Strike Force) ci rustjerk. Zatim nejvokalnejsi zastanci Rust, ktere jsem potkal, byli spise mizerni programatori C/C++, kteri z chyb obvinovali "zastaraly" programovaci jazyk. Rust umoznuje nekterou kategorii problemu resit lepe, nektere casti navrhu jsou celkem elegantni, nicmene to neni panacea resici vetsinu problemu parallelniho programovani a Rust je na dobre ceste k podobnemu molochu jakym je C++, jen bez srovnatelneho mnozstvi produkcniho kodu, schopnych rogramatoru a dotazenych nastroju.
Rozhodnutí vývojářů (nebo spíš manažerů) Firefoxu nechat (stále ještě) tak rozšířenou aplikaci záviset na jazyku, který je v tak syrovém stavu, že se vydává "stable" verze každých šest týdnů. S tím, že se dokonce ani nezafixuje konkrétní verze, ale prostě se bude používat to, co je zrovna nejnovější. Uživatelé a balíkáři ať se v tom vykoupou, co je nám po nich.To bych podepsal. Skutecnost, ze pro kompilaci tak dulezite komponenty je potreba pouzivat nestabilni jazyk s efektivne rolling releasy byla pro me jedna z poslednich kapek, po ktere jsem po letech linii Firefox/Mozilla/Netscape opustil.
Otazka je, zda-li vubec existuje nejaky uspesny jazyk, ktery je postaveny na idealech.Ok, asi budu té otázky litovat, ale na jakých ideálech je postavený rust? Mě napadá jen "fearless concurrency", což je nicméně jeden z těch debilních meme vzniklých až celkem dlouhou dobu po návrhu jazyka...
Pak by mel ale skutecne poskytovat "fearless concurrency""fearless concurrency" je kravina, PR meme. Co skutečně poskytuje/neposkytuje už bylo řečeno.
a neprinaset jine problemy.Já jsem u toho tvého problému s FF nepochopil souvislost s rustem.
Zatim nejvokalnejsi zastanci Rust, ktere jsem potkal, byli spise mizerni programatori C/C++, kteri z chyb obvinovali "zastaraly" programovaci jazyk.Přiznám se bez mučení, že jsem mizerný C/C++ programátor... Napsat netriviální kus kódu, u kterého bych mohl dát ruku do ohně za to, že neobsahuje UB, paměťové chyby a/nebo race conditions asi nedokážu. Určitě ne bez nějaké ruční a/nebo automatizované verifikace (kde už ale bude částečný překryv s tím, co delá rustc). OTOH je pravda, že stejnětak asi nedokážu napsat kód v Rustu, u kterého bych mohl opravdu dát ruku do ohně, že neobsahuje třeba logické chyby, DoS chyby nebo podobně. Stále bych s tím ale měl nejspíše méně starostí o jednu/dvě kategorie problému a mohl být o chlup klidnější s tím, že třeba out-of-bounds přístup způsobí pouze DoS, nikoli RCE. Nebo něco podobného.
Rust je na dobre ceste k podobnemu molochu jakym je C++To souhlasím, co se týče růstu komplexity jazyk. Jsem zvědam, co s tím (ne)udělají.
kde už ale bude částečný překryv s tím, co delá rustcPrave, ja vzdycky chapal Rust tak, ze se vzaly best practices (z C++) a udelaly se z nich striktni pozadavky, aby bylo mozne zarucit to ci ono. Vetsina programatoru C/C++, ktera ma ambice zustat dusevne pricetna pri programovani vicevlaknovych aplikaci, bez tak bude dodrzovat podobne principy jako ma Rust, akorat to bude bez tech zaruk.
Určitě ne bez nějaké ruční a/nebo automatizované verifikace (kde už ale bude částečný překryv s tím, co delá rustc).Automatizovane nastroje a restrikce jazyka na bezpecny subset.
Ja nezpochybnuji prinost Rustu, nicmene mi prijde, ze na bezpecnost se zuzene kouka prizmatem integrity pameti ve vicevlaknovych aplikacich, coz samo o sobe nestaci.To souhlasim. Paměťová bezpečnost je IMHO celkem podstatná část (třeba když se člověk podívá na přibývající CVEs apod.), ale samozřejmě to samo o sobě nestačí.
Ohledne pouziti bezpecneho jazyka, jsem spise skeptik, staci se kouknout na osud Ada. Je tu jiz roky, ma standard, certifikovane nastroje/kompilatory, formalne definovanou a verifikovatelnou verzi (Ada/SPARK) a presto ji temer nikdo nepouziva, nebot psat programy v ni je slozite a drahe.To je pravda, nicméně je psaní v C++ jednodušší a levnější při dodržení veškerých guidelens, testování, atd.? Můj dojem je, že psát programy v Rustu je obecně naopak jednodušší, nikoli složitější (což nevylučuje, že některé specifické problémy mohou být složitější). Zejména běžné věci. Třeba když chci v C++, aby můj objekt byl moveable, musím mu dopsat příslušné konstruktory/operátory a korektně ošetřit stav "prázdný objekt" v member funkcích a destruktoru. Což je dost boilerplate kódu. Nebo třeba nutnost používat PIMPL, což je taky boilerplate a navíc i runtime overhead. Použití mutexu je také složitější a nebezpečnější. Dále třeba práce s unicode stringy. C++ optinal oproti tomu rustovému neumí skoro nic. Dále třeba interátory, jsou obtížnější na korektní použití, ale přitom neposkytují tolik užitečných funkcí. Přijde mi celkově - a bohužel včetně moderních verzí C++ - že člověk musí pochopit spoustu komplexity a následně napsat spoustu boilerplate, ale ve výsledku za to dostane strašně málo benefitu, naopak ještě třeba přibudou další pitfalls a footguns :-/
To je pravda, nicméně je psaní v C++ jednodušší a levnější při dodržení veškerých guidelens, testování, atd.?Rekl bych, ze programovaci jazyk sam o sobe neni hlavni faktor, dulezitejsi je jeho znalost a zkusenosti s nim ze strany vyvojoveho teamu a vecem jako coding guidelines ci testovani neutecete v zadnem jazyku.
Třeba když chci v C++, aby můj objekt byl moveable, musím mu dopsat příslušné konstruktory/operátory a korektně ošetřit stav "prázdný objekt" v member funkcích a destruktoru.Nemusite. Pravidla, kdy kompilator generuje defaultni verze move constructor/move assignment jsou pomerne jasna a lze to lehce vynutit. Manualne je to nutne psat pokud vam member-wise presunuti nestaci a to vetsinou indikuje komplexejsi programovou logiku uvnitr tridy ci komplexni dedicnou hearchii (spatny navrh).
Nebo třeba nutnost používat PIMPL, což je taky boilerplate a navíc i runtime overhead.PIMPL je neprijemny, overhead zrovna zde dokaze kompilator casto eliminovat pokud pouzije std::unique_ptr. Co se tyka boiler-plating, Rust me take zrovna neprijde jako usporny jazyk.
Použití mutexu je také složitější a nebezpečnější.Parallelni programovani neni jednoduche v zadnem jazyku a je to predevsim o datovych zavislostech.
Dále třeba práce s unicode stringy. C++ optinal oproti tomu rustovému neumí skoro nic.Stringy jsou mizerie.
Dále třeba interátory, jsou obtížnější na korektní použití, ale přitom neposkytují tolik užitečných funkcí.Staci, nevyhody nejsou natolik zasadni aby se menil jazyk.
Rekl bych, ze programovaci jazyk sam o sobe neni hlavni faktor, dulezitejsi je jeho znalost a zkusenosti s nim ze strany vyvojoveho teamu a vecem jako coding guidelines ci testovani neutecete v zadnem jazyku.S tím samozřejmě souhlasím, ale je to taková ne-odpověď a přijde mi, že protiřečí tvému výroku o Adě. Jestliže můžeme o Adě něco takového říct, určitě je na místě se zeptat, jestli to neplatí i o C++ ...
Nemusite. Pravidla, kdy kompilator generuje defaultni verze move constructor/move assignment jsou pomerne jasna a lze to lehce vynutit.Měl jsem na mysli právě např. při použití PIMPL. V té chvíli totiž potřebuješ (byť prázdný) custom destructor, a tím pádem nemáš generované move konstruktory / operátory. Naívc musíš v member funkcích buď ošetřit stav prázdného PIMPL pointeru, nebo se spokojit s tím, že způsobí SEGFAULT při použití u moved-from objektu...
Co se tyka boiler-plating, Rust me take zrovna neprijde jako usporny jazyk.Ano, to souhlasím. Hlavně v porovnání s vyššími jazyky je ukecaný...
Parallelni programovani neni jednoduche v zadnem jazyku a je to predevsim o datovych zavislostech.Však o tom to právě je - že jazyky jsou do různé míry schopné ty datové závislosti modelovat a ošetřit chyby.
Staci, nevyhody nejsou natolik zasadni aby se menil jazyk.No, to záleží na tom, jaký máš požadavky, pokud požadavkem bude paměťová bezpečnost a snazší paralelizace, může to dávat smysl. Jinak tahle odpověď celkem dobře ilustruje hlavní důvod použití C++ - status quo. C++ se tím pádem poslední dobou začíná čím dál více posouvat do pozice podobné třeba PHP nebo něčeho takového (s tím rozdílem, že C++ není tak zdaleka příšerný jazyk jako PHP).
C vidim i pres jeho slabiny spise pozitivneAno, to já taky, ovšem při použití na vhodné úrovni. C vidím jako vhodný pro kernely OS a embedded firmware. Pro programování user space programů / aplikací mi ale už moc vhodný nepřijde.
S tím samozřejmě souhlasím, ale je to taková ne-odpověď a přijde mi, že protiřečí tvému výroku o Adě. Jestliže můžeme o Adě něco takového říct, určitě je na místě se zeptat, jestli to neplatí i o C++ ...
Nemyslím, že si to protiřečí. Sehnat vývojáře je obecně problém. A je pořád o dost jednodušší sehnat vývojáře na projekt v C++ než vývojáře na projekt v Adě. Takže abych větší projekt založil na Adě, musel bych být přesvědčen, že ty výhody oproti C++ budou dostatečně významné, aby převážily ty technické a organizační potíže, které to přinese. Pokud o tom přesvědčen nejsem, tak raději použiju C++, i kdybych si myslel, že to v Adě o něco příjemnější bude. (Hobby projekt, který stejně bude z větší části one man show, je samozřejmě něco jiného.)
A je pořád o dost jednodušší sehnat vývojáře na projekt v C++ než vývojáře na projekt v Adě.Jenže ten požadavek nebyl hledat vývojáře C++, ale vývojáře C++, kteří mají obrovské zkušenosti a/nebo jsou takoví machři, že dokáží psát kvalitní MT kód. Ty podmníky, které ty nebo little.owl kladete na programátory v C/C++ jsou natolik vysoké, že už mi přijde, že se to skoro té Adě blíží... Je to samozřejmě trochu nadsázka, nicméně všimni si, že ve stejném vlákně oba argumentujete dostupností programátorů C/C++ a zároveň z velké části vidíte problémy MT programování v C/C++ v neschopnosti programátorů.
Jenže ten požadavek nebyl hledat vývojáře C++, ale vývojáře C++, kteří mají obrovské zkušenosti a/nebo jsou takoví machři, že dokáží psát kvalitní MT kód.A vy byste nehledal programatory, kteri dokazi psat kvalitni [MT] kod? Od programatoru C/C++ se ocekava schopnost psat prehledny udrzovatelny kod s zadnym undefined/unspecified behaviour, a minimem dokumentovanych implementation-defined behaviour, s dodrzenim coding guidelines a s tim ze maji jasnou predstavu co delaji a proc. Na stranu druhou museji mit podminky takto pracovat - coz casto neni splneno a to ma pak konsekvence. Kazdy dela chyby, pak musi byt chyceny pri kod review, statickou analyzou a kaskadou testovani; zajisteni kvality SW je process. Rozdil mezi dobrym/spatnym a zkusenym/mene zkusenym programatorem je predevsim v tom jak casto a kolik takovych chyb udelaji, a rozdily mezi programatory jsou pomerne velke.
Ty podmníky, které ty nebo little.owl kladete na programátory v C/C++ jsou natolik vysoké, že už mi přijde, že se to skoro té Adě blíží...Podminky na programatory a na jazyky jsou dve ruzne veci. Pokud clovek umi C/C++, neni problem pro nej zacit rychle pouzivat vhodny subset jazyka a zacit dodrzovat nejake guidelines. Pokud clovek Adu neumi, tak jsou jeji restrikce irelevantni.
Je to samozřejmě trochu nadsázka, nicméně všimni si, že ve stejném vlákně oba argumentujete dostupností programátorů C/C++ a zároveň z velké části vidíte problémy MT programování v C/C++ v neschopnosti programátorů.Nemam pocit, ze jsme to zduraznovali, ale neni v tom rozpor. V C/C++ lze psat bezpecne vicevlaknove aplikace, vyzaduje to vice pozornosti a snadneji se udela chyba, ale jak jsem psal jiz nekolikrat, implementace v nejakem jazyce je jen jeden krok procesu vyvoje kvalitniho SW.
A vy byste nehledal programatory, kteri dokazi psat kvalitni [MT] kod? Od programatoru C/C++ se ocekava schopnost psat prehledny udrzovatelny kod s zadnym undefined/unspecified behaviour, a minimem dokumentovanych implementation-defined behaviour, s dodrzenim coding guidelines a s tim ze maji jasnou predstavu co delaji a proc.Tak to je snad samozřejmé, že člověk hledá co nejlepší vývojáře, otázka je, jakou šanci mám je najít a zaplatit.
V C/C++ lze psat bezpecne vicevlaknove aplikace, vyzaduje to vice pozornosti a snadneji se udela chyba, ale jak jsem psal jiz nekolikrat, implementace v nejakem jazyce je jen jeden krok procesu vyvoje kvalitniho SW.Tu zmínku o těch ostatních krocích jsem nepochopil. Přijdou mi samozřejmé. Tady se bavíme právě právě o tom kroku implementace. Nebo je snad třeba unit testing v C++ nějak výrazně snazší v porovnání s jinými jazyky? Mně přijde, že to spíše opět bude naopak...
Tu zmínku o těch ostatních krocích jsem nepochopil. Přijdou mi samozřejmé. Tady se bavíme právě právě o tom kroku implementace. Nebo je snad třeba unit testing v C++ nějak výrazně snazší v porovnání s jinými jazyky? Mně přijde, že to spíše opět bude naopak...
Nejde o to, že by to bylo výrazně snazší. Ale stejně tak to není výrazně obtížnější. On tady v podstatě nikdo netvrdí, že by celkové nároky na vývoj v C++ byly nějak výrazně menší než v těch exotických jazycích. Ale stejně tak nejsem vůbec přesvědčen (a očividně nejsem sám), že by to v Rustu, Adě nebo nějakém dalším cool jazyce šlo celkově o tolik lépe, aby to vynahradilo komplikace spojené s volbou daleko méně rozšířeného jazyka.
Ale stejně tak nejsem vůbec přesvědčen (a očividně nejsem sám), že by to v Rustu, Adě nebo nějakém dalším cool jazyce šlo celkově o tolik lépe, aby to vynahradilo komplikace spojené s volbou daleko méně rozšířeného jazyka.V tomhle ohledu nejsme ve při. Však jsem poznamenával, že byly projekty, kde jsem Rust zavrhl ve prospěch setrvání u C/C++, mj. právě také z tohoto důvodu. Celkově jsem sem psal hlavně kvůli obraně toho rozhodnutí Mozilly použít ho, tam mi přijdou ty důvody dobré a ta kritika mi přišla dosti nesmyslná, až histerická. Ale to neznamená, že bych považoval za rozumné hned použít Rust všude, kde to je jen trochu možné.
S tím samozřejmě souhlasím, ale je to taková ne-odpověď a přijde mi, že protiřečí tvému výroku o Adě.Ani ne. Michal Kubecek vam to presne vysvetlil.
Měl jsem na mysli právě např. při použití PIMPL.PIMPL mi nikdy neprisel jako problem, protoze ho moc nepouzivame s vyjimkou public interfacu modulu, coz je zlomek kodu a tam jen z duvodu exportu zavislosti.
Však o tom to právě je - že jazyky jsou do různé míry schopné ty datové závislosti modelovat a ošetřit chyby.Rust dokaze osetrit urcitou tridu chyb, ale jeho prinost v kontextu celeho zivotniho cyklu producktu a vyvojoveho procesu neni takovy, aby se vyplatilo prejit; fakticky to ani neni mozne. A vubec neresi hlavni problemy co jsme z hlediska kvality a spolehlivosti meli za poslednich 10 let.
PIMPL mi nikdy neprisel jako problem, protoze ho moc nepouzivame s vyjimkou public interfacu modulu, coz je zlomek kodu a tam jen z duvodu exportu zavislosti.PIMPL byl příklad, ten problém je obecně v tom, že C++ move semantics rozbíjejí RAII. (Přidávají do lifetime objektu stav, kdy objekt ještě není uvolněn, ale už není ve validním/iniciovaném stavu.)
Rust dokaze osetrit urcitou tridu chyb, ale jeho prinost v kontextu celeho zivotniho cyklu producktu a vyvojoveho procesu neni takovy, aby se vyplatilo prejit; fakticky to ani neni mozne. A vubec neresi hlavni problemy co jsme z hlediska kvality a spolehlivosti meli za poslednich 10 let.Nepostřehl jsem moment, kdy se z diskuse stala úvaha proč ne/přejít na Rust v tvém zaměstnání.
Přidávají do lifetime objektu stav, kdy objekt ještě není uvolněn, ale už není ve validním/iniciovaném stavu.Presouvate snad rvalue, tedy objekt bez identity/jmena a movable, a pak to neni problem. Navic nemam pocit, ze movable-but-not-copyable pristup rozbiji RAII.
Presouvate snad rvalue, tedy objekt bez identity/jmena a movable, a pak to neni problem. Navic nemam pocit, ze movable-but-not-copyable pristup rozbiji RAII.To by znamenalo používat move semantics pouze pro dočasné objekty bez identity. Trochu škoda.
Představu, že nějaká nová zázračná Cool Language of the Year bude tou kouzelnou hůlkouTak možná ne všechny problémy ale některé ano. Přiznám se, že jsem nikdy pořádně nepochopil, proč je tak těžké navrhnout přirozeně multithreading / multiprocessing jazyk. Ale nejsem programátor, svoje skriptíky za nějaké větší a komplexnější programy považovat nebudu. Ovšem vycházím z toho, že v shellu můžeme bez problémů psát
prog1 | prog2 | prog3
atd. a tímto automaticky bez jakékoliv větší námahy psát programy využívající několik procesorů. Stačí jen dodržet jednoduchou zásadu a to, že výstup programu by měl být snadno zpracovatelný na vstupu jiného programu. O zbytek se postará OS.
Další automaticky a snadno použitelnou věcí, kterou používám takřka denně, je konstrukce find něco | parallel prog
.
A ve skutečnosti výše uvedené techniky lze bez problémů zkombinovat, takže parallel
může spouštět vláček programů spojených rourou atp.
(Ano vím, že dneska jsou k disposici ultrarychlé fronty, takže programy mohou asynchronně strkat data do fronty a libovolný jiný program na to může reagovat a požadavek zpracovat.)
Je to pro mě (ten unixový způsob) tak přirozené, že příliš nerozumím tomu, proč v programovacích jazycích je stále potřeba explicitně označovat místa "tady bude thread" a nedej bože to ještě ručně zařídit.
Když si vezmu za příklad python, tak má krásnou knihovnu multiprocessing.Pool a tam je map. Dám ji funkci, pole a výsledkem je pole výsledků té funkce na prvky vstupního pole. Automaticky paralelně v maximálním počtu procesů podle počtu procesorů. O víc se starat nemusím, multiprocessing na jeden řádek.
Ok, ale proč tohle není součástí jazyka? Dovedu si představit automaticky paralelní list comprehension (nebo možná ještě lépe generátor), který, pokud může dokázat (to je podmínka i pro Pool.map) že volaná funkce nemá žádné vedlejší efekty (k čemuž mimochodem Python vede programátora od počátku), tak to provede paralelně. A dovedu si představit, že debuger, nebo něco jako pylint upozorní na neparalelizovatelné smyčky s tím, že když se to přepíše, tak to pojede.
Ano, vím, že tohle není všespásné a stále budou existovat místa, která bude potřeba explicitně rozdělovat (protože program samozřejmě nepozná, že například tab v prohlížeči by měl být samostatný proces), ale současně si nemyslím, že je na tom něco tak složitého. Techniky máme i v tom 40 let starém shellu.
Ne všechno lze řešit takhle, nebo aspoň ne bez nepřijatelné ztráty výkonu. Někdy jednotlivé thready potřebují sdílet data a řešit přístup k nim.
Namátkou třeba connection tracking. Mám pár desítek (někdy i stovky) procesorů, na kterých se paralelně zpracovávají pakety. Pro každý se potřebuju podívat, jestli odpovídá nějaké existující položce, případně provést nějaké další kontroly (třeba u TCP se kontrolují sequence a acknowledgement number, jestli dávají aspoň trochu smysl) a podle toho se buď zahodí, přiřadí se mu existující položka z tabulky nebo se vytvoří nová.
Pokud se něco záasadního nezměnilo, řešením je klasická hash tabulka, kde je pro každou hodnotu hashe RCU list, takže třeba čtení (což je drtivá většina přístupů) nezdržuje prakticky vůbec a jen přidávání a odebírání je potřeba pokrýt spinlockem.
Jak to budeš řešit ve svém modelu? Napadá mne ustanovit jeden thread jako "strážce tabulky", kterému se předá request, on provede lookup, vyřeší co je třeba a vrátí odpověď. Výsledek bude ještě horší než kdybych celou tabulku pokryl jedním univerzálním zámkem (o režii té komunikace). Kdyby někdo něco takového zkusil navrhnout, maintainer ho požene klackem (nadsázka, Pablo není ten typ, ale naději na úspěch bych tomu stejně nedával).
Spousta aplikací by tak bezesporu fungovat mohla. Ale je dost míst - i v userspace - kde si takový luxus programátor dovolit nemůže.
iter
, kde ho s pomocou rayon
-u jednoducho prepises na par_iter
a je to. Jazyk samotny kedze je o trochu vyssej urovne ako C ti pomaha niektore ulohy krasne paralelizovat prave tym, ze pozaduje po programatorovi aby svoj kod pisal o trochu jednoznacnejsie. iter
pomerne jednoznacne hovori ze ides pracovat nad prvkami nejakeho pola. S extra garanciou pristupu k premennej v podobe sledovania vlastnictva potom vies pomerne jednoducho povedat "toto urob, ale v 4 vlaknach". Keby si v Ruste robil klasicky for, i<len(),i++
, tak je ta abstrakcia o trochu horsia - clovek este ako tak pochopi, ze o co ide ale uz tam o cosi tazsie vlozis tu logiku vlakien. Prave pre to, ze je to o kusok nizsia uroven. (a to uz sa ani nebavime o ASM)
Python je tiez dobry priklad, lebo (ignorujuc GIL) vies v kode pomerne jasne deklarovat zamer programatora. Pride mi ze taky kod sa potom casto omnoho lepsie optimalizuje ked ho ma compiler prelozit do strojoveho kodu. V pripade Pythonu je to tak trosku premarnena prilezitost. Jednak bol vytvoreny v case ked jedno jadro bol standard a tiez sa zvycajne pouziva na ulohy kde GIL nie je az tak limitujuci.
Go je v tomto smere asi lepsi priklad, tam je ten paralelizmus tak nejak core vlastnost jazyka a vo vela pripadoch ziskas paralelizmus tak nejak by the way. Go ma samozrejme svoje vlastne problemy (podla mna skor sposobene vedenim projektu ako jazykom samotnym) ale to je vedlajsie.
Ostatne keby nizkourovnovost bola hlavnou garanciou vysokeho paralelneho vykonu, mali by sme C vidiet s velkym odstupom na poprednych prieckach v aplikaciach kde na vykone skutocne zalezi, ale tak jednoznacne to nie je.
Když si vezmu za příklad python, tak má krásnou knihovnu multiprocessing.Pool a tam je map.To úplně neodpovídá té koloně v shellu s parallel, protože to nezpracovává průtokově. Seznam musí být hotový a pak na něj uděláš paralelně map. Něco podobného je i v C, stačí na strategické místo napsat
#pragma omp parallel
. V C++ pak jsou Threading Building Blocks, které umí jak toto, tak průtokové zpracování, fronty, partition problému…
pool.map
je potřeba hotový seznam, zatímco parallel
nebo třeba xargs
si to bere postupně s stdin
. V tom je jistě rozdíl a sám jsem si napsal udělátko, které umožňuje paralelně zpracovávat položky ve frontě, kam je možné je průběžně zapisovat.
Mým cílem bylo spíš vyvolat diskusi na toto téma, nejsem programátor, jistě se na to dívám zkresleně a zajímal mě jiný pohled.
parallel_for
a pride mi ze presne preto vela ludi uteka k Rustu. Jednak je ta dokumentacia absolutne mizerna oproti tomu, co automaticky vygeneruje rustdoc, druhak je to sialene komplikovane oproti rayon a jeho par_iter
.
Toto je pohlad cloveka podobne ako Heron, ktory vacsinu casu potrebuje nieco zbastlit v Bashi a Pythone, ale obcas potrebuje nieco vykonnejsie, takze je mozne ze mi nieco uchadza, ale tak ako je TBB prezentovane by som dlho vahal, ci mi to stoji za tu namahu.
Pozeram dokumentaciu k tom TBB parallel_for a pride mi ze presne preto vela ludi uteka k Rustu.TBB je inteli knihovna. Zatim ten utek, treba v nabidkach placene prace, neni videt.
#pragma omp parallel for for (auto it = v.begin(); it < v.end(); it++) { ... }nebo je mozne pouzit paralellni for_each od C+17 (C++20 to jeste rozsiruje). Oboji je dokumentovane s precisnosti standardu a verze s OpenMP je pouzitelna i v C.
Ja by som tomu dal tak dva-tri roky, kam to povedie.Já bych tomu klidně dal i víc. Ono to potrvá i v případě, že to půjde dobře... Mně přijde, že lidé, kteří se tu tak pohoršují nad nestabilitou rustu a jeho použití ve FF, asi úplně zapomněli historii C a C++. V obou případech bylo mezi vznikem jazyka a standardizací >15 let. A že by se v mezidobí nepsal v těch jazycích produkční software?
OpenMP je tak trochu kanon na vrabce,OpenMP neni kanon na vrabce, ma stabilni podporu v kompilatorech jiz roky a umoznuje velmi dobre parallelizovat starsi kod.
stale si stojim za tym, ze aj v pripade OpenMP je dokumentacia uplne prisernaCo je konkretne na dokumentaci OpenMP pro C/C++ priserneho? Viz. zde ci zde ci zde.
int aa[] = {0,1,3 /*...*/}; std::for_each(std::execution::par, std::begin(aa), std::end(aa), [&](int i) { ; // do something });ci jednoduse to modifikovat pro jakykoliv STL container nebo vasi vlastni tridu.
Ja by som tomu dal tak dva-tri roky, kam to povedie.To bude trvat mnohem dele.
Co je konkretne na dokumentaci OpenMP pro C/C++ priserneho? Viz. zde ci zde ci zde.Uz len to, ze je to PDF je naprosty des. Pre porovnanie spominany rayon. S jednoduchym vyhladavanim, prikladmi ktore maju zvyraznenu syntax a nalinkovane typy. (a to aj typy mimo dokumentovanej kniznice, napriklad std::) Odkazy priamo do zdrojovych kodov.. (danej verzie!) Python standard library je hadam jedina vec ktora sa blizi standardu aky vie v podstate bez namahy vygenerovat rustdoc.
Mne pride toto take citatelnejsie:int aa[] = {0,1,3 /*...*/}; std::for_each(std::execution::par, std::begin(aa), std::end(aa), [&](int i) { ; // do something });
(0..3).into_par_iter().for_each( |i| // do something );
Uz len to, ze je to PDF je naprosty des.Znovu, co je na tom desiveho? Jedna o rozumne napsanou specifikaci standardu, vcetne prikladu, na zaklade nehoz lze implentovat prekladac. To je fakticky nejlepsi verze dokumentace jakou muzete dostat.
Pre porovnanie spominany rayon.Oproti specifikaci standardum OpenMP, pouziva tato dokumentace celkem vagni jazyk s nejednoznacnou interpretaci. Podle takoveho popisu interface by knihovna sla tezko reimplementovat, aniz by se rozbily aplikace a to je dobre meritko kvality dokumentace.
Mne pride toto take citatelnejsie:Nekdo proste radsi zelenou, nekdo modrou.
Znovu, co je na tom desiveho? Jedna o rozumne napsanou specifikaci standardu, vcetne prikladu, na zaklade nehoz lze implentovat prekladac. To je fakticky nejlepsi verze dokumentace jakou muzete dostat.Neda sa v tom rozumne vyhladavat. (a pred tym, nez povies, ze to je problem PDF prehliadaca, nie PDF prehliadac nepozna koncept funkcii, makier a traits, rustdoc ano) Plus vsetky dalsie problemy ktore PDF ma ako napriklad fakt ze je to non-free format zatazeny patentami, velmi tazko sa zobrazuje na citackach/mobilnych displayoch, neda sa don linkovat z inej dokumentacie,..
Oproti specifikaci standardum OpenMP, pouziva tato dokumentace celkem vagni jazyk s nejednoznacnou interpretaci. Podle takoveho popisu interface by knihovna sla tezko reimplementovatMozno tam kazdy vidime to svoje, ale ta dokumentacia doslova zahrna aj kod ktory danu funkcionalitu implementuje keby si chcel naozaj ist az na uroven implementacnych detailov. Je dost mozne, ze z tej dokumentacie dokazes extrahovat komplet cely kod rayonu. Plus jazyk samotny pomerne jasne urcuje co bude tvoja funkcia robit, ci bude menit nejake data, v akej forme ich vrati a ako dlho potrebuje aby data boli alokovane napriklad. Samotny deskriptor funkcie ti povie polovicu dokumentacie. To ze je to pekne nalinkovane a ofarbene je uz len prijemny detail.
Neda sa v tom rozumne vyhladavat. (a pred tym, nez povies, ze to je problem PDF prehliadaca, nie PDF prehliadac nepozna koncept funkcii, makier a traits, rustdoc ano) Plus vsetky dalsie problemy ktore PDF ma ako napriklad fakt ze je to non-free format zatazeny patentami, velmi tazko sa zobrazuje na citackach/mobilnych displayoch, neda sa don linkovat z inej dokumentacie,..Mate strukturovany dokument s kvalitou zpracovani na urovni standardu, s presnym jazykem, s definici pojmu, terminologie, s obsahem, s indexem, s moznosti referovat doslova kazdy cislovany radek, reviewovany, s historii zmen, referencni kartu se vsim podstatnym ... a to vse je irelevantni, protoze PDF. Navic jste zaspal dobu, PDF je free otevreny format s ISO standardem, uz deset let, viz zde ci zadarmo zde.
Mozno tam kazdy vidime to svoje, ale ta dokumentacia doslova zahrna aj kod ktory danu funkcionalitu implementuje keby si chcel naozaj ist az na uroven implementacnych detailov.Pokud dokumentace API knihovny dohani uzivatele ke studovani kodu implementace, je spise horsi; coz je v praxi vetsina mimo implementacni standardy.
mnohem příjemnější pro programátora,To je pak subjektivni, ja preferuji presnejsi specifikaci, nebot vagnejsi ci neuplny popis muj zivot nikdy lehci neudelal, spise naopak.
nic nefungovalo protoze kazdy dodavatel intepretoval specifikaci trochu jinak ... Veci jako may, might, should, shall maji presne definovany vyznamVsimni si, ze v pripade psani specifikace chvalis pouziti jazyka (byt prirozeneho), ktery ma omezene vyjadrovaci schopnosti, a povazujes to za dobrou vec. Ale v pripade programovaciho jazyka (Rustu) ti to vadi. Pricemz se jedna jen o dve ruzne faze vyvoje. Klidne bych mohl tvrdit, ze specifikaci muzes napsat obecnym jazykem bez nejakeho vymezovani, co je to must a should, jen s tou podminkou, ze autor specikace bude umet dobre psat specikace.
Vsimni si, ze v pripade psani specifikace chvalis pouziti jazyka (byt prirozeneho), ktery ma omezene vyjadrovaci schopnosti,To neni o omezenosti, to je o presnosti.
Ale v pripade programovaciho jazyka (Rustu) ti to vadi.Nevadi, Rust az tolik neomezuje, tedy nad ramec programovaci jazyka, ktery musi byt z podstaty presny. Hlavni problem vidim v tom, ze je to zatim stale experimentalni nestabilni rolling jazyk, s tim ze jeho prinost neni v praxi az tak velky, aby se vyplatilo ted vubec uvazovat o nahrazeni ustalenych systemovych jazyku se stabilnim ekosystemem.
Klidne bych mohl tvrdit, ze specifikaci muzes napsat obecnym jazykem bez nejakeho vymezovani, co je to must a should, jen s tou podminkou, ze autor specikace bude umet dobre psat specikace.Tvrdit muzete co chcete. Psani jednoznacne specifikace, ale i treba zakonu a podobnych veci, vyzaduje definici pojmu a terminu ci uzivani ustalene terminologie, to neni barvita beletrie, kde je na fantazii ctenare si text interpretovat po svem.
3.1.34Tohle je nejen bezne, ale ve sve podstate nutne.
shall
term used to express mandatory requirements for conformance to this Recommendation | International Standard
3.1.35
should
term used to refer to behaviour of an implementation that is encouraged to be followed under anticipated ordinary circumstances, but is not a mandatory requirement for conformance to this Recommendation | International Standard
To neni o omezenosti, to je o presnosti.V momente, kdy jednotlivym pojmum davas jeden konkretni vyznam, jiz dochazi k omezeni.
ze jeho prinost neni v praxi az tak velky, aby se vyplatilo ted vubec uvazovat o nahrazeni ustalenych systemovych jazyku se stabilnim ekosystemem.Mozna pro tebe pro vasi firmu. V Mozille (a asi i jinde) si to nemysli a ne vsude maji tak striktni pozadavky. Treba takove PHP nebo JavaScript maji naprosto zbesily vyvoj a prekvapive to nevadi milionum jeho uzivatelu.
Tvrdit muzete co chcete. Psani jednoznacne specifikace...Ona to byla puvodne parafraze na jednoho prispevetele do tehle diskuze.
V momente, kdy jednotlivym pojmum davas jeden konkretni vyznam, jiz dochazi k omezeni.Definovani terminologie neomezuje vyjadrovaci prostredky ktere mate k dispozici pro psani specifikaci, presne naopak, nebot vagni a nejednoznacne pojmy nemuzete pouzit.
Treba takove PHP nebo JavaScript maji naprosto zbesily vyvoj a prekvapive to nevadi milionum jeho uzivatelu.Srovnavat webovy vyvoj, kde veci maji kratky polocas rozpadu a vyvojari prepisuji frameworky a aplikace snad kazde tri roky se systemovym programovanim kam Rust aspiruje a kde se udrzuji veci i desitky let, tak jednoduse nejde. Navic je to nesmyslne srovnani, treba Javascript ma rozumny stabilni standard (ECMA), ktery se zpetne kompatibilne updatuje transparentnim zpusobem jednou za rok; rozhodne se nemeni kazde tri tydny. Mozilli pristup k Rustu uz dela problemy distribucim (viz. predchozi Michaluv link) nebo kdy LTS distribuce si nemohou dovolit updatovat kompilator desetkrat za rok a pak distrubuuji derave davno nepodporovane verze (viz. ono CVE).
Definovani terminologie neomezuje vyjadrovaci prostredky ... nebot vagni a nejednoznacne pojmy nemuzete pouzit.To trochu nedava smysl.
Srovnavat webovy vyvoj, kde veci maji kratky polocas rozpadu a vyvojari prepisuji frameworky a aplikace snad kazde tri rokyTo by ses divil, kolik veci napsanych v PHP bezi deset a vic let, coz uz je docela srovnatelne s onim systemovym programovanim.
To trochu nedava smysl.Muzete to upresnit? Specifikace musi byt jednoznacna, tedy normativni casti maji jen jednu a pouze jen jednu moznou interpretaci. Proto vetsina dokumentu tohoto typu zacina s "Terms and Definitions" ci "Glosary", nebo referuji dalsi normativni dokumenty, ktere definuji terminologii. Za temito vecmi stoji uz vice nez stolete zkusenosti jak psat a pouzivat technicke dokumenty, standardy a specifikace.
napsanych v PHP bezi deset a vic letAle jo, php je stalice. A maji to stesti, ze jim nekdo podporuje a posila roky bezpecnostni updaty na starsi verze. Php5 ma kolik let? Patnact?
Mozilli pristup k Rustu uz dela problemy distribucim (viz. predchozi Michaluv link)Za celou tu diskusi jsem z p. Kubečka nedostal informaci, jaké problémy to distribucím dělá. Získal jsem dojem, že problémy mají především proto, že rolling-updatujou Firefox v non-rolling distru. Také nebyl nikde vysvětlen důvod toho požadavku, proč musí OpenSUSE dodávat spolu s FF i odpovídající rustc - podezírám je, že považují rustc jen za takový divný gcc a podle toho se k němu chovají, což není úplně smysluplné.
nebo kdy LTS distribuce si nemohou dovolit updatovat kompilator desetkrat za rok a pak distrubuuji derave davno nepodporovane verze (viz. ono CVE)Tam není problém v tom rolling modelu ale hlavně v tom, že ta bezpečnostní chyba nebyla nahlášena v rámci vydání Rust 1.21. I kdyby byla bývala existovala LTS verze Rustu, stejně by to distribuce ve chvíli zazáplatování bezpečnostní chyby musely aktualizovat, což v současné situaci vyjde v podstatě nastejno jako aktualizovat na poslední stable verzi. Hlavně to ale chtělo a chce dobudoucna o té chybě informovat.
Za celou tu diskusi jsem z p. Kubečka nedostal informaci, jaké problémy to distribucím dělá.
Dostal, dokonce několikrát. Ale z části jste tu informaci ignoroval, z části jste ty problémy nepovažoval za důležité. S tím nic nenadělám.
Také nebyl nikde vysvětlen důvod toho požadavku, proč musí OpenSUSE dodávat spolu s FF i odpovídající rustc
Protože distribuční balíčky se buildí v OBS nástroji dané distribuce. Vytvoří se chroot (to spíš při lokálním buildu) nebo VM (v OBS), tam se nainstaluje společný minimální základ, balíčky z BuildRequires
a uzávěr na závislosti a v tomto prostředí proběhne build. (Na začátku je samozřejmě nějaký bootstrapping, ale to už bychom zacházeli do zbytečných detailů.) Stejně tak se pro balíčky třeba pro SLES 10 (první release 2006) stále používá toolchain ze SLES 10 - některé by koneckonců s aktuálním gcc (a dalšími nástroji) ani přeložit nešly.
Ty nástroje se sice updatují a nedávno se třeba i do gcc ve starších distribucích přidávala podpora retpolines, ale nikdo nepůjde do takového dobrodružství, aby třeba ve SLE11 (nebo třeba i SLE12) upgradoval defaultní gcc na verzi 8.
Dostal, dokonce několikrát. Ale z části jste tu informaci ignoroval, z části jste ty problémy nepovažoval za důležité. S tím nic nenadělám.V tom problému s buildováním jsem naznačil, v čem si myslim, že byl problém, odpověď bylo "prostě to nešlo". V tom problému s distribucí jsme se nejdál dostalu k tvému "Co kdyby bylo více SW jako Firefox, to by byla katastrofa", na což jsem odpověděl, že by to nebyl problém (opravdu nevidim, v čem by to byl problém). Takže na mou věru nevidim/nerozumim, kde tam je ten problém.
Protože distribuční balíčky se buildí v OBS nástroji dané distribuce. Vytvoří se chroot (to spíš při lokálním buildu) nebo VM (v OBS), tam se nainstaluje společný minimální základ, balíčky z BuildRequires a uzávěr na závislosti a v tomto prostředí proběhne build. (Na začátku je samozřejmě nějaký bootstrapping, ale to už bychom zacházeli do zbytečných detailů.)Ok, ale v čem je benefit toho balíčku `
rust
` oproti stáhnutí rustc od Mozilly, ať už pomocí rustup nebo ručně? Dávalo by mi to o něco větší smysl leda v případě, že by balíček `rust
` byl v OpenSUSE bootstrapnut z nějaké archaické verze rustu po jednotlivých release, ale o tom silně pochybuju, nejspíše je `rust
` sestaven opět stáhnutím rustc od Mozilly, čiliže je to víceméně to samé akorát s balíkem navíc...
To už by mi dávalo mnohem větší smysl balíčkovat rustup
.
Ok, ale v čem je benefit toho balíčku `rust` oproti stáhnutí rustc od Mozilly, ať už pomocí rustup nebo ručně?
Reprodukovatelnost buildu (ideálně úplná, nelze-li, aspoň částečná). Navíc to není ani technicky možné, ten chroot/VM nemá (z dobrých důvodů) konektivitu, takže si nic stáhnout nemůže, ani kdyby se packager zbláznil.
Vy jste nejspíš s modelem Rustu sžitý natolik, že vám představa, že se v rámci buildu distribučního balíčku odkudsi stáhne nejnovější verze překladače, ze které ještě odkapává barva, a tím se balíček přeloží, připadá přirozená. Mně připadá strašidelná (a naštěstí i těm, kdo navrhovali ty nástroje a postupy).
Reprodukovatelnost buildu (ideálně úplná, nelze-li, aspoň částečná). Navíc to není ani technicky možné, ten chroot/VM nemá (z dobrých důvodů) konektivitu, takže si nic stáhnout nemůže, ani kdyby se packager zbláznil.Tak odněkud se začít musí, např. zdroják FF musí odněkud pojít. Počítám, že ze src balíčku, který taky musí nějak vznikat... A ten rust balíček taky jistě nějak vzniká...
Vy jste nejspíš s modelem Rustu sžitý natolik, že vám představa, že se v rámci buildu distribučního balíčku odkudsi stáhne nejnovější verze překladače, ze které ještě odkapává barva, a tím se balíček přeloží, připadá přirozená.Aby bylo jasno, ten aktuální model distribuce Rustu nepovažuju za nijak skvělý a je celkem zjevné, že dobudoucna se s tím bude muset něco dělat, zároveň ale je imho celkom jasné, že vyžadovat LTS verze, dlouhodbou stabilitu atd. je v aktuální fázi naprosto nereálné. Takže ty moje návrhy nejsou něco, co bych považoval za ultra skvělý nápad a model hodný následování, ale pouze za něco použitelného v rámci aktuální situace, dokud nepřijde čas na a potřeba lepšího řešení. Co se týče stahování překladače odkudsi, ten překladač se nejspíše odkudsi stáhnul o krok nebo několik kroků dříve tak jako tak. Kdyby Mozilla byla evil, resp. ještě více evil než za co už ji máš, pokud to tedy vůbec je možné, tak by tohle schéma stejně nejspíše vůbec nepomohlo.
Mně připadá strašidelná (a naštěstí i těm, kdo navrhovali ty nástroje a postupy).Jo, ten motiv děsivosti a katastrof už jsem z těch komentářů pochopil (narozdíl od technické podstaty většiny problému). Vidím zde obrovský potenciál pro tvorbu apokalyptické literatury.
To je problem rolling modelu bez LTS, protoze v podstate kazdy kdo neupdatuje jak blazen je v haji.Pro nějakou definici "je v háji" při které nejsi v háji...
Adobe grants every individual and organization in the world the royalty-free right, under all Essential Claims that Adobe owns, to make, have made, use, sell, import and distribute Compliant Implementations.A dalej:
“Compliant Implementation” means the portion of an application, product, or service that reads, writes modifies or processes computer files compliant with the Specification.
ISO by je s tim vyhodiloISO to v podstate neriesi:
The International Organization for Standardization draws at tention to the fact that it is claimed that compliance with this document may involve the use of patents concerning the creation, modification, display and processing of PDF files which are owned by the following parties:ISO takes no position concerning the evidence, valid ity and scope of these patent rights.
- Adobe Systems Incorporated, 345 Park Avenu e, San Jose, California,95110-2704, USA
Dovedu si představit automaticky paralelní list comprehension (nebo možná ještě lépe generátor), který, pokud může dokázat (to je podmínka i pro Pool.map) že volaná funkce nemá žádné vedlejší efekty (k čemuž mimochodem Python vede programátora od počátku), tak to provede paralelně.Jak by to fungovalo? Možná nerozumím tomu, jak to myslíš, ale celá podstata generátorů spočívá v tom, že další hodnotu vytváří až na vyžádání. Prostor pro paralelizaci by mohl být spíše u čtení z toho generátoru a následném výpočtu, pokud to okolnosti umožnují, ale generátory bohužel nejsou thread-safe. Nic ti ale v zásadě nebrání použít tu frontu, kterou jsi zmiňoval, a pak potřebuješ jeden thread, který tu frontu bude z generátoru plnit (i kdyby ve hře nebyl generátor, tak plnění fronty typicky někde budeš potřebovat zajistit, pokud to nelze nebo není vhodné udělat dopředu). To není moc složité a asi si neumím představit syntaktický cukr, který by to výrazně usnadnil. U list comprehension by to mohlo dávat větší smysl, ovšem nejde jen o absenci side-effectů, ale o nezávislost na pořadí vykonání. Příkladem budiž
[x for x in range(5)]
, ale nikoliv [time.time() for _ in range(5)]
(při paralelním provedení by nebylo garantováno, že list bude seřazen).
Pokud tě to nějak zvlášť trápí, asi by nebyl problém napsat si funkci, která dostane generátor a paralelně z něj naplní list. Osobně se ovšem nedomnívám, že by to za standardních podmínek dávalo smysl, protože listy tak velké, že by se paralelizace vyplatila navzdory režii, typicky vytvářet nechceš v první řadě. Vzhledem k tomu, že to bude explicitní, analýzu AST a dokazování si můžeš ušetřit.
Jak by to fungovalo? Možná nerozumím tomu, jak to myslíš, ale celá podstata generátorů spočívá v tom, že další hodnotu vytváří až na vyžádání.Ano, klasický generátor vyrábí na vyžádání, ale tenhle generátor by si jich pár mohl předpočítat a potom je vracet z poolu okamžitě. Tedy to "na vyžádání" by vrátilo výsledek hned a prvky by se počítaly asynchronně v jiných procesech.
U list comprehension by to mohlo dávat větší smysl, ovšem nejde jen o absenci side-effectů, ale o nezávislost na pořadí vykonání. Příkladem budiž [x for x in range(5)], ale nikoliv [time.time() for _ in range(5)] (při paralelním provedení by nebylo garantováno, že list bude seřazen).No otázkou je, zda je tohle dobrý nápad sám o sobě. Proto jsem uváděl za příklad comprehension a nikoliv cyklus for. Prvky v list comprehension by měly záviset pouze na prvcích vstupního pole. Každopádně je to jedna z dalších podmínek. Ostatně list comprehension je "jen" syntaktický cukr pro map a filter a u multiprocessing.pool.map taky nemáš zajištěno pořadí, ve kterém ty prvky budou počítané. Výsledné uspořádání je ale stejné, jako uspořádání vstupního pole.
Pokud tě to nějak zvlášť trápíNikoliv, já si poradím jinak, jen mě zajímají důvody, proč dneska není žádný jazyk, který by byl multithreading sám o sobě bez explicitního vytváření vláken / procesů programátorem. Ostatně máme tady deklarativní jazyky, u kterých by se to přímo nabízelo. U imperativních je to přirozeně horší.
Ano, klasický generátor vyrábí na vyžádání, ale tenhle generátor by si jich pár mohl předpočítat a potom je vracet z poolu okamžitě.Otázkou je, kolik je pár. Kde má generátor „dno“ není dopředu známo, stejně jako doba generování jedné položky a rychlost vybírání fronty. Počet threadů, jejich obsluhu, i maximální délku fronty bys musel nastavovat nějakou heuristikou, což samo o sobě představuje režii. V řadě případů to navíc bude úplně zbytečná mikrooptimalizace. Uvažujme třeba program, který dávkově zpracovává obrázky (jak zmiňoval oryctolagus). Generátor může vracet jména souborů, které potom v nějaké smyčce zpracováváš. Samotné vygenerování jména souboru představuje několik instrukcí, zatímco zpracování obrázku mnohem víc. Prostor pro paralelizaci by tedy byl právě tam. Pak už ale nedává smysl paralelizovat ten generátor zvlášť. Samotná paralelizace generator comprehensions by dávala smysl pouze v případě, kdy by právě toto byl bottleneck. Jak často se to reálně děje, aby to navíc nemělo side-effecty a nebylo to ukázkovým příkladem chybně navrženého kódu?
Proto jsem uváděl za příklad comprehension a nikoliv cyklus for.Ten můj příklad není comprehension?
jen mě zajímají důvody, proč dneska není žádný jazyk, který by byl multithreading sám o sobě bez explicitního vytváření vláken / procesů programátoremProtože vícevláknový program, který běží stejně pomalu, nebo dokonce pomaleji než kdyby běžel v jediném vlákně, k ničemu není. Nejpalčivější je typicky samotná logika programu, kde by zřejmě jedinou nadějí bylo spekulativní vykonávání podobně jako to dělají procesory. Kód uvnitř podmínky by tedy mohl být vyhodnocen dříve než podmínka samotná. Tam, kde efekt vykonání nelze zvrátit, nebo je to moc drahé, by se s provedením počkalo. Myslím si, že toho se dříve či později dočkáme, ale nemyslím si, že by to v tuto chvíli mělo nějaký výrazný potenciál (to spíše až s příchodem té hybridní architektury). Současně může být obtížné to zakomponovat do stávajících jazyků. Namátkou by to rozbilo smyčky, které měří, jak dlouho něco trvá – dobrá, to lze považovat za výjimku a tedy to spekulativně nevyhodnocovat, ale opravdu bych si netroufal tvrdit, že tím ty výjimky končí. Příliš silnou redukcí to zase do značné míry ztratí svůj význam.
Generátor může vracet jména souborů, které potom v nějaké smyčce zpracováváš.Proč by měl vracet jen jména? Můžu mít funkci
make_thumbnail
a můžu mít generátor:
thumbs = (make_thumbnail(image) for image in images)a potom třeba
for thumb in thumbs: whith open(filename, 'wb') as image_file: image_file.write(thumb)Právě jsem napsal generátor náhledů na 4 řádky. (Neřešme drobnosti jako jména souborů apod.) Ve skutečnost tohle dělám nějak takto:
pool.map(make_write_thumb, images)
(ta fce to rovnou i zapíše na disk).
Kdyby výše uvedený generátor byl (automaticky) paralelizovatelný, tak je to pěkně rychlý pythonic kód.
Proč by měl vracet jen jména?To byl příklad takového typického užití comprehensions, kde paralelizace žádné zrychlení nepřinese.
Můžu mít funkci make_thumbnail a můžu mít generátor:Můžeš. A taky se ti může stát, že se všechna jádra procesoru rozjedou na plné obrátky a budou generovat jeden thumbnail za druhým. Ale protože nebude stíhat disk, tedy ta smyčka, kterou z toho generátoru chceš, akorát jsi uživateli na nějakou dobu zahltil systém a zaplnil RAM. Přeji hodně štěstí při hledání nějaké heuristiky, která bude fungovat dostatečně dobře za všech okolností. Přitom jsi mnohem lepší řešení naznačil sám. Naspawnuješ worker thready, kterým předáš jméno souboru a necháš je vygenerovat i zapsat vygenerovaný thumbnail. Ke generování i zápisu dochází průběžně po celou dobu a nikde se zbytečně nehromadí data v RAM. Uživateli ještě dáš možnost si naspecifikovat, kolik threadů chce – kdyby se o to staral přímo jazyk a kontrolu nad tím neměl vlastně ani programátor, tato možnost se vytratí (nezbylo by než systémové prostředky před programem nějak skrývat, aby ta jeho chytristika tedy naspawnovala méně threadů).
K zahlcení může dojít i u toho map. Pokud nebude stíhat disk, tak se to narve do write cache a map bude vesele generovat dál. Jsi na tom stejném.To jde řešit buď flushnutím nebo nastavením velikosti bufferu. Je-li jeho výchozí velikost rozumná, není třeba se o to starat vůbec (zatímco ve tvém případě by napsání nějaké heuristiky bylo nezbytné).
Navíc ty dva příklady nejsou ekvivalentní. Zatímco ten příklad s map zapisuje přímo na disky, tak z generátoru lezou obrázky, které mám k disposici jako data v paměti a mám je v iterable. Takže s tím můžu dál dělat nějaká kouzla (třeba vodoznak) a až někdy na konci je můžu uložit a to nejen na disk, ale třeba do db, nebo je poslat po síti přímo klientovi.V paměti je nemáš. Generátor on-demand vytvoří a vydá položku a jakmile na ni ztratíš referenci, může být uvolněna. Jestli thumbnaily generuješ generátorem a smyčkou je pouze zapisuješ, nebo ve smyčce děláš obojí, je totéž.
Mít na každou eventualitu speciální metodu (abych mohl použít map) mě nepřijde jako dobrý návrh.Nerozumím popsanému problému. Ostatně tu knihovnu, kterou jsi zmiňoval, stejně nepoužívám.
Jinak nevidím důvod, proč by si uživatel nemohl nastavit počet threadů v případě, kdy by se jednalo o prostředek jazyka.Protože by to bylo globální pro celý program. Na různé úlohy je smysluplný úplně jiný počet threadů.
Nerozumím popsanému problému.Hmm, nevím jak jinak to vysvětlit. Ve výše uvedeném případu se používají dvě metody.
make_thumbnail
přijme obrazová data a vrátí obrazová data (zmenšený obrázek). S těmi může dále něco dělat, přidat vodoznak, rámeček, cokoliv. Druhá metoda make_write_thumb
jen udělá zmenšeninu a rovnou ji uloží na disk.
Ty metody nejsou ekvivalentní, protože první metoda vrací data (se kterými lze dále pracovat) a druhá rovnou zapíše na disk obrázek a žádná data nevrací. Druhá metoda vznikla jen proto, aby se to lépe paralalelizovalo pomocí pool.map
. Je to špatný návrh, ale viděl jsem to již vícekrát.
Abych se tohoto špatného návrhu zbavil, navrhl jsem paralelní generátor. Celé by to mohlo vypadat třeba takto:
thumbs = (make_thumb(img) for img in images) if mark: thumbs = (add_mark(img) for img in thumbs) if border: thumbs = (add_border(img) for img in thumbs) if stega: thumbs = (ukryj_data(img) for img in thumbs) ...Prostě taková pipeline na zpracování dat, každý generátor by si udělal pár prvků do zásoby, asynchronně ve vedlejších threadech. Ano vím, že častější metoda je:
for img in images: thumb = make_thumb(img) if mark: thumb = add_mark(thumb) if border: thumb = add_border(thumb) ....Ale obecný paralelní
for
mě přijde implementačně ještě náročnější.
Pool.map
, či jak to bylo) a docílit téhož nesrovnatelně lepším způsobem. Vždyť ten první kód je šílená prasárna.
data | parallel neco | filter | paralell neco1 | filter1 | parallel neco2 ...Což se v bashi na reálných binárních souborech dělá dost blbě (navíc se dost blbě přeskakujou jednotlivý kroky té pipeline), protože by se všichni museli domluvit na společném separátoru. V tom pythonu to můžeme mít oddělené rovnou v nějakém iterable. Jako aktuálně to stejně řeším distribuovanou frontou, kam se strkají joby a workeři na to reagují, ale pořád mám pocit, že dělám něco navíc, co by šlo dělat elegantněji.
Stačilo by vzít kód, který jsi uvedl v těle toho for cyklu, a spustit ho v samotném threadu.Celá diskuse je o tom, proč se to neděje automaticky
for
může paralelizovat. (A ano, protože je to těžké, uvedl jsem jako příklad generátor, přičemž na funkci v něm mohou být kladeny stejné podmínky jako v případě pool.map
.)
tam těch threadů poběží dohromady neznámo kolikA proč bych to měl řešit? V erlangu máš běžně miliony těch jejich interních threadů, async io v pythonu jich zvládne tisíce (i když teda navenek jen jako single thread k vůli GIL, takže to se nepoužívá pro CPU bound věci). V OS taky neřeším počet procesů, počet je takový jaký je a scheduler je tady od toho, aby to dokázal rozdělit přes všechny dostupné procesory.
Celá diskuse je o tom, proč se to neděje automatickyJá tomu rozumím, ale snažím se ukázat, že to není tak jednoduché a nutně žádoucí. Kdybych v současném stavu neviděl nedostatky, netvrdil bych před několika dny v jiném vláknu této diskuze, že očekávám vznik jazyků a frameworků, které multithreading usnadní. Sám dlouho zvažuji vytvoření frameworku, který by mi můj způsob práce v Pythonu usnadnil. Určité věcí – a paralelizace mezi ně patří – tam řeším pořád dokola a produkuji boilerplate kód. U toho generátoru jsi mluvil o speciální syntaxi, takže ani ty asi nepovažuješ za dobrý nápad, aby jazyk sám o sobě paralelizoval úplně všechno, kde může dokázat, že to lze. Jaký je tedy rozdíl oproti té funkci, kterou jsem zmiňoval hned na začátku naší debaty? Přitom to rovnou řeší všechny problémy, které jsem zmiňoval: místo heuristiky můžeš v argumentech, klidně nepovinných, uvést maximální délku nebo velikost bufferu a počet threadů. Jestli pro to bude mít jazyk syntaktický cukr považuji za druhořadé. Jeden problém to tedy přecejen má: generátory nejsou thread-safe, takže napsat takovou funkci možná nebude triviální. Nějak to ale řešitelné bude.[...] Pointa je, že chci, aby ten jazyk sám poznal, že tento for může paralelizovat. (A ano, protože je to těžké, uvedl jsem jako příklad generátor, přičemž na funkci v něm mohou být kladeny stejné podmínky jako v případě pool.map.)
A proč bych to měl řešit? V erlangu máš běžně miliony těch jejich interních threadů, async io v pythonu jich zvládne tisíce (i když teda navenek jen jako single thread k vůli GIL, takže to se nepoužívá pro CPU bound věci). V OS taky neřeším počet procesů, počet je takový jaký je a scheduler je tady od toho, aby to dokázal rozdělit přes všechny dostupné procesory.Protože thready představují režii navíc. Mnohokrát jsem se v praxi setkal s tím, že další zvyšování počtu threadů celkový výkon snižovalo (z různých důvodů). To přepínání zkrátka něco stojí a scheduler nemůže vědět, že ten který thread je vlastně zbytečný a když se k lizu nedostane vůbec, nic se nestane. Lightweight thready u CPU-sensitive práce AFAIK nepomůžou.
a() | b() | c()
je ekvivalentní c(b(a()))
, tj. single-thread, ale možná by se z toho dalo vyjít a upravit to, aby se to chovalo podobně jako v tom BASHi (kdyby sis s tím chtěl hrát).
a()
by vracelo stream, b()
by přijímalo a vracelo stream, c()
by přijímalo stream), přičemž interně by a, b, c
běželo ve vlastních threadech. No jenže, tím se nic neřeší a odpovědnost na input output buffer by ze přenesl dovnitř do každé metody a tím je to ještě více zkomplikuje.
No nic, asi zůstanu o unixového přístupu, triviální prográmky dělající jednu věc a budu to paralelizovat externě jako doposud.
stdin
a stdout
), nebo přímo nad jednou položkou (pak se o čtení z fronty a zapisování do fronty stará framework, tj. funkci bude sám volat v nějakém cyklu). Je otázka, v kolika případech by to dávalo smysl.
A taky se ti může stát, že se všechna jádra procesoru rozjedou na plné obrátky a budou generovat jeden thumbnail za druhým. Ale protože nebude stíhat disk, tedy ta smyčka, kterou z toho generátoru chceš, akorát jsi uživateli na nějakou dobu zahltil systém a zaplnil RAM.To nemyslim, že by hrozilo - všechny ty vlákna budou nejspíše zapisovat na disk synchronně, tudíž tohle by nemělo nastat, ne?
Heron navrhoval, že by generátor mohl automaticky běžetTo ano, ale ne do nekonečna. Při vytvoření si klidně může nacachovat nějaký počet položek a při jejich vyčerpání pod určitou mez zase generovat další. (High-Low water mark algorithm). To všechno asynchronně, ať vlákno, které prvky z generátoru zpracovává nemusí na vyrobení dalšího prvku čekat.
protože pokud rychlost čtení z generátoru bude nižší než rychlost generování dalších položek, tak se ti budou nárazově střídat fáze nic nedělání a vytížení CPU na 100 %Tak to je docela normální stav i dnes. Pokud ti nestíhá disk, tak stejně ti program naplní write buffer, počká, naplní, počká. Žádný cpu bound program snad nethrottluje podle toho, jak moc je plný výstupní buffer nebo jak stíhá disk (což se navíc může velice rychle měnit).
Celou diskuzi ovšem shledávám značně nesmyslnou s ohledem na to, že nebyla prezentována jediná praktická výhoda těch paralelizovaných generátorů.Diskuse začala zamyšlením, proč neexistují automaticky multithreading (processing) jazyky, když pomocí primitivních prostředků v bashi toho hravě dosáhnu (ano, nikoliv pro všechny případy, ale spousta dat se dá transformovat tak, aby to šlo). Paralelní implementace generátorů s malým bufferem je jen jeden nápad a ano, v mnoha programech se takto dopředu generují prvky do zásoby aby se na ně potom nemuselo čekat. Viz onen případ prohlížečů obrázků, považuji za naprosto normální, že si prohlížeč nacachuje obrazová data následujících několika obrázků (a nemusel by taky hned dropovat obrázky minulé) a skok na další obrázek provede hned a nezačne jej teprve načítat z disku a dekódovat. Na toto se podobný přístup hodí, můžeš mít generátor s dekódovanými obrázky a když uživatel klikne v gui na next, tak to zobrazit okamžitě.
Parallelismus je predevsim o datatovych zavislostechJistě.
nikoliv o jazyku a implementace kernelu ukazuje to lze implentovat i v CJistě, to ani nikdo netvrdí. Já se na to jen snažím dívat opačně. Podle mě, dostatečným popisem datových struktur by se dalo dosáhnout toho, že programovací jazyk potom může udělat multiprocessing automaticky. Například u toho listu, pokud popíšu, že tyto prvky jsou opravdu na sobě nezávislé, a lze je zpracovávat v libovolném pořadí, tak by mohl jazyk (resp. běhové prostředí) například nahradit map za pool.map a bylo by. Zrovna u toho Rustu bych čekal, že se nějakou takovou cestou vydá. Už teď tam mají hromadu symbolů pro popis vlastnictví apod. těch dat, takže by možná kompilátor mohl dokázat i ledacos paralelizovat, protože ty informace má.
Pouziti | provadi serializaci, umoznuje v pipeline parallelism, ktery je vetsinou znacne limitovany a prilis neskaluje.Tak ono to spíš záleží na tom, kde se to řízne. Ona ta kolona není ani tak o tom, že by to vydrtilo všechny dostupné procesory v jednom onelineru, ale pokud se vhodných způsobem takto rozdělí zpracování dat, může se těch procesorů použít víc. Proto jsem uváděl oba dva typy zpracování, jak roura, tak parallel.
Podle mě, dostatečným popisem datových struktur by se dalo dosáhnout toho, že programovací jazyk potom může udělat multiprocessing automaticky.To bych radsi rovnou presel od imperativnich k funkcionalnim jazykum, jenze problem je stavajici HW.
Například u toho listu, pokud popíšu, že tyto prvky jsou opravdu na sobě nezávislé, a lze je zpracovávat v libovolném pořadí, tak by mohl jazyk (resp. běhové prostředí) například nahradit map za pool.map a bylo by.A neni jednodusi rovnou pouzit pool.map programatorem? Imperativni jazyk, ktery by tohle dokazal bude hodne verbalni a hadam, ze to bude zdroj jinych problemu.
Tak ono to spíš záleží na tom, kde se to řízne.Tam jde o to jestli to muzete riznout, jaka je velikost bloku a zdali operace nad blokem jsou ci nejsou treba ciste iterativni. Nastesti u vetsiny problemu co resime to jde - data rozbit do bloku, algoritmus do sekvence nezavisly kroku, a pak to lze prutokove s prekryvem spustit pres N procesoru.
Parallelismus je predevsim o datatovych zavislostech, nikoliv o jazyku a implementace kernelu ukazuje to lze implentovat i v C.To je chybny uhel pohledu. Otazka nestoji, jestli neco lze implementovat, nebo nelze. Ale otazka zni, jak snadno lze implementovat a s jak velkym rizikem vzniku chyb. Jazyky typu C/C++, kde lze temer kdykoliv menit cokoliv, v tomto smeru programatorovi prilis nepomahaji. Z tohoto pohledu Rust, tlacici na imutabilitu a hlidani zodpovednosti za objekty, jde zrejme dobrou cestou.
Pouziti | provadi serializaci, umoznuje v pipeline parallelismA tomto je. Serializace se postara o nemennost dat, roura z podstaty prilis netrpi na problemy s vedlejsimi efekty, a mas jednoduchy, snadno uchopitelny nastroj pro paralelni vypocet, ktery dokaze pouzit kazdy. A to je smer, kterym by se chtel vydat Heron, pripadne asi i Rust, a ja bych s nimi do jiste miry souhlasil. Chceme-li vytvaret snadno paralelni aplikace, je potreba k tomu mit vhodne nastroj/abstrakce a toho lze pravdepodobne dosahnout jen tim, ze se omezi expresivita jazyka. Otevrenou otazkou zustava, kde udelat tu delici caru...
Serializace se postara o nemennost dat, roura z podstaty prilis netrpi na problemy s vedlejsimi efekty, a mas jednoduchy, snadno uchopitelny nastroj pro paralelni vypocet, ktery dokaze pouzit kazdy.
Pro určitou (z mého pohledu dost omezenou) třídu paralelizovatelných úloh.
Pro určitou (z mého pohledu dost omezenou) třídu paralelizovatelných úloh.To pochopitelne ano, ale hlavni myslenka spociva v tom, ze pokud mas omezeny vypocetni model, paralelizace vubec nemusi bolet a muze ji pouzit (temer) kazdy. Vezmi si takove MapReduce, to je de facto chytrejsi roura, ktera umoznuje resit mnohem sirsi tridu uloh, opet bez nejakeho vetsiho utrpeni pro programatora. Takovy Apache Spark je pro zmenu zase o neco chytrejsi MapReduce, ktery umoznuje pohodlne(ji) resit jeste vetsi tridu uloh, bez toho aniz by to programatora vyrazneji zatezovalo.
To je chybny uhel pohledu. Otazka nestoji, jestli neco lze implementovat, nebo nelze.Pokud neco parallelne implementovat nelze, tak to nelze. I kdyz NC=P je nerozhodnuty problem, vetsina lidi v CS se kloni k zaveru ze exituji tridy algoritmu, ktere parallelizovat nelze.
Ale otazka zni, jak snadno lze implementovat a s jak velkym rizikem vzniku chyb.Pokud to paralellne implementovat lze, programovani je az treti krok. Programovaci jazyk je jen nastroj, lopata, ktery umozni programatorovi lepe ci snadneji pracovat, ale i s primitivnimi nastroji lze dosahnou dobrych vysledku.
A tomto je. Serializace se postara o nemennost dat,Neni. Serializace vam pomuze pokud zpracovavate datove streamy, kde zavislost na predchozich datech je v jednotlivych stupnich zpracovani omezena a velikost bloku dat limitovana. Posunme to do extremu, predstavte si mate algoritmus, jehoz vystup zavisi na vsech predchozich datech stejne. Pak prichod noveho bloku dat znamena ze zacinate s vypoctem znovu a s vetsim objemem dat. Ono i staci, aby vypocet zavisel jen na velkem mnozstvi predchozich dat ci jen vysledku predchoziho bloku, u iterativnich algoritmu (kazdy krok zavisi na predchozim kroku) a udusite se na jednom jadre.
vetsina lidi v CS se kloni k zaveru ze exituji tridy algoritmu, ktere parallelizovat nelze.Je evidentni, ze nektere alogritmy jsou prirozene sekvencni a prostor pro prirozenou paralelizaci tam moc neni.
s primitivnimi nastroji lze dosahnou dobrych vysledkuS timhle pristupem muzeme s klidem zahodit vsechny jazyky s vyssi urovni abstrakce nez jsou instrukce procesoru, protoze se prece da vsechno napsat v assembleru strojovem kodu.
programovaci jazyk je jen nastroj, lopata, ktery umozni programatorovi lepe ci snadneji pracovatTo je ale vcelku podstatny detail. Za chyby v programech muze v drtive vetsine pripadu lidsky faktor a programovaci jazyk by mel mit prostredky, jak temto chybam predchazet. Sam v jinem prispevku pises, ze kod by mel splnovat nejake guidelines, projit code-review, nemel by obsahovat UB, mel by prochazet statickou analyzou. Tak proc je tak spatne mit tyto veci soucasti specifikace jazyka?
Daleko casteji jsem v situaci, kdy vyvojari maji casovy slot, 4-8 jader, k dispozici cast FPGA, definovanou DDR bandwidth a nejsou schopni to plne vyuzit,Toto je hodne specificka nika low-level vyvoje a mam znacne pochybnosti, jestli cokoliv z toho lze zobecnit na problemy vyvoje bezneho software.
Neni. Serializace vam pomuze pokud zpracovavate datove streamy, kde zavislost na predchozich datech je v jednotlivych stupnich zpracovani omezena a velikost bloku dat limitovanaViz #117
Tak proc je tak spatne mit tyto veci soucasti specifikace jazyka?
Protože každé pravidlo má své výjimky. A jednou za čas se prostě dostanete do situace, kdy vás požadavek na striktní dodržení těch pravidel donutí vytvořit něco, co je nečitelné a navíc ještě neefektivní.
sun.misc.Unsafe
. Nebo implementaci Pythonu a časté používání C extensions v Python ekosystému. Něco podobného platí o JS. A tak dále... Ty důvody pro tohle jsi tady vlastně i sám částečně popsal.
Vem v úvahu třeba vnitřnosti Javy a používání sun.misc.Unsafe
.
To je dost hloupý článek – zcela neopodstatněně přehání. Unsafe by AFAIK bylo možné plnohodnotně nahradit JNI, čili jeho řeči o tom, jak by to naprosto zničilo Java ekosystém, jsou krajně mimo. Pokud by to opravdu nešlo nahradit a Oracle tu třídu přesto zcela odstranil, jednoduše by ji někdo zabalil jako samostatnou nativní knihovnu. Řeči o rozbití zpětné kompatibility a dokonce přirovnávání k situaci u Pythonu 2/3, je už jen zoufalá snaha o senzaci, nebo nadmíru špatný úsudek, pakliže hovoříme o neveřejném API. Autor toho článku by si mohl založit IT bulvár.
Unsafe nebo JNI, to vyjde nastejno, obojí jsou mechanismy pro obcházení bezpečnostních fíčur Javy.Nikoliv. JNI je mechanismus pro spojování JVM se zbytkem světa. Unsafe poskytuje přístup k nějakým low-level věcem přímo z Javy. S obcházením bezpečnostních prvků jazyka to na rozdíl od Rustu nemá společného skoro nic. A ostatně to, že ta třída je nezdokumentovaná, podstatná část těch metod je oanotována jako deprecated a vedla se diskuze o jejím odstranění vypovídá něco o tom, jak důležitou roli hraje.
unsafe
nutně něco špatně. Pořád je jednodušší ohlídat si chyby na pár místech uvnitř unsafe
bloku než všude. Ale o Rustu nic nevím, tak nejsem schopen ho hodnotit jako celek.
Ta paměťová nebezpečnost ovšem není cílem, ale vedlejším účinkem. Já bych to nesrovnával.No, ona ta nebezpečnost
unsafe
v Rustu taky není cílem per se, kdo by chtěl mít nebezpečný kód jen tak pro nic za nic, že. Typicky jde o dosažení výkonu a/nebo interakci s OS, hardware, C knihovnami apod., což mi přijde podobné jako účel JNI.
Máš ale pravdu v tom, že v Rustu to je součást jazyka a interaguje se zbytkem jazyke. To je hlavně dané tím, že Rust je určený mimo jiné k tomu, aby v něm mohl být napsán Rust nebo podobné věci, tj. víceméně cokoli, zatímco VM Javy je v C++, Java tohle nemusí řešit.
S timhle pristupem muzeme s klidem zahodit vsechny jazyky s vyssi urovni abstrakce nez jsou instrukce procesoru, protoze se prece da vsechno napsat v assembleru strojovem kodu.Zbytecna extrapolace.
Tak proc je tak spatne mit tyto veci soucasti specifikace jazyka?Nerikam, ze je to spatne. Rikam tyhle veci jsou uz k dispoci i pro C/C++, byt ne soucast standardu a je to jeden z duvodu proc pridana hodnota Rustu neni v praxi natolik velka. Na Ade ilustruji, ze tyhle veci navic nestaci, a to Ada/SPARK je formalne verikovana a verifikovatelna, a Rust neni. Ohledne rolling specifikace Rustu ... dokud to nebude mit stabilni standard a implementaci, C/C++ v rade oblasti nenahradi.
Toto je hodne specificka nika low-level vyvoje a mam znacne pochybnosti, jestli cokoliv z toho lze zobecnit na problemy vyvoje bezneho software.Jenze to je ale presne domena, kam se Rust sam pasuje: "Rust is a systems programming language" - a podstatna cast systemoveho programovani low-level vyvoj.
Zbytecna extrapolace.Ani ne. Mně přesně totéž napado, když jsem četl tvůj příspěvek...
Rikam tyhle veci jsou uz k dispoci i pro C/C++, byt ne soucast standarduNapř.?
Ani ne. Mně přesně totéž napado, když jsem četl tvůj příspěvek...A me zase napada britske prislovi: A bad workman always blames his tools.
Např.?Co Napr.? Treba ze jako nemame nastroje pro statickou analyzu kodu?
A me zase napada britske prislovi: A bad workman always blames his tools.Tohle přísloví se v diskusích o jazycích často používá pro 'morální relativizaci' vlastností jazyků ve snaze zabránit jejich srovnávání. Úplně nejčastěji to slýchávám jako argument pro PHP. Že to prý to je dobrý jazyk, že akorát programátoři ho špatně používají a pak si na něj blbě stěžují. To už jsem slyšel tolikrát, že už to ani není vtipné.
Co Napr.? Treba ze jako nemame nastroje pro statickou analyzu kodu?Tím jsem myslel jaký např. bys doporučil nástroj pro statickou analýzu, který by mě v C++ mohl dostat někam tím směrem, kterým jde Rust.
To už jsem slyšel tolikrát, že už to ani není vtipnéJa mam podobny pocit, kdyz slysim jak v C/C++ nelze psat bezpecny MT kod a Rust to zachrani.
Tím jsem myslel jaký např. bys doporučil nástroj pro statickou analýzu, který by mě v C++ mohl dostat někam tím směrem, kterým jde Rust.Nase situace je trochu specificka a vsechny nastroje, ktere pouzivame, vcetne kompilatoru musi byt certifikovane. Kazdy projekt ma jine pozadavky a dohodnute nastroje ze zakaznikem, ale napriklad pouzivame nastroje od QA Systems (QA-C++, QA-Misra, QA-Verify), ktere se dobre integruji s Autosarem. K tomu mame in-house developed nastroje postavene na clang static analyser (dodelane restrikce a kompatibilita s Autosar), address sanitiser, integrovany Valgrind a pouzivame i Code Analysis z VS2017, ale nic z toho neni certifikovano. Dalsi nastroje pocitaji metriky, analyzujici memory map, callgraph a stacky, simuluji asynchronni HW udalosti. Vse integrovano do CI, vcetne SIL/HIL. Jedna z nejlepsich cest jak objevit problemy, je pouzit ruzne kompilatory od ruznych implementatoru C/C++ standardu.
Ja mam podobny pocit, kdyz slysim jak v C/C++ nelze psat bezpecny MT kod a Rust to zachrani.Já nepsal, že by to nešlo (ono to jde), ale že to je za trest. Což je samozřejmě subjektivní... Taky v to úplně nepočítám kernel kód, tam je s jistým nekomfortem potřeba počítat, i když vylepšení by se tam určitě taky daly udělat...
Nase situace je trochu specificka a vsechny nastroje, ktere pouzivame, vcetne kompilatoru musi byt certifikovane. Kazdy projekt ma jine pozadavky a dohodnute nastroje ze zakaznikem, ale napriklad pouzivame nastroje od QA Systems (QA-C++, QA-Misra, QA-Verify), ktere se dobre integruji s Autosarem. K tomu mame in-house developed nastroje postavene na clang static analyser (dodelane restrikce a kompatibilita s Autosar), address sanitiser, integrovany Valgrind a pouzivame i Code Analysis z VS2017, ale nic z toho neni certifikovano. Dalsi nastroje pocitaji metriky, analyzujici memory map, callgraph a stacky, simuluji asynchronni HW udalosti. Vse integrovano do CI, vcetne SIL/HIL.Uff. Díky za info. V takovéhle situaci by mě ani nenapadlo vůbec o Rustu uvažovat jako o možnosti. Stejně tak ale mi tento setup nepřijde úplně feasible pro spoustu projektů, zejména FOSS. To je velká a (hádám) drahá infrastruktura. Mam z minulosti zkušenost s nástrojem Parfait od Sunu (který asi bude už dneska mrtvý, protože Oracle), nebylo to špatné a umělo to odhalit všelijaké chyby, ale Rustu se to neblížilo ani zdaleka...
Stejně tak ale mi tento setup nepřijde úplně feasible pro spoustu projektů, zejména FOSSVe FOSSu se da dobre testovat bez narocne infrastruktury. Ukazkovym prikladem je SQLite - viz. zde. Hned prvni veta:
As of version 3.23.0 (2018-04-02), the SQLite library consists of approximately 128.9 KSLOC of C code. (KSLOC means thousands of "Source Lines Of Code" or, in other words, lines of code excluding blank lines and comments.) By comparison, the project has 711 times as much test code and test scripts - 91772.0 KSLOC.naznaci rozdil.
Počkat, to je ale testování, tj. jiné téma než statický analýza.Je to jen ukazka toho, ze FOSS projekt muze mit velmi dobrou a levnou testovaci infrastrukturu.
Dokonce tam i píšou, že pro ně není statická analýza moc užitečná.Protoze podstatna cast problemu SW je oblasti, ktera se statickou analyzou nepokryje, narozdil od intenzivniho [unit] testingu ci treba runtime [fuzzy] testu.
Jinak tuhle stránku už jsem viděl nalinkovanou mnohokrát z podobných diskusí, je to takový céčkařův svatý grál.To neni o programovacim jazyku, to je o pristupu ke tvorbe SW a jestli je to napsane C, C++ ci Rustu neni az tak podstatne.
Protoze podstatna cast problemu SW je oblasti, ktera se statickou analyzou nepokryje, narozdil od intenzivniho [unit] testingu ci treba runtime [fuzzy] testu.Tak zrovna ty race conditions se testují dost blbě a IMHO se naopak lépe pokryjí statickou analýzou á la Rust.
What do you think of the projects currently underway to develop OS kernels in languages like Rust (touted for having built-in safeties that C does not)?
That's not a new phenomenon at all. We've had the system people who used Modula-2 or Ada, and I have to say Rust looks a lot better than either of those two disasters.
I'm not convinced about Rust for an OS kernel (there's a lot more to system programming than the kernel, though), but at the same time there is no question that C has a lot of limitations.
To anyone who wants to build their own kernel from scratch, I can just wish them luck. It's a huge project, and I don't think you actually solve any of the really hard kernel problems with your choice of programming language. The big problems tend to be about hardware support (all those drivers, all the odd details about different platforms, all the subtleties in memory management and resource accounting), and anybody who thinks that the choice of language simplifies those things a lot is likely to be very disappointed.
Nicmene vetsina race conditions u systemoveho programovani je zpusobena interakci s HWNesouhlasim. Respektive nevim, co si pod tím pojmem představuješ ty (on je to hodně vágní pojem), ale cílovka Rustu je víceméně jakákoli vrstva, kde si nemůžeš z důvodu zachování výkonu dovolit GC a další overhead spojený s použitím vysokoúrovňových jazyků. To znamená třeba i různé démony atp.
interakci s HW (interrupty, DMA, caches, memory mapped HW/registers etc.) a tam vam nepomuze.Pro alespoň část těchto mechanismů mohou existovat abstrakce/wrappery využívající borrowck nebo jiné fíčury jazyka, podobně jako třeba existují abstrakce pro C++ využívající fíčury jazyka (RAII apod.). Viděl jsem nějaké takové první vlaštovky např. pro interakci s GPIO.
Pokud jde o race conditions na "normalnich" datech sdilenych mezi thready, staci dodrzovat par zakladnich veci (...)To je stále dokola o tom samém, co už psal děda jabko. Jasně, že to jde. Koneckonců paměťovou korektnost taky lze mít - stačí "dodržovat pár základních věcí" jako např. mít jasný ownership model, vědět jaký má co lifetime, jak je který buffer velký a např. vytvořit API k přístupu... atd. atd. Ono s jakýmkoli turing-complete jazykem vždycky všechno jde a vždycky stačí "jen dodržovat pár základních věcí". Ta pointa není v tom, že za tebe Rust něco udělá nebo vyřeší nějaký návrh nebo tak něco, ale v tom, že kontroluje, jestli "dodržuješ pár základních věcí" a když ne, tak tě upozorní, to je celé.
Linus to popsal zde, kde se vyjadruje k budoucnosti Linuxu a moznosti psat kernel v Rustu - a to bych podepsal:To může podepsat víceméně kdokoli vzhledem k tomu, že to je celkem velmi zjevné. Linus je trochu Cpt. Obvious v této citaci.
Ok, ale proč tohle není součástí jazyka? Dovedu si představit automaticky paralelní list comprehension (nebo možná ještě lépe generátor), který, pokud může dokázat (to je podmínka i pro Pool.map) že volaná funkce nemá žádné vedlejší efekty (k čemuž mimochodem Python vede programátora od počátku), tak to provede paralelně.Rust tohle umí pomocí knihovny rayon, která v zásadě jen využívá vestavěných fíčur jazyka (borrowchecker pro kontrolu side-efektů, traits) a standardní knihovny (iterátory) a doplňuje je o platform-specifika (určení vhodného počtu threadů apod.). Např. jsem nedávno implementoval dávkové zpracování obrázků do jednoho prográmku a paralelizovat to bylo s touhle knihovnou naprostá hračka. Jinak na vyšší úrovni se na tyhle věcí používá asynchronní programování a to není vůbec snadné nějak dobře namodelovat za splnění všelijakých podmínek. Existuje např. Actor model, který IIRC hodně používá Scala. Pak jsou korutiny, které integrované třeba Go. V Rustu se vyvíjí mírně neobvklé pojetí Futures, které má slibný výkon, ale přijde mi to hrozně nedotažené na programátorské straně. Celkově každé to řešení má nějaké nevýhody, typicky čím to je příjemnější pro programátora, tím je větší overhead.
Např. jsem nedávno implementoval dávkové zpracování obrázků do jednoho prográmku a paralelizovat to bylo s touhle knihovnou naprostá hračka.Já používám
pool.map
na něco podobného, na obrázky taky, ale tam mám už roky vytvořené skriptíky s find | parallel convert
a optipng
apod.
Galerie obrázků jsou vůbec kapitola sama pro sebe. Asi už nelze mít více nezávislé balíky dat, než jsou jednotlivé obrázky (nebo obecně multimediální soubory) a přesto je spousta galerií napsaná jako single thread. Vlastně jediná, u které jsem si všiml masivnějšího paralelismu, je sigal.
O GUI prohlížečích obrázků raději nehovořit. Cachovat (dekódovat do paměti) následující obrázek umělo už DOSové ACDSee a v roce 2018 stále musím čekat při přechodu na následující obrázek. O paralelním vytváření náhledů si taky můžeme nechat jen zdát. No nic, škoda se rozčilovat.
Bylo to levnější než Intel, ale výkonem jádra to za ním silně zaostávalo
Jak se to vezme. V době, kdy přišly na trh (a ještě docela dlouho poté) stál osmijádrový Bulldozer přibližně polovinu toho, co čtyřjádrové procesory Intelu s podobným výkonem. Pokud někoho zajímal primárně výkon v jednothreadových aplikacích, tak mu samozřejmě nezbylo než pořídit ten Intel - ale pro toho osmijádrové procesory tak jako tak určené nejsou.
chybělo GPU
Což byl záměr a osobně jsem za to byl moc rád.
a přesto to mělo šílený odběr
Šílený odběr měl jen ten jeden úletový model s TDP asi 220 W. Třeba FX-8150, kterou mám dodnes, měla maximální spotřebu při plné zátěži 125 W, šestijádra (a IIRC i jedno osmijádro) 95 W. Měly snad tehdejší modely Intelu se srovnatelným výkonem nějak výrazně méně?
Ve špatně paralelizovatelných úlohách, kde se neustále bude řešit synchronizace a zámky
Ne všude, kde se hodně času stráví čekáním na zámky, je to opravdu nutné. Třeba v linuxovém síťovém stacku najdete spoustu míst, kde dřív byl prostě spinlock, protože to tak bylo nejjednodušší a při malém počtu procesorů to nijak nevadilo, ale jak procesorů přibývalo, bylo potřeba přejít buď na jemnější zamykání, RCU nebo úplně lockless algoritmy. Jsou místa, kde i k použití atomické proměnné musíte mít sakra dobrý důvod, protože by to byla brzda.
Otázkou zůstává, proč by to mělo úzce souviset s tím, že Intel prosazoval čtyřjádrové procesory. Pokud se nevyplatilo začít se věnovat paralelizaci na čtyřjádře, na osmi-, šestnácti- či dvaatřiceti- jádře se to už vyplatí?
Ano, přesně tak to je. Jak už jsem psal výše, pokud máte před očima dva nebo čtyři procesory, může být praktičtější na ně přímo rozdělit úlohy tak, aby spolu moc nekolidovaly. Když musíte počítat s tím, že ten software poběží na desítkách procesorů, je úroveň konkurence úplně někde jinde a řešení, které bylo pro dva nebo čtyři "dost dobré", se může rychle stát nepoužitelným. A to nemluvím o tom, že Linux dnes běhá i na systémech, kde jsou ty počty v tisících; ty se sice zatím obvykle používají dost specifickým způsobem, ale s vyššími desítkami nebo nižšími stovkami už vážně počítat musíte.
stál osmijádrový Bulldozer přibližně polovinu toho, co čtyřjádrové procesory Intelu s podobným výkonemAno, to je pravda. Však jsem psal, že to bylo levnější než Intel; uznávám, že cenu za jednotku výkonu mělo AMD lepší.
Což byl záměr a osobně jsem za to byl moc rád.To už samozřejmě záleží na požadavacích toho kterého zákazníka. Pokud si v případě Intelu vystačí s integrovaným GPU, u AMD by bylo potřeba připočíst cenu za srovnatelnou grafickou kartu. Naopak zákazník, kterému integrované GPU stejně nestačí, by vlastně platil za něco, co nevyužije (kromě havárií, kdy integrovanou GPU použije jako záložní).
Třeba FX-8150, kterou mám dodnes, měla maximální spotřebu při plné zátěži 125 W, šestijádra (a IIRC i jedno osmijádro) 95 W.Ano, to jsem měl na mysli. Patrně jsem si ovšem chybně pamatoval spotřebu tehdejších Intelů, protože jsem měl za to, že maximální spotřeba byla 65 W. Co se teď dívám, dokonce i udávaná „průměrná“ spotřeba je vyšší. Porovnával jsem tedy zřejmě minimální a maximální spotřebu. Za to se omlouvám a poznámku o šíleném odběru beru zpět.
Ne všude, kde se hodně času stráví čekáním na zámky, je to opravdu nutné.To nerozporuji. Spíš jsem chtěl říct, že nejlepším kandidátem na paralelizaci jsou ty úlohy, které běží co možná nejvíce nezávisle na sobě (a co nejdéle). Spoustu úloh sice teoreticky paralelizovat lze, ale v praxi se zkrátka nevyplatí to dělat. Někde se to vyplatit může, ale zrychlení bude relativně malé a cenou za to bude ta zvýšená komplexita programu. Proto ostatně očekávám ten příchod nových jazyků či frameworků, které jejich psaní usnadní (a nebo se prostě ukotví nová paradigmata a best practices a těch jazykových změn potřeba ani tolik nebude).
Když musíte počítat s tím, že ten software poběží na desítkách procesorů, je úroveň konkurence úplně někde jinde a řešení, které bylo pro dva nebo čtyři "dost dobré", se může rychle stát nepoužitelným. A to nemluvím o tom, že Linux dnes běhá i na systémech, kde jsou ty počty v tisících; ty se sice zatím obvykle používají dost specifickým způsobem, ale s vyššími desítkami nebo nižšími stovkami už vážně počítat musíte.Měl jsem na mysli převážně desktopové systémy, kde si asi dost dobře nedokážu představit scénář, kde by se skutečně nevyplatilo single-threaded aplikaci rozdělit alespoň na dva thready, ale vyplatilo by se architekturu překopat ještě radikálněji a umožnit škálování na libovolný počet threadů. Abych to řekl ještě jinak: Těch single-threaded programů, které by zasloužily alespoň tam, kde to jde snadno a přímo se k tomu vybízí, rozdělit na více threadů, je dodnes mnoho a nikdo se nemá k tomu je upravit. V tomto kontextu nerozumím, co by příchod (n > 4)-jádrových CPU měl zásadně změnit. Uznávám, že Max mluvil o nových herních enginech, které se uzpůsobí novému hardwaru. To nerozporuji, jen zpochybňuji, že Intel něco „brzdil“.
Měl jsem na mysli převážně desktopové systémy
Rozumím, ale právě proto, že výkonnější desktopové procesory se dnes počtem jader dostávají tam, kde před pár lety byly serverové a před více lety víceprocesorové servery, je IMHO na místě očekávat, že leccos z vývoje, který tehdy proběhl tam, se bude opakovat i u desktopů.
kde si asi dost dobře nedokážu představit scénář, kde by se skutečně nevyplatilo single-threaded aplikaci rozdělit alespoň na dva thready, ale vyplatilo by se architekturu překopat ještě radikálněji a umožnit škálování na libovolný počet threadů
Jsou úlohy, kde je rozdíl v náročnosti rozdělení na malý fixní počet threadů a na obecný počet (případně ne úplně obecný, ale řekněme do desítek) poměrně malý (nebo dokonce vůbec žádný). Pokud víte, že většina vašich uživatelů má dvě jádra a jen mizivé procento víc než čtyři, rozhodujete se vlastně, jestli určité množství práce investujete do zrychlení programu na (ideálně) dvojnásobek. Když budete vědět, že nemalé procento má nebo brzy bude mít jader 8, 16 nebo 32, rozhodujete se, jestli stejné (nebo o něco větší) množství práce investujete do toho, aby váš program běžel o řád (či více) rychleji. A to může mít dost zásadní vliv na rozhodnutí, jestli se to vyplatí.
Rozumím, ale právě proto, že výkonnější desktopové procesory se dnes počtem jader dostávají tam, kde před pár lety byly serverové a před více lety víceprocesorové servery, je IMHO na místě očekávat, že leccos z vývoje, který tehdy proběhl tam, se bude opakovat i u desktopů.Souhlasím.
Jsou úlohy, kde je rozdíl v náročnosti rozdělení na malý fixní počet threadů a na obecný počet (případně ne úplně obecný, ale řekněme do desítek) poměrně malý (nebo dokonce vůbec žádný). Pokud víte, že většina vašich uživatelů má dvě jádra a jen mizivé procento víc než čtyři, rozhodujete se vlastně, jestli určité množství práce investujete do zrychlení programu na (ideálně) dvojnásobek. Když budete vědět, že nemalé procento má nebo brzy bude mít jader 8, 16 nebo 32, rozhodujete se, jestli stejné (nebo o něco větší) množství práce investujete do toho, aby váš program běžel o řád (či více) rychleji. A to může mít dost zásadní vliv na rozhodnutí, jestli se to vyplatí.Vidím to trochu jinak. Zatím stále výkon jednotlivých jader rostl (sice se růst zpomaloval, ale nějaká zlepšení tam byla stále – bohužel to mělo i stinné stránky, jak vidno díky Meltdown a Spectre). Jakmile se ten růst zastaví nebo zpomalí ještě víc (nebo v extrémním případě klesne do záporných hodnot právě kvůli opravám chyb), jedinou cestou, jak vytřískat víc výkonu, bude právě paralelizace. V tu chvíli by se tomu začal uzpůsobovat vývoj software tak jako tak, i kdyby jader nepřibývalo a zůstalo třeba u těch čtyř. V praxi výrobci počty jader samozřejmě zvyšovat začnou, takže tyhle dvě věci se stanou souběžně.
Zatím stále výkon jednotlivých jader rostl (sice se růst zpomaloval, ale nějaká zlepšení tam byla stále).
Posledních 10 let je ten růst tak pomalý, že v podstatě nestojí za řeč.
Jakmile se ten růst zastaví… jedinou cestou, jak vytřískat víc výkonu, bude právě paralelizace. V tu chvíli by se tomu začal uzpůsobovat vývoj software tak jako tak, i kdyby jader nepřibývalo a zůstalo třeba u těch čtyř.
První čtyřjádrový procesor jsem si pořídil někdy v roce 2008, možná o něco dřív (mimochodem, v jednom počítači ho mám dodnes). Že by se od té doby zvýšil výkon na jádro čtyřikrát, to bych se tvrdit rozhodně neodvážil. Takže už před deseti lety bylo možné paralelizací na běžný, nikterak high-end, procesor docílit stejného zrychlení, na jaké bylo bez paralelizace třeba čekat deset let. Kdyby vaše teorie fungovala, tak ten okamžik, o kterém mluvíte, už dávno nastal.
Posledních 10 let je ten růst tak pomalý, že v podstatě nestojí za řeč. [...] Že by se od té doby zvýšil výkon na jádro čtyřikrát, to bych se tvrdit rozhodně neodvážil.Čtyřikrát ne, ale zhruba 2× ano. Dal jsem pár minut tomu, abych našel nějaká data. Pokud někdo máte lepší zdroj, budu jen rád. Vyhledal jsem na ark.intel.com (víceméně náhodně) dva desktopové procesory ve srovnatelné cenové relaci (při zanedbání inflace). Prvním byl Intel Core 2 Duo E7400 (2008/Q1, doporučená prodejní cena 125 USD), druhým pak Intel Core i3-8100T (2018/Q2, doporučená prodejní cena 117 USD – tedy o 8 USD levnější než ten starší). Benchmark – netuším, jak dobrý – jsem našel na serveru Geekbench. V případě staršího CPU uvádí single-core výkon 1657, u novějšího pak 3537 až 4128. Proč se mi jednou podařilo nalézt výsledky přímo pro daný CPU a podruhé srovnávají celé počítače, ve kterých je osazen, nevím; rovněž se mi nelíbí rozsah těch hodnot ve druhém případě, protože tak velkou variabilitu bych u dobrého CPU benchmarku ani u různých strojů asi nečekal. Takže jak říkám: pokud někdo máte lepší zdroj, sem s ním.
Takže už před deseti lety bylo možné paralelizací na běžný, nikterak high-end, procesor docílit stejného zrychlení, na jaké bylo bez paralelizace třeba čekat deset let. Kdyby vaše teorie fungovala, tak ten okamžik, o kterém mluvíte, už dávno nastal.Je třeba vzít v úvahu, že také vzrostla poptávka po programátorech a cena jejich času. Výkon se stále postupně zvyšoval i bez dodatečných úprav softwaru (a to nejen u CPU, ale také se třeba přecházelo na rychlejší disky, což zákazníkům mohlo dát subjektivně lepší pocit i přesto, že určité úlohy trvají stále skoro stejnou dobu). Možná se zkrátka vyplatilo zákazníkům říct, ať si – pokud to potřebují – připlatí za dražší procesor, kde předpokládám, že ten rozdíl ve výkonu na jádro může být ještě o dost větší (ale to už se mi opravdu dohledávat nechce). Moje hypotéza byla, že až se zkrátka narazí na strop, kdy už spoléhat na zvyšující se výkon jednoho jádra nepůjde, naopak možná začne i klesat (opravy chyb, optimalizace spotřeby v přenosných zařízeních, …), a začne být poptávka po větším zrychlení, tak pak se tomu začne software uzpůsobovat. Ale je to samozřejmě jen čirá spekulace a je docela dobře možné, že se prostě mýlím. Nakonec na tom možná ani tolik nezáleží, protože výsledek – tedy sílící trend paralelizace – předvídáme stejný.
Čtyřikrát ne, ale zhruba 2× ano.
Tím spíš to podporuje, co jsem napsal.
Moje hypotéza byla, že až se zkrátka narazí na strop, kdy už spoléhat na zvyšující se výkon jednoho jádra nepůjde…
A já tvrdím, že na ten strop už jsme de facto narazili před nějakými 5-10 lety. Není to sice tvrdý strop (dosud se to zrychlovalo rovnoměrně a od teď najednou a ni o píď), ale to asi nikdo čekat nemohl. Pokud deset let vývoje přineslo zrychlení na něco jako dvojnásobek, tak IMHO doba,
kdy už spoléhat na zvyšující se výkon jednoho jádra nepůjde
už je nějakou dobu tady.
Naopak zákazník, kterému integrované GPU stejně nestačí, by vlastně platil za něco, co nevyužije (kromě havárií, kdy integrovanou GPU použije jako záložní).Pokud funguje přepínání grafiky, integrovanou grafiku využijí i lidi s dedikovanou pro úsporu energie. Tomu záměru/požadavku nemít integrované GPU, přestože technologie to umožňuje, moc nerozumim. Jaké to má výhody?
Pokud funguje přepínání grafiky, integrovanou grafiku využijí i lidi s dedikovanou pro úsporu energie.Pravda.
Tomu záměru/požadavku nemít integrované GPU, přestože technologie to umožňuje, moc nerozumim. Jaké to má výhody?Také nevím.
Pokud funguje přepínání grafiky, integrovanou grafiku využijí i lidi s dedikovanou pro úsporu energie.No, nevím jak na Linuxu, ale tohle na Windows funguje jenom v noteboocích.
Tomu záměru/požadavku nemít integrované GPU, přestože technologie to umožňuje, moc nerozumim. Jaké to má výhody?Myslim, ze ta odpoved je celkom jednoznacna - vyssia cena. Zvysuje to plochu daneho cipu, co zvysuje chybovost a znizuje vytaznost vo vyrobe. To samo o sebe sa musi na cene odrazit. Dalej tam celkom urcite budu patentove poplatky a ktovie co este. Plus ak sa ta GPU pokazi, tak ju zvycajne musis menit aj s CPU. To hovorim ako clovek ktory ma doma asi 7 procesorov s integrovanym GPU z toho 5 od Intelu.
Ano, přesně tak to je. Jak už jsem psal výše, pokud máte před očima dva nebo čtyři procesory, může být praktičtější na ně přímo rozdělit úlohy tak, aby spolu moc nekolidovaly. Když musíte počítat s tím, že ten software poběží na desítkách procesorů, je úroveň konkurence úplně někde jinde a řešení, které bylo pro dva nebo čtyři "dost dobré", se může rychle stát nepoužitelným.Ano. Ted pracuji na architekture/designu projektu, kde mame (8-16)+1 procesorovych jader v jednom SoC a nejrozumenjsi reseni je napsat scheduler, ktery nove spustene workery prirazuje volnym procesorum. Uz jen ASIL B sice trochu skripe, ale je to nejlepsi cesta jak vyuzit limitovane zdroje.
Mně vždycky přišlo že tučňák potřebuje hlavně pořádnou RAM, tak jsem před lety koupil 16GB s úvahou jestli rovnou nevzít 32GB ("hmm, komplet systém v RAM, to by lítalo!"). Určitě nebyla nejrychlejší a šel jsem spíš po ceně, ale proti předchozímu stroji se 4GB RAM to je nebe a dudy. Jak to má kam cachovat, tak to trhá asfalt i se starým pre-Ryzen pre-GCN APU.
A aby se neřeklo, tak v Palemoonu běžně 200 záložek z redditu, občas 600-1200 z jiných webů, převážně obrázky na jednodušších stránkách bez JS. Ano, Palemoon jede jen v jednom threadu. A když se náhodou zadýchá, tak mám alespoň jistotu, že na všechno ostatní mám další tři jádra.
To je pravda. Jen jsem chtěl poukázat na to, že množství RAM mívá větší vliv, než si někteří myslí
asi bych spíš řekl ekonomický než sociálníS tim bych prave asi polemizoval. Zalezi, jestli bereme treba ekonomickou externalitu jako problem ekonomicky nebo socialni. Napriklad, autor programu muze usetrit cas, ale za cenu, ze celkovy dopad na ekonomiku (spotrebovana energie a cas v dusledku sirokeho pouziti nekvalitniho programu) bude mnohem vyssi. Ale z hlediska firmy, pro kterou pracuje, a pro kterou jde jen o externalitu, to usetreni bude davat smysl. Konecne, hraje zde roli neco jako Jevonsuv paradox. Ja myslim, ze to je spis socialni nez ekonomicky problem.
Napriklad, autor programu muze usetrit cas, ale za cenu, ze celkovy dopad na ekonomiku (spotrebovana energie a cas v dusledku sirokeho pouziti nekvalitniho programu) bude mnohem vyssi. Ale z hlediska firmy, pro kterou pracuje, a pro kterou jde jen o externalitu, to usetreni bude davat smysl.
Pokud se ten program používá v rámci stejné firmy, tak je potřeba to zahrnout do té ekonomické rozvahy. Pokud se používá jinde, pak se to tam promítne ve formě rizika, že zákazník přejde ke konkurenci.
Nakonec i u toho hobby projektu stojíte často před volbou, zda čas, který máte k dispozici, bude vhodnější věnovat vyšší efektivitě nebo třeba implementaci nové funkce a co uživatelé ocení víc.
Napriklad, autor programu muze usetrit cas, ale za cenu, ze celkovy dopad na ekonomiku (spotrebovana energie a cas v dusledku sirokeho pouziti nekvalitniho programu) bude mnohem vyssi.Zajímavé je tohle zamyšlení třeba u browserů (poslední dobou bloated rozežrané nabobtnané hrůzy), kde se každá neefektivita násobí miliardou instalací.
Ano, paralelni a vicevlaknove programovani jsou technicky narocnejsi. Totez plati pro programovani, ktere efektivne vyuziva prostredku pocitace.On je tam problem i psychologicky. Pro paralelni programovani je casto vyhodne pri programovani plytvat nebo pouzivat struktury, ktere pro jednovlaknove aplikace nejsou nejefektivnejsi. Rada programatoru se tomu plytvavemu stylu podvedome brani (a na rovinu reknu, ze nejsem vyjimka). Na jednu stranu, kdyz clovek zacne vytvaret kopie dat pro kazde vlakno, zacne mu v hlave blikat vystraha, ze to je neefektivni (i kdyz v realu to muze byt zanedbatelne). Na druhou stranu, kdyz ma nejakou strukturu obklopenou zamkem, zadna takova vystraha se nejspis neozve a spis se uklidni, ze to asi bude dobre, kdyz to osefoval tim zamkem (pricemz dopad na vykon muze byt desivy).
Tiskni
Sdílej:
ISSN 1214-1267, (c) 1999-2007 Stickfish s.r.o.