Hoofdcategorieën
Topicacties

[C#] Simulatie met meerdere threads op Core2Duo niet sneller

Pagina: 1 2 3 last

Reageer Nieuw Topic
Dat was ik niet..
Berichten: 793
Reg. datum: 20 juli 2006

Vrijwel alle multithreaded applicaties welke ik schrijf c.q. onderhoud zijn gebaseerd op distributed application designs. Elke thread kan gezien worden als een 'standalone' applicatie. De hoofd thread fungeert als dispatcher om de threads te starten.

Locking kun je ook deels voorkomen door een event handler te gebruiken. Via ISynchronizeInvoke kun je dan het event naar de hoofdtread sturen en de hoofdthread is de enigste welke een locking op de collectie uitvoert om het resultaat op te slaan. Er zijn verschillende methoden om synchronisatie te voorkomen.

Locking is opzich geen probleem zolang slechts 1 thread de locking uitvoert. Multi threaded locking hebben namelijk kernel hooks nodig en gaan daardoor buiten de CLR om. Locking op de hoofd thread (het process welke is opgestart door de CLR) wordt door de CLR uitgevoerd zolang er geen multi threaded lock nodig is.

Door alleen locking op de hoofd thread te gebruiken (in de dispatcher en event handler) is het vrij eenvoudig om multi threaded synchronisatie te voorkomen. Zelf ontwikkel ik geen threads welke weer afhankelijk zijn van andere threads.

Wat betreft de CTP versies. Geen van de vorige versies heeft een verandering gebracht in bestaande API. Elke CTP bevat eigenlijk vooral meer speelgoed voor multi threaded applicaties.

Stel je wilt een matrix van 10x10 printen. Je zou via een loop 10 maal een thread kunnen starten welke elk een rij afdrukt. Maar waarschijnlijk is de winst dan vrij minimaal. De meeste threaded zullen dan de CPU power moeten delen en de overhead zal een groot deel van de performance winst teniet doen. Via een Semaphore in de loop slecht 2 of 3 theads starten zal in de meeste gevallen meer winst opleveren (de CPU schedular is dan minder kwijt de resources te verdelen). Voor de meeste applicaties zijn threads voornamelijk interessant als er veel idle tijd is (bijv. wachten op database of netwerk response). Rekenkundige threads hebben over het algemeen weinig idle (lees: alle threads willen processor tijd) tijd en zal de winst minimaal zijn. Rekenkundige threads halen de meeste winst als zij worden verdeeld over meerdere cores. Echter verplaatst de CLR deze threads allemaal naar dezelfde thread zodra er threads gesynchroniseerd dienen te worden.

Al onze multi threaded applicaties hebben een ingebouwde 'profiler' test procedure. Deze profiler test voert de verschillende kerntaken 100 maal uit. De profiler gebruikt na elke run een thread meer totdat de uitvoer langer duurt dan de vorige. Elke run wordt driemaal uitgevoerd en het gemiddelde uitvoeringstijd wordt gebruikt voor de vergelijking. De tests slaan uiteindelijk de optimale waardes op in de app.config en vormen daarmee de maximum waarde van de semaphores.

Soms zijn synchronisaties echter niet te voorkomen. Anders dan in C/C++ regelt de CLR heel veel zaken voor jouw waar je geen of weinig invloed op hebt. Een van die zaken is de fallback van multi threaded apartment naar single threaded apartment (applicaties draaien dan op een enkele core). De processor instructie pipelines worden ook 'threads' genoemd.

Distributed application design patterns vormen vaak een goede basis voor een multi threaded applicatie. Een aantal goede design patterns hiervoor zijn te vinden op http://www.cs.wustl.edu/~schmidt/patterns-ace.html (C++ based, maar theorie is ook bruikbaar voor c#/vb developers) en op http://www.cmcrossroads.com/bradapp/javapats.html zijn distributed design patterns (en de Gang of Four patterns) voor java.

Debugging is twice as hard as writing the code in the first place. Therefore, if you write the code as cleverly as possible, you are, by definition, not smart enough to debug it.

quote:
Niemand_Anders schreef op maandag 21 juli 2008 @ 12:01:
Locking is opzich geen probleem zolang slechts 1 thread de locking uitvoert. Multi threaded locking hebben namelijk kernel hooks nodig en gaan daardoor buiten de CLR om. Locking op de hoofd thread (het process welke is opgestart door de CLR) wordt door de CLR uitgevoerd zolang er geen multi threaded lock nodig is.
Wat zijn de nadelen van het gebruik van een kernel hook? Kost dat zoveel extra tijd?

Website
lordpalf of the flapdrols

Dat was ik niet..
Berichten: 793
Reg. datum: 20 juli 2006

De CLR van .net is van nature vrij complex (als in veel mogelijkheden) en heeft ingebouwde managed locking mechanismes (zoals monitor). De System.Threading.WaitHandle (waarvan Semaphore, Mutex erven) is een system wide locking/synchronisatie mechanisme. Deze locks zijn krachtig maar omdat ze buiten de CLR om werken resource intensiever. Voor het OS is het gemakkelijker om threads op dezelfde core te syncen, dan als deze over meedere cores verspeid zijn. De CLR grijpt daarom ook in door de 'systeem' threads naar dezelfde core te verplaatsen zodat vervolg synchronisaties minder resources (en daarmee processor tijd) kost. Runtime thread locks (o.a. monitor) worden alleen door de CLR afgehandeld en wordt ook weleens aangeduid als een managed lock.

In het verleden heb ik weleens de Win32 api (CreateMutex en ReleaseMutex) erbij gepakt en zelf de locking opgepakt. Daarmee kun je ook voorkomen dat een MTA app door de CLR wordt omgezet naar een STA app. De main thread van via Thread.TrySetApartment de state nog wel veranderen naar MTA voordat de subthread start, maar regelmatig switchen tussen STA en MTA kost aardig wat cpu time.

Bij een enkele cross thread lock kun je daarmee ervoor zorgen dat je applicatie in MTA mode blijft draaien. Via IntPtr creert de CLR dan een object (integer) met tevens een reference op de kernel stack. Deze handle kun je vervolgens gebruiken met de win32 mutex calls. Uiteraard is windows zelfs nog wel tijd kwijt met de synchronisatie lock. Veelvuldig op kernel niveau synchroniseren heeft dus een zeer negatieve impact op de performance.

Van Jeffrey Richter heb ik ooit begrepen dat managed locks werken door het reference object van de caller aan een resource te koppelen op de CLR stack. Als de CLR ziet dat een andere caller probeert dan de resource te benaderen geeft deze een exceptie. Op het moment dat je een kernel lock gebruikt wordt er behalve een integer (IntPtr) (structures verblijven op de stack, terwijl objecten (classes) op de heap verblijven en enkel een reference daarna toe op de stack hebben) op de stack, ook een unmanaged integer aangemaakt (pointer) buiten de CLR. Echter de instantie van het locking mechanisme (instance van bijv. Mutex) staat op de heap. De CLR moet dan samen met de kernel de toegang tot de managed en unmanaged instances synchroniseren en dat kost dus tijd. Er wordt op dat moment dus eigenlijk een dubbele synchronisatie uitgevoerd. Dat is helaas het nadeel van een runtime omgeving.

Als je dus door een onderdeel te herschrijven een synchronisatie punt kunt weg werken, kun je dus al relatief wat winst bereiken. De hoeveelheid winst is vooral afhankelijk van de idle times welke in een instructie pipelines ontstaan. Als jouw blokje code geen afhankelijkheden heeft is de performance winst afhankelijk van het aantal execution engines welke een core tot zijn beschikking heeft.

Vrijwel al mijn multi threaded applicaties gebruiken een private message queue (welke wordt gelezen door de main thread) om informatie uit een subthread weer bij de hoofd thread te bezorgen. De message queue receive handler vuurt op basis van de berichten dan de juiste event af (ThreadFinished, ThreadException, ThreadCancelled, etc).

In principe zorgt het gebruik van meerdere threads voor een performance winst en elke synchronisatie call zorgt voor performance verlies. De optelsom van beide bepaald uiteindelijk of er winst overblijft.

Debugging is twice as hard as writing the code in the first place. Therefore, if you write the code as cleverly as possible, you are, by definition, not smart enough to debug it.


Acties: [view][quote]


Door: whoami
Moderator PRG/SEA/DTE
quote:
Niemand_Anders schreef op maandag 21 juli 2008 @ 17:06:
Vrijwel al mijn multi threaded applicaties gebruiken een private message queue (welke wordt gelezen door de main thread) om informatie uit een subthread weer bij de hoofd thread te bezorgen. De message queue receive handler vuurt op basis van de berichten dan de juiste event af (ThreadFinished, ThreadException, ThreadCancelled, etc).

In principe zorgt het gebruik van meerdere threads voor een performance winst en elke synchronisatie call zorgt voor performance verlies. De optelsom van beide bepaald uiteindelijk of er winst overblijft.
Talk is cheap, show me the code. :P
plz
Berichten: 4.796
Reg. datum: 29 september 2000

@Niemand_Anders: +3: inzichtvol

Thanks :)

AoC: Ankeh - 4X ToS | WoW: Zhazam - 70 Mage | Sammia - 70 Druid

Berichten: 348
Reg. datum: 15 januari 2008

Of ik heb het verhaal van Niemand_Anders verkeerd gelezen, of er staat niet duidelijk bij dat STA vs MTA een legacy-iets is. Het is alleen relevant bij COM-interactie is (denk aan clipboard/ActiveX controls). Wat het met ShowDialog('ShowModal') te maken heeft zie ik al helemaal niet.
Of, om de documentatie te quoten:
quote:
The .NET Framework does not use apartments, and managed objects are responsible for using all shared resources in a thread-safe manner themselves.
Ik vraag me ook af hoe de 'private message queue' precies werkt. Is dit een queue die toevallig intern met locks werkt? :)

Dat neemt niet weg dat dingen als PLINQ de toekomst zijn.
 
Berichten: 5.666
Reg. datum: 02 februari 2004

Ik moet zeggen dat ik dit een mateloos interessant topic vind!
Is het ook misschien niet een leuk idee om hiervan een meer algemeen topic te maken over multi-threading?
Iets als 'Het grote multi-threading topic - Deel 1' o.i.d.?

Nog een vraagje: is een koppeling tussen twee databases (die 's nachts draait)
[=is een programma dat een aantal CSV bestanden inleest (met daarin een database dump van enkele tienduizenden records), en deze vervolgens vergelijkt met een andere database en daar bestaande records in update/creëert]
relatief makkelijk multithreaded te maken?

Kater? Eerst water, de rest komt later
Bouw mee aan Tweak-City! Topic


Acties: [view][quote]


Door: whoami
Moderator PRG/SEA/DTE
quote:
Haan schreef op dinsdag 22 juli 2008 @ 09:59:

Is het ook misschien niet een leuk idee om hiervan een meer algemeen topic te maken over multi-threading?
Iets als 'Het grote multi-threading topic - Deel 1' o.i.d.?
Nee, ik vind van niet.
'Grote' topics verzanden dan meestal in allemaal korte vraagjes, en zijn moeilijk beheersbaar. Daarbij denk ik ook dat je een 'groot multithreading' topic gauw minder interessant zal worden omdat je op den duur door de bomen het bos niet meer zal zien.
quote:
Nog een vraagje: is een koppeling tussen twee databases (die 's nachts draait)
[=is een programma dat een aantal CSV bestanden inleest (met daarin een database dump van enkele tienduizenden records), en deze vervolgens vergelijkt met een andere database en daar bestaande records in update/creëert]
relatief makkelijk multithreaded te maken?
Ik denk het wel. Per CSV bestand kan je een 'task' starten die dat CSV bestand verwerkt en vergelijkt met een andere database. Je hebt dan ook al het geluk dat de database de nodige locking mechanismen al voor jou kan doen.
Maar, wat is de bedoeling hiervan ? Is dat een soort home-brew replicatie ?
quote:
Haan schreef op dinsdag 22 juli 2008 @ 09:59:
Nog een vraagje: is een koppeling tussen twee databases (die 's nachts draait)
[=is een programma dat een aantal CSV bestanden inleest (met daarin een database dump van enkele tienduizenden records), en deze vervolgens vergelijkt met een andere database en daar bestaande records in update/creëert] relatief makkelijk multithreaded te maken?
Dat hangt van een aantal zaken af. Het openen van het bestand en het uitlezen van de regels kun je multithreaded doen maar levert weinig tot niets op. Het inlezen van een batch regels, bijvoorbeeld 50 zal elke thread na elkaar moeten doen. Dus of één thread dit doet of meerdere levert in dit geval niet veel performance winst op. Het wordt pas interessant tijdens het verwerken van de regels. Je kan bijvoorbeeld een batch regels gaan verwerken terwijl een andere thread de volgende vijftig regels gaat inlezen. Je kunt er ook voor kiezen om meerdere batches tegelijk te verwerken in meerdere threads. Het is dan wel belangrijk dat je erg zorgvuldig omgaat met concurrency. Stel dat batch 1 een vergelijking uitvoert op regel 1 en daarna batch 2 een wijziging uitvoert op regel 1 dan is het resultaat van de vergelijking in batch 1 niet meer betrouwbaar. Dus relatief makkelijk als je voldoende voorkennis hebt en zorgvuldig test.

Website
lordpalf of the flapdrols

Berichten: 5.666
Reg. datum: 02 februari 2004

quote:
whoami schreef op dinsdag 22 juli 2008 @ 11:02:
Ik denk het wel. Per CSV bestand kan je een 'task' starten die dat CSV bestand verwerkt en vergelijkt met een andere database. Je hebt dan ook al het geluk dat de database de nodige locking mechanismen al voor jou kan doen.
Maar, wat is de bedoeling hiervan ? Is dat een soort home-brew replicatie ?
Het is een koppeling tussen een legacy applicatie waar men geen afstand van kan nemen en een nieuw systeem.
Maar ik ga eerst wel wat meer oefenen op eigen progjes, dat is wat veiliger ;)

Kater? Eerst water, de rest komt later
Bouw mee aan Tweak-City! Topic

BooBs for BraiNs
Berichten: 1.446
Reg. datum: 02 december 2002

quote:
Niemand_Anders schreef op maandag 21 juli 2008 @ 17:06:
Zodra een applicatie monitor gebruikt, verplaatst de CLR alle threads uit dat applicatie domein naar dezelfde core waardoor je applicatie feitelijk Single Threaded Apartment (STA) wordt en jouw applicatie nog slechts een enkele core gebruikt. Standaard draaien .net applicaties in STA mode. Dit kan eenvoudig veranderd worden door het MTAThread attribute te zetten in Program.cs. Op dat moment zal de CLR threads ook verdelen over meerdere cores/cpu's. Om die reden levert een Form.ShowModal call ook een exceptie op. ShowModal wordt alleen ondersteund bij appliacties welke in STA mode draaien.
-------------------------------------------------
De CLR van .net is van nature vrij complex (als in veel mogelijkheden) en heeft ingebouwde managed locking mechanismes (zoals monitor). De System.Threading.WaitHandle (waarvan Semaphore, Mutex erven) is een system wide locking/synchronisatie mechanisme. Deze locks zijn krachtig maar omdat ze buiten de CLR om werken resource intensiever. Voor het OS is het gemakkelijker om threads op dezelfde core te syncen, dan als deze over meedere cores verspeid zijn. De CLR grijpt daarom ook in door de 'systeem' threads naar dezelfde core te verplaatsen zodat vervolg synchronisaties minder resources (en daarmee processor tijd) kost. Runtime thread locks (o.a. monitor) worden alleen door de CLR afgehandeld en wordt ook weleens aangeduid als een managed lock.
-------------------------------------------------
Locking is opzich geen probleem zolang slechts 1 thread de locking uitvoert. Multi threaded locking hebben namelijk kernel hooks nodig en gaan daardoor buiten de CLR om. Locking op de hoofd thread (het process welke is opgestart door de CLR) wordt door de CLR uitgevoerd zolang er geen multi threaded lock nodig is.

Door alleen locking op de hoofd thread te gebruiken (in de dispatcher en event handler) is het vrij eenvoudig om multi threaded synchronisatie te voorkomen. Zelf ontwikkel ik geen threads welke weer afhankelijk zijn van andere threads.
-------------------------------------------------
Soms zijn synchronisaties echter niet te voorkomen. Anders dan in C/C++ regelt de CLR heel veel zaken voor jouw waar je geen of weinig invloed op hebt. Een van die zaken is de fallback van multi threaded apartment naar single threaded apartment (applicaties draaien dan op een enkele core). De processor instructie pipelines worden ook 'threads' genoemd.
Daar wil ik wel eens een bron van zien.

Mocht zo'n gedrag in de CLR zitten dan denk ik dat het hier wel in zou staan.
Bovendien ben ik nu al even aan het googlen op iets wat er ook maar op lijkt en kan ik helemaal niets vinden.

Yo momma's so fat, Dr. Martens had to kill 3 cows just to make her a pair of shoes.


Acties: [view][quote]


Door: whoami
Moderator PRG/SEA/DTE
Daar ben ik eigenlijk stiekem ook wel benieuwd naar :P
Dat was ik niet..
Berichten: 793
Reg. datum: 20 juli 2006

Sorry, voor de late reply, maar ik zit momenteel op mijn vakantie adres (Zadar, Kroatie). Veel informatie aangereikt door Jeffrey Richter wordt niet door Microsoft onderkent noch ontkent. Wat wel feitelijk vast staat is dat in .NET 2.0 de CLR engine een nieuw thread model heeft gekregen. Zo start een applicatie nu standaard in MTA mode (winform apps hebben nog steeds in program.cs de STAThread attribute), terwijl dit in 1.x nog standaard STA mode was. Ten tijde van 2.0 kon de CLR ook geen onderscheid maken tussen een dubbele processor en een multicore CPU. De multicore CPU heeft namelijk een gemeenschappelijk basis met daarop 2 of 4 uitvoerings eenheden. Alle cores kunnen bij alle instructie pipelines. Bij een dubbele processor is dat niet mogelijk en is synchronisatie complexer.

Omdat de CLR wel al support voor meerdere processors is in het 2.0 threading model in elk geval opgenomen dat subthreads altijd op dezelfde processor leven als de hoofd thread. Van wat ik heb begrepen is Microsoft's standpunt in deze dat zij nooit de interne werking kunnen garanderen (c.q. behouden) en daarom daarover ook geen uitspraken doen.

Ik weet dat Microsoft wel heeft geexperimenteerd met multicore support in de CLR. Het is niet bekend of deze ooit in 3.0 of 3.5 is toegevoegd.

Als de MTA mode zoals de MSDN documentatie aangeeft alleen van invloed is op (D)COM(+) componenten, dan is het vreemd dat zij dit in 2005 ineens veranderen, terwijl het aantal programmeurs van (D)COM(+) componenten sinds het .NET framework juist flink is afgenomen.

Zodra ik terug ben van vakantie (volgende week donderdag) zal ik alle mails welke ik heb ontvangen van Jeffrey en enkele Microsoft programmeurs verzamelen. Ik zal ook eens kijken hoever de chat history van mijn IRC client terug gaat.

Overgens de AMD PDF raad nog steeds aan (sectie Lock Optimalisations) om locks (synchronisatie) te voorkomen zoals 'enter late, leave early' en 'lock only when necessary' en data te kopieren voor voordat de thread wordt gestart zodat subtreads geen (of minimaal) resources van de hoofd hoeven te raadplegen.

Overigens gaat ook de PDF over een multi core CPU. Net zoals de Intel processors delen alle processing units dezelfde basis en heeft de pipeline verplaatsing vooral een negatieve impact. Probleem schijnt de hardware abstractie van windows te zijn. Windows zal een AMD QuadCore processor zien als 4 processors en daardoor ziet de CLR ook 4 processors. Echter zijn deze virtueel omdat een OS geen taak aan een specifieke core kan hangen. Er is dus 1 queue met 4 consumers. Bij een dual quadcore systeem zijn er 2 queues met elk 4 consumers. En wat de wat STA mode in 2.0 doet is ervoor zorgen dat zoveel mogelijk threads op 1 processor komen zodat er geen processor synchronisatie nodig is.

Ik kom hier nog op terug.

Debugging is twice as hard as writing the code in the first place. Therefore, if you write the code as cleverly as possible, you are, by definition, not smart enough to debug it.

BooBs for BraiNs
Berichten: 1.446
Reg. datum: 02 december 2002

quote:
Niemand_Anders schreef op donderdag 21 augustus 2008 @ 15:37:
Sorry, voor de late reply, maar ik zit momenteel op mijn vakantie adres (Zadar, Kroatie). Veel informatie aangereikt door Jeffrey Richter wordt niet door Microsoft onderkent noch ontkent. Wat wel feitelijk vast staat is dat in .NET 2.0 de CLR engine een nieuw thread model heeft gekregen. Zo start een applicatie nu standaard in MTA mode (winform apps hebben nog steeds in program.cs de STAThread attribute), terwijl dit in 1.x nog standaard STA mode was. Ten tijde van 2.0 kon de CLR ook geen onderscheid maken tussen een dubbele processor en een multicore CPU. De multicore CPU heeft namelijk een gemeenschappelijk basis met daarop 2 of 4 uitvoerings eenheden. Alle cores kunnen bij alle instructie pipelines. Bij een dubbele processor is dat niet mogelijk en is synchronisatie complexer.
Als je met gemeenschappelijke basis de memory controller bedoelt, fair enough.
Verder is een multicore CPU niets meer als 4 aparte/losse CPUs op 1 package met nog wat glue logic. Soms zijn bepaalde caches geshared en zijn er nog wat extraatjes, maar het blijven X losse cores. Core1 kan dus niet bij de pipeline van core2 en andersom.
quote:
Omdat de CLR wel al support voor meerdere processors is in het 2.0 threading model in elk geval opgenomen dat subthreads altijd op dezelfde processor leven als de hoofd thread. Van wat ik heb begrepen is Microsoft's standpunt in deze dat zij nooit de interne werking kunnen garanderen (c.q. behouden) en daarom daarover ook geen uitspraken doen.
Dit geldt voor zover ik weet enkel voor COM en Co.
quote:
Ik weet dat Microsoft wel heeft geexperimenteerd met multicore support in de CLR. Het is niet bekend of deze ooit in 3.0 of 3.5 is toegevoegd.
Parallels extension for .NET ? Zie http://msdn.microsoft.com...rency/default(en-us).aspx
quote:
Overgens de AMD PDF raad nog steeds aan (sectie Lock Optimalisations) om locks (synchronisatie) te voorkomen zoals 'enter late, leave early' en 'lock only when necessary' en data te kopieren voor voordat de thread wordt gestart zodat subtreads geen (of minimaal) resources van de hoofd hoeven te raadplegen.
Dit is gewoon good practice en is voor elke programmeertaal en elk platform hetzelfde.
quote:
Overigens gaat ook de PDF over een multi core CPU. Net zoals de Intel processors delen alle processing units dezelfde basis en heeft de pipeline verplaatsing vooral een negatieve impact. Probleem schijnt de hardware abstractie van windows te zijn. Windows zal een AMD QuadCore processor zien als 4 processors en daardoor ziet de CLR ook 4 processors. Echter zijn deze virtueel omdat een OS geen taak aan een specifieke core kan hangen. Er is dus 1 queue met 4 consumers. Bij een dual quadcore systeem zijn er 2 queues met elk 4 consumers. En wat de wat STA mode in 2.0 doet is ervoor zorgen dat zoveel mogelijk threads op 1 processor komen zodat er geen processor synchronisatie nodig is.

Ik kom hier nog op terug.
Windows Vista heeft een nieuwe GetLogicalProcessorInformation() (zie http://msdn.microsoft.com/en-us/library/ms683194.aspx) die je kan gebruiken om informatie op te vragen over de processoren in het systeem.

Wat windows XP betreft, ziet die volgens mij toch echt wel 4 aparte processoren en is er dus niet 1 enkele runqueue voor meerdere processoren. Volgens mij sla je de bal mis met HyperThreading.

Yo momma's so fat, Dr. Martens had to kill 3 cows just to make her a pair of shoes.

Burn your lie into me
Berichten: 3.073
Reg. datum: 07 maart 2000

quote:
H!GHGuY schreef op donderdag 21 augustus 2008 @ 19:53:
Windows Vista heeft een nieuwe GetLogicalProcessorInformation() (zie http://msdn.microsoft.com/en-us/library/ms683194.aspx) die je kan gebruiken om informatie op te vragen over de processoren in het systeem.
Evenals Windows XP :)

Penance can't absolve your sin. All your belief cannot absolve your sin.

programulator
Berichten: 21.027
Reg. datum: 26 september 2000

Ik krijg ook een beetje een klop-en-klepel gevoel bij het verhaal van Niemand_Anders. Het grote voordeel van meerdere on-die cores is dat ze sneller met elkaar kunnen communiceren (er zit geen langzame bus tussen die over het moederbord moet). En afgezien van het feit dat ze wat resources kunnen sharen (zoals cache idd, maar ik zou dat niet meteen een voordeel willen noemen) is er geen verschil. De eerste Core 2 Quads van Intel waren zelfs feitelijk twee losse dual-cores in 1 package (geen idee of dat bij de nieuwere ook nog zo is trouwens).

Wat er bij Hyperthreading (Intels implementatie van SMT) gebeurt is dat er een enkele core is met een aantal resources (ALU's, instruction decoders, etc.) die worden gebruikt door meerdere hardware threads die naast elkaar lopen. Omdat ze die resources moeten delen is dat niet zo efficient als een multicore oplossing - twee number crunchers die tegelijk draaien zullen zo goed als geen winst halen bij een SMT core tov een normale core, omdat ze continu moeten vechten om dezelfde resources.

En dan komen we op het STA / MTA verhaal. In een STA COM applicatie kunnen op zich best meerdere threads draaien, echter draaien die altijd in hun eigen apartment met hun eigen resources (class instances). Er is geen resource sharing tussen apartments, en communicatie verloopt middels de thread message queue, en er moet dus ook een message pump zijn. Als je een COM object aanmaakt dat leeft in een andere apartment dan krijg je in feite een proxy naar dat object. Die proxy zorgt voor marshalling van de calls op dat object naar de thread van het daadwerkelijke object dmv de thread message queue.

Maar goed, dit komt dus uit de tijd van OLE en COM. COM GUI zut vereist een STA thread, en omdat Windows Forms COM gebruikt (drag & drop gaat bijv. middels OLE) heeft die dus ook een STA nodig. Wat niet meteen betekent dat je niet meerdere threads in je applicatie kunt gebruiken... Alleen COM marshalling zal ervoor zorgen dat je communicatie met dat soort objecten dus via de proxy verlopen (en dus niet in je eigen thread worden afgehandeld). .Net zelf heeft geen apartments en bouwt gewoon op het NT threading systeem wat prima met meerdere hardware threads, cores en processors om kan gaan. Synchronisatie gaat met de bestaande primitives, zoals kernel-level waitable objects (mutexes, semaphores, events) en de atomic bouwstenen voor user-level synchronisatie (zoals atomic compare-and-swap operaties, de Interlocked meuk dus).

De concurrency affairs articles van Jeffrey Richter zeggen verder ook verdacht weinig over thread scheduling in de CRL, noch over apartments.

.oisyn wijzigde dit bericht 22-08-2008 02:18 (8%)

Berichten: 160
Reg. datum: 15 februari 2002

quote:
pedorus schreef op donderdag 17 juli 2008 @ 15:21:
Je start nu 2 threads in het voorbeeld, maar dat kan eigenlijk eentje minder door de hoofdthread ook een taak op zich te laten nemen, maar dat is een beetje een minioptimalisatie.
Ben ik niet helemaal met je eens, je wilt over het algemeen de hoofd thread voor UI Zaken responsive houden (weet niet of het in dit geval om een console app of GUI apje gaat).
 
Berichten: 348
Reg. datum: 15 januari 2008

quote:
CMG schreef op vrijdag 22 augustus 2008 @ 02:57:
[...]

Ben ik niet helemaal met je eens, je wilt over het algemeen de hoofd thread voor UI Zaken responsive houden (weet niet of het in dit geval om een console app of GUI apje gaat).
Een post onder die post wordt gevraag naar een progress-bar, waardoor die alinea sowieso onzin werd... :)

Misschien dat je bij veel threads daar maar het beste Interlocked voor kan gebruiken in plaats van Invoke(of Backgroundworker dat daar een klein laagje omheen is). Dan lees je gewoon om de zoveel tijd even de huidige toestand af. Aan de andere kant is precieze progress niet heel belangrijk, dus misschien dat het volatile keyword volstaat. MS gebruikt ook Interlocked zie ik nu, in combinatie met Backgroundworker. Ze gebruiken daar Parallel.For() om de boel automatisch op te splitsen. Ik denk enkel dat bij snelle processors de progress veel vaker dan nodig word geupdate in het voorbeeld in CTP june 2008.

Maar Parlellel.For() gebruiken lijkt me wel handig. In de toekomst gaan we naar duizenden cores, dus je kan maar beter voorbereid zijn :) Vanaf zo'n 6 processors treden nu vaak al behoorlijke problemen op als de synchronizatie niet handig gebeurd, dus 1000en wordt echt lastig... (4-6 processors is gebaseerd op ervaringen bij de cell processor)
 
Voor de mensen die zich wat dieper willen verdiepen in threads en .net, zie deze site:
http://www.albahari.com/threading/index.html Erg uitgebreid en zeer interessant.

Website
lordpalf of the flapdrols

programulator
Berichten: 21.027
Reg. datum: 26 september 2000

Ik zit het een beetje door te lezen, maar ik krijg erg m'n twijfels over de kennis en ervaring van de auteur.

Ik bedoel, neem dit voorbeeld:
quote:
Threads share data if they have a common reference to the same object instance. Here's an example:
C#:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
class ThreadTest {
 bool done;
 
 static void Main() {
   ThreadTest tt = new ThreadTest();   // Create a common instance
   new Thread (tt.Go).Start();
   tt.Go();
 }
 
 // Note that Go is now an instance method
 void Go() {
   if (!done) { done = trueConsole.WriteLine ("Done"); }
 }
}

Because both threads call Go() on the same ThreadTest instance, they share the done field. This results in "Done" being printed once instead of twice
.
Bliep, race condition.
En vervolgens:
quote:
Static fields offer another way to share data between threads. Here's the same example with done as a static field:
C#:
1
2
3
4
5
6
7
8
9
10
11
12
class ThreadTest {
 static bool done;    // Static fields are shared between all threads
 
 static void Main() {
   new Thread (Go).Start();
   Go();
 }
 
 static void Go() {
   if (!done) { done = trueConsole.WriteLine ("Done"); }
 }
}

Both of these examples illustrate another key concept – that of thread safety (or, rather, lack of it!) The output is actually indeterminate: it's possible (although unlikely) that "Done" could be printed twice. If, however, we swap the order of statements in the Go method, then the odds of "Done" being printed twice go up dramatically:
C#:
1
2
3
static void Go() {
  if (!done) { Console.WriteLine ("Done"); done = true; }
}

Euh ja, dude, waarom denk je in hemelsnaam dat dat bij je vorige voorbeeld anders is?
quote:
.oisyn schreef op dinsdag 16 september 2008 @ 23:52:
Ik zit het een beetje door te lezen, maar ik krijg erg m'n twijfels over de kennis en ervaring van de auteur.

Ik bedoel, neem dit voorbeeld:

[...]
.
Bliep, race condition.
En vervolgens:

[...]

Euh ja, dude, waarom denk je in hemelsnaam dat dat bij je vorige voorbeeld anders is?
Hij zegt ook "Both of these examples" :P

Website
lordpalf of the flapdrols


Acties: [view][quote]


Door: Creepy
Moderator PRG/SEA/DTE
Eye Have You
Berichten: 13.126
Reg. datum: 01 juni 2001

Hij zegt ook
quote:
Because both threads call Go() on the same ThreadTest instance, they share the done field. This results in "Done" being printed once instead of twice:
bij de eerste example zoals .oisyn al aanngeeft. En dat klopt gewoon niet. Hier kan prima done twee keer worden afgedrukt. Later begint ie over "both of these examples". Niet echt duidelijk verwoord...

- Ik kan niet zingen, geen gitaar spelen en niet drummen.... ik hou het wel bij Rock Band
Juist dan gaan mensen het weer prachtig vinden (Denk aan de josty band *blauw* *blauw* *rood*, *blauw* *blauw* *rood)

quote:
Creepy schreef op woensdag 17 september 2008 @ 09:47:
Hij zegt ook

[...]

bij de eerste example zoals .oisyn al aanngeeft. En dat klopt gewoon niet. Hier kan prima done twee keer worden afgedrukt. Later begint ie over "both of these examples". Niet echt duidelijk verwoord...
Ik ben het met je eens dat hij het onduidelijk geformuleerd heeft. Wat hij bedoeld te zeggen is dat beide aanroepen op een andere thread uitgevoerd worden maar toch refereren naar hetzelfde veld done. Als zijn code thread safe was zou het voorbeeld beter uit de verf komen.

HawVer wijzigde dit bericht 17-09-2008 14:26 (1%)
Reden: typo's

Website
lordpalf of the flapdrols

Berichten: 78
Reg. datum: 10 december 2007

nm,

Ik reageerde geloof ik op 2 pagina posts terug :).

Phoeba wijzigde dit bericht 17-09-2008 11:29 (80%)

 
programulator
Berichten: 21.027
Reg. datum: 26 september 2000

quote:
HawVer schreef op woensdag 17 september 2008 @ 08:45:
[...]

Hij zegt ook "Both of these examples" :P
Mmmja, daar las ik idd overheen 8)7. Maar hij had het wat duidelijker kunnen formuleren :)

Pagina: 1 2 3 last



VNU Media logo Powered by True

© 1998 - 2008 Tweakers.net - Alle rechten voorbehouden

Uitgever van: