Parallisme in Julia: ondersteuning voor native threading

In hun arXiv papervermelden de oorspronkelijke auteurs van Julia het volgende:

2.14 Parallelism.
Parallelle uitvoering wordt verzorgd door een op berichten gebaseerd multiverwerkingssysteem dat in Julia in de standaardbibliotheek is geïmplementeerd.
Het taalontwerp ondersteunt de implementatie van dergelijke bibliotheken door:
het verstrekken van symmetrische coroutines, die ook kunnen worden gezien als:
coöperatief geplande threads. Deze functie maakt asynchrone
communicatie moet worden verborgen in bibliotheken, in plaats van dat de
gebruiker terugbellen instellen. Julia ondersteunt momenteel geen native
threads, wat een beperking is, maar het voordeel heeft dat de
complexiteit van gesynchroniseerd gebruik van gedeeld geheugen.

Wat bedoelen ze met te zeggen dat Julia native threadsniet ondersteunt? Wat is een native thread?

Ondersteunen andere geïnterpreteerde talen zoals Pythonof Rdit type parallellisme? Staat Julia hierin alleen?


Antwoord 1, autoriteit 100%

Bijwerken

Toen deze vraag in 2013 werd gesteld, had Julia inderdaad geen ondersteuning voor multithreading. Tegenwoordig ondersteunt Julia echter native threading met wat naar voren is gekomen als het beste taalmodel voor composable thread-programmering. Dit model is ontwikkeld door Cilk en Intel’s Threading Building Blocks, verder op taalniveau gebracht door Go en wordt nu ook gebruikt door Julia. Verklaringen in het oorspronkelijke antwoord hieronder over andere dynamische talen blijven waar: ze ondersteunen nog steeds geen native threading met ondersteuning voor parallelle uitvoering van gebruikerscode. De geschiedenis van het toevoegen van threading-mogelijkheden aan Julia verliep in de volgende fasen op hoog niveau:

  • Julia 0.3:ondersteuning voor native threads met een OpenMP-achtig rekenmodel (d.w.z. parallel for loops). Deze functionaliteit was zeer beperkt: er was geen I/O of netwerken toegestaan ​​in parallelle code.

  • Julia 1.3:volledig configureerbare, krachtige M:N threading. Dit threadingmodel is hetzelfde als Go (en Cilk en Intel TBB), waarbij taken worden gebruikt om mogelijke gelijktijdigheid uit te drukken, en die taken worden uitgevoerd op threads uit een pool van native threads door een planner.

  • Julia 1.7:ondersteuning voor migratie van taken tussen native threads. Hierdoor kan een taak worden uitgevoerd op één native thread, wordt deze onderbroken en vervolgens hervat op een andere thread, zodat de beschikbare computerbronnen volledig kunnen worden benut.

Oorspronkelijk antwoord

“Native threads” zijn afzonderlijke uitvoeringscontexten, beheerd door de kernel van het besturingssysteem, toegang tot een gedeelde geheugenruimte en mogelijk gelijktijdig uitgevoerd op afzonderlijke kernen. Vergelijk dit met afzonderlijke processen, die gelijktijdig op meerdere kernen kunnen worden uitgevoerd, maar afzonderlijke geheugenruimten hebben. Ervoor zorgen dat processen goed op elkaar inwerken is eenvoudig, omdat ze alleen via de kernel met elkaar kunnen communiceren. Ervoor zorgen dat threads niet op onvoorspelbare, foutieve manieren met elkaar omgaan, is erg moeilijk, omdat ze op onbeperkte wijze hetzelfde geheugen kunnen lezen en schrijven.

De R-situatie is vrij eenvoudig: R is niet multithreaded. Python is iets gecompliceerder: Python ondersteunt threading, maar vanwege de global interpreter lock (GIL), is er geen daadwerkelijke gelijktijdige uitvoering van Python-code mogelijk. Andere populaire open source dynamische talen bevinden zich in verschillende toestanden met betrekking tot native threading (Ruby: no/kinda /yes?; Node.js: nee) , maar over het algemeen is het antwoord nee, ze ondersteunen geen volledig gelijktijdige native threading, dus Julia staat hierin niet alleen.

Als we parallellisme met gedeeld geheugen toevoegen aan Julia, zoals we van plan zijn– of je nu native threads gebruikt of meerdere processen met gedeeld geheugen – het zal echte gelijktijdigheid zijn en er zal geen GIL zijn die gelijktijdige uitvoering van Julia-code verhindert. Dit is echter een ongelooflijk lastige functie om aan een taal toe te voegen, zoals blijkt uit de niet-bestaande of beperkte ondersteuning in andere zeer populaire, volwassen dynamische talen. Het toevoegen van een shared-memory gelijktijdigheidsmodel is technisch moeilijk, maar het echte probleem is het ontwerpen van een programmeermodel waarmee programmeurs op een productieve en veilige manier effectief gebruik kunnen maken van hardwareconcurrency. Dit probleem is over het algemeen onopgelost en is een zeer actief gebied van onderzoek en experiment – er is geen “gouden standaard” om te kopiëren. We zouden gewoon ondersteuning voor POSIX-threads kunnen toevoegen, maar dat programmeermodel wordt over het algemeen als gevaarlijk beschouwd en ongelooflijk moeilijk om correct en effectief te gebruiken. Go heeft een uitstekend verhaal over gelijktijdigheid, maar het is ontworpen om zeer gelijktijdige servers te schrijven, niet om gelijktijdig op grote hoeveelheden gegevens te werken, dus het is helemaal niet duidelijk dat het eenvoudigweg kopiëren van het Go-model een goed idee is voor Julia.

Other episodes