PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Dual-Core-Programmierung in .NET und C++


PatTheMav
2007-06-13, 16:45:40
Ich wollt mal fragen, ob einer von euch Erfahrung mit Dual Core-Programmierung (bzw. genauer gesagt "echter" Multithreading-Programmierung) in C++ oder noch besser in .NET hat, weil ich zwar mit OpenMP seit paar Wochen rumkrebse, ich aber das Projekt in .NET abliefern muss und mir da paar Tips oder Links zu Tutorials und FAQs sehr helfen würden.

Ich hab bisher zwar schon mit Threads gearbeitet aber das waren eher sehr billige Sachen wie ein mit mehreren Threads auf Verbindungen wartender Server (TCP Client/Server-Programmierung), aber noch nichts wirklich aufwendiges, was auch HT oder 2 wirkliche Cores ausnutzen würde, mitsamt GUI :)

del_4901
2007-06-13, 17:49:28
intel Thread Checker und
intel Thread Profiler sollten hilfreich sein.

bei .net wird sicherlich bei allen Sprachen eine Thread Klasse mitgeliefert.

Dann musst du wissen was ne Semaphore, Mutex oder Blockade ist.
Und das kein Befehl Atomar ist.
Sowie Murphys-Gesetz auswendig lernen.

Ach weil ich grad noch mitsamt GUI lese ... das lässt du mal schoen bleiben!

Monger
2007-06-13, 18:07:00
Afaik ist die Threadverwaltung in .NET transparent. Sprich: die Anwendung hat keine Ahnung, auf welchem Core welcher Thread landet, und interessiert sich auch gar nicht dafür.
Jede .NET Anwendung die mehrere Threads verwendet, profitiert afaik im Prinzip auch von Dual Core.

Edit: weil AlphaTier die GUI anspricht: das wichtigste an Multithreading ist, wann man es besser lassen sollte.
Du solltest nie mehrere Threads verwenden weil es halt gerade so hübsch aussieht, sondern nur dann wenn du sie wirklich dringend brauchst, und auch nur unter schweren Magenkrämpfen. Threads können dir üble Probleme bereiten, und sind dann höllisch zu debuggen.

Gast
2007-06-13, 18:48:13
Sprich: die Anwendung hat keine Ahnung, auf welchem Core welcher Thread landet, und interessiert sich auch gar nicht dafür.


Du kannst natürlich auch bei verwalteten Threads die Affinität angeben.
Was man allerdings beachten sollte: verwaltete Threads entsprechen nicht einem nativen Windows Thread. Wenn du in einer .NET Anwendung mehrere Threads erstellst, injeziert die VM die Zeitschleifen der verwalteten Threads in richtige native Workerthreads. Sprich: Es "kann" sein, dass ein verwalteter Thread a und b im selben nativen Thread von Windows gebündelt hintereinander ausgeführt werden.

PatTheMav
2007-06-13, 22:36:54
Also habe ich in .NET im Grunde keinen direkten Einfluss darauf, was auf welchem Core läuft, also meinetwegen ne Sound-Decodierung auf den einen, die Video-Decodierung auf den anderen Kern zu legen?

Das GUI ist eine Maßgabe an das Projekt, es soll ein kleines Windows-Programm werden, dass mehrere Kerne nutzt und das auch irgendwie visuell zeigt - so isses vom Prof vorgegeben.

Gast
2007-06-13, 22:45:04
Also habe ich in .NET im Grunde keinen direkten Einfluss darauf, was auf welchem Core läuft, also meinetwegen ne Sound-Decodierung auf den einen, die Video-Decodierung auf den anderen Kern zu legen?


Doch, du kannst die Affinität setzen. Aber genau wie bei nativen Threads gibt's kein 100%iges Versprechen, dass der Thread auch auf dem entsprechend festgelegten Core ausgeführt wird.


Das GUI ist eine Maßgabe an das Projekt, es soll ein kleines Windows-Programm werden, dass mehrere Kerne nutzt und das auch irgendwie visuell zeigt - so isses vom Prof vorgegeben.

Du kannst das GUI im Prinzip auch multithreaded machen, wenn es z.B. darum geht mit GDI ein paar Linien bzw. Animationen zu machen. Aber die Fensterverwaltung eines Prozess ist AFAIK an einem Thread gebunden. Dazu gehören dann ja auch alle nativen Controls wie Buttons usw., die ja im Grunde ebenfalls Fenster sind.

Kabelsalat
2007-06-13, 22:54:00
Ein paar Links zu dem Thema (.Net):

http://www.yoda.arachsys.com/csharp/threads/
http://www.albahari.com/threading/
http://msdn2.microsoft.com/en-us/library/f857xew0(vs.71).aspx
http://www.codeproject.com/cs/library/managediocp.asp
http://msdn.microsoft.com/msdnmag/issues/07/05/CLRInsideOut/default.aspx?loc=de
http://www.devsource.com/article2/0,1895,1942729,00.asp

Auch bin ich in der Dotnetpro (www.dotnetpro.de) in den letzten Jahren auf einige gute Artikel gestoßen. Auch die MSDN Library hat gute Inhalte zu bieten.

PS: Auch Grundlagenwissen über das COM Threading Modell und allgeine Windows Threading Grundlagen können in Zusammenhang mit .Net nützlich sein (etwa im Bereich WinForms, PInvoke...)

del_4901
2007-06-13, 23:05:32
Ich sage es jetzt noch ein letztes mal deutlich. Wenn mehrere Threads in eine Ausgabe schreiben wird es zu Problemen kommen! Und da sind Magenschmerzen das geringste Problem.

Gast
2007-06-13, 23:26:12
Ich sage es jetzt noch ein letztes mal deutlich. Wenn mehrere Threads in eine Ausgabe schreiben wird es zu Problemen kommen! Und da sind Magenschmerzen das geringste Problem.

Dann muss man eben synchronisieren, wenn es mehrere Threads sein sollen.
Damit muss man sich aber irgendwann einmal auseinandersetzen.

del_4901
2007-06-13, 23:36:43
Dann muss man eben synchronisieren, wenn es mehrere Threads sein sollen.
Damit muss man sich aber irgendwann einmal auseinandersetzen.
Und die Synchronisation sorgt dann dafür das eh immer nur einer dran kommt.
Ganz tolles Kino! Dann habe ich 0 Parallität, mehr Klassen, unübersichtlichen Code, ganz zu schweigen von der Wartbarkeit, eingetauscht gegen Synconiationsoverhead. Naja wenigstens stürzt das Programm nicht ab.

PatTheMav
2007-06-14, 00:30:47
Ich sage es jetzt noch ein letztes mal deutlich. Wenn mehrere Threads in eine Ausgabe schreiben wird es zu Problemen kommen! Und da sind Magenschmerzen das geringste Problem.
Natürlich haste recht, aber das Programm wird ja nichts für den Produktiveinsatz, sondern nur billiges "das kann man machen"-Beispiel.

Ist ja dasselbe, wenn man Timings von mehreren Threads ungefiltert auf stdout raushaut, da haste auch Kraut und Rüben und die Professoren sind entzückt...

del_4901
2007-06-14, 06:37:02
Wenn ich dein Prof währ, würde ich dir den Versuch Sachen zu parallelisieren, welche nicht paralleliserbar sind, um die Ohren hauen! Aber ganz gewaltig.

Also zeichne Apfelmännchen oder irgendwas anderes, was parallelisierbar ist.

Ectoplasma
2007-06-14, 08:19:25
Also habe ich in .NET im Grunde keinen direkten Einfluss darauf, was auf welchem Core läuft, also meinetwegen ne Sound-Decodierung auf den einen, die Video-Decodierung auf den anderen Kern zu legen?

Das ewige Mißverständnis. Wozu willst du das? Das System kümmert sich selbst um die Zuweisung eines Threads an eine CPU und zwar ziemlich effizient. Die Sache mit einer dedizierten CPU Zuweisung ist dagegen ineffizient.

Shink
2007-06-14, 08:27:19
Ist ja dasselbe, wenn man Timings von mehreren Threads ungefiltert auf stdout raushaut, da haste auch Kraut und Rüben und die Professoren sind entzückt...
Ahja, naja gut...

Klar kann man gut Dinge parallel berechnen, die man dann ausgibt, aber die Ausgabe kann ohnehin nie parallel sein (probier doch mal, auf einem Pixel am Bildschirm zwei Farben gleichzeitig darzustellen), also:
- Parallel berechnen.
- Ergebnisse in eine Queue stellen, die für Einsatz mit mehreren Threads gedacht ist.
- Einen eigenen Thread anstellen, der die Queue leert und darstellt/hinausschreibt/etc. (Bzw: der den "Redraw"-Thread der Forms dazu zwingt).

Wenn du tatsächlich Dinge einzelnen Prozessoren zuweisen willst, benötigst du MPI - das zu tun ist aber nur bei Rechnern ohne gemeinsamem Speicher sinnvoll und dort auch für viele Algorithmen notwendig.

Monger
2007-06-14, 08:40:22
Dann muss man eben synchronisieren, wenn es mehrere Threads sein sollen.
Damit muss man sich aber irgendwann einmal auseinandersetzen.

GUIs haben die böse Eigenschaft, schnell mal nen Deadlock zu produzieren. Java ist dafür ein Musterbeispiel: da hatten sie zu Anfang das ganze AWT Framework auf Threadsicherheit ausgelegt um die Oberfläche eben mit mehreren Threads rendern zu können. Das hat dann aber so viel Probleme gemacht, dass sie mit jeder Version mehr und mehr zurückgerudert sind, bis eben mittlerweile von der einstigen Parallelität nichts mehr übrig geblieben ist.

Multithreading an der Stelle ist nicht etwa kompliziert oder schwierig, sondern schlicht unkontrollierbar und sinnlos. Um Himmels Willen die Finger davon lassen!
Das hat sich AlphaTier nicht einfach so aus den Fingern gesogen, sondern das ist einfach Common Sense.

Gast
2007-06-14, 09:16:34
Und die Synchronisation sorgt dann dafür das eh immer nur einer dran kommt.
Ganz tolles Kino! Dann habe ich 0 Parallität, mehr Klassen, unübersichtlichen Code, ganz zu schweigen von der Wartbarkeit, eingetauscht gegen Synconiationsoverhead. Naja wenigstens stürzt das Programm nicht ab.

Der Sinn deiner Aussage erschließt sich mir nicht. Du lagerst natürlich Berechnungen in Threads aus, die eine gewisse Last verursachen. Wenn diese dann mal fertig sind, schreibst du die Ergebnisse zurück in die GUI. Oder als Bsp. wäre ganz einfach eine Progressbar zu nennen: Du hast einen Thread, der irgend eine Arbeit verrichtet und rufst dann in festen Abständen eine Callback im GUI Thread auf, die den Fortschrittsbalken setzt. Das ist Alltgag und gang und gebe. Verstehe nicht, wie man so etwas anzweifeln kann.

del_4901
2007-06-14, 09:21:52
Der Sinn deiner Aussage erschließt sich mir nicht. Du lagerst natürlich Berechnungen in Threads aus, die eine gewisse Last verursachen. Wenn diese dann mal fertig sind, schreibst du die Ergebnisse zurück in die GUI. Oder als Bsp. wäre ganz einfach eine Progressbar zu nennen: Du hast einen Thread, der irgend eine Arbeit verrichtet und rufst dann in festen Abständen eine Callback im GUI Thread auf, die den Fortschrittsbalken setzt. Das ist Alltgag und gang und gebe. Verstehe nicht, wie man so etwas anzweifeln kann.

Ich habe nur gesagt das mehrere Threads nicht in eine Ausgabe schreiben sollten. Ich habe nie behauptet, das man Ergebnisse nicht an diesen einen Thread liefern kann.

][immy
2007-06-14, 09:22:06
bei der GUI musst du darauf achten, das wenn du etwas von einem anderen thread aus ändern möchtest (z.B. cursor verändern oder solche spielerein) das du immer zu dem thread in dem das control verwaltet wird (was dann meist der hauptthread ist). ansonsten bekommst du immer nette fehler.

wenn du z.B. in einem anderen thread auf ein control zugreifen möchtest solltest du die InvokeRequired-Eigenschaft abfragen. ist diese true musst du dich in den entsprechenden thread einklinken.
mehr dazu kannst du aber auch hier (http://msdn2.microsoft.com/de-de/library/system.windows.forms.control.invokerequired(VS.80).aspx)nachlesen.

Novox
2007-06-14, 17:19:33
[immy;5584311']wenn du z.B. in einem anderen thread auf ein control zugreifen möchtest solltest du die InvokeRequired-Eigenschaft abfragen. ist diese true musst du dich in den entsprechenden thread einklinken.
mehr dazu kannst du aber auch hier (http://msdn2.microsoft.com/de-de/library/system.windows.forms.control.invokerequired(VS.80).aspx)nachlesen.

Oder einfach System.ComponentModel.BackgroundWorker verwenden.

SgtTynis
2007-06-15, 13:16:55
Oder einfach System.ComponentModel.BackgroundWorker verwenden.

Der Backgroundworker leidet wie so manche Komponente im .NET daran, dass er zwar 80% der Anwendungsfälle abdeckt, man aber immer der Depp ist, der gerade einen der verbleibenden 20% nicht unterstützten Anwendungsfälle lösen muss :rolleyes:

Novox
2007-06-15, 16:11:02
Der Backgroundworker leidet wie so manche Komponente im .NET daran, dass er zwar 80% der Anwendungsfälle abdeckt, man aber immer der Depp ist, der gerade einen der verbleibenden 20% nicht unterstützten Anwendungsfälle lösen muss :rolleyes:
Sofern es nur um Rückmeldung von Worker-Threads an die GUI geht, ist das Ding gut geeignet - und dafür ist es ja auch da. Die eigentliche Arbeit kann man problemlos "manuell" gesteuerte Threads erledigen lassen.

PatTheMav
2007-06-15, 17:59:16
Die GUI selbst soll ja nicht multithreaded sein - das soll halt nur ein brauchbares Interface für die dahinter zu steuernden MP-Geschehnisse sein.

Also meinetwegen eine GUI für ein Apfelmännchen-Zeichenprogramm, dass die Berechnungen auf zwei Cores ausführt oder sowas .. oder habt ihr da einfachere Ideen? Das soll nämlich vom Aufwand nicht so gross wie ein Projekt, sondern eher im Rahmen einer 90-Minuten-Klausur bleiben (dafür ist das als Ersatz gedacht, weil die Klausur nicht mehr angeboten wird und mein Kollege und ich das Modul brauchen).

Shink
2007-06-16, 17:41:09
Wenn du nen Prof beeindrucken willst: Den Klassiker Matrixmultiplikation, mit z.B. 2 hoch n vielen Threads, wobei n einstellbar ist.

PatTheMav
2007-09-18, 15:29:00
Ahoi - ich dacht mal, ich erzähl euch, was ich nun schlussendlich für meinen Prof realisiert hab.

Da die Abgabe nur noch 2 Wochen entfernt war und ich (mal wieder ;)) nichts gemacht hab in der Zwischenzeit hab ich ein ganz billiges GUI gebaut, dass im unteren Teil je nach Anzahl Prozessoren im System wie der Taskmanager die CPU-Auslastungen anzeigt mitsamt Graphen.

Um die Dinger dann nur mit meinem Programm fleißig auslasten zu können, kann man sich zwei Dateien auswählen und die einzeln oder beide gleichzeitig mit dem GZIP-Funktionen von .NET komprimieren lassen. Ne schicke Progressbar für jede Datei wird auch angezeigt, so dass man den Fortschritt für beide beobachten kann.

Das ganze funktioniert auch wie erwartet - bei der Kompression einer Datei wird die Last gleichmäßig aufgeteilt, wenn beide Komprimieren arbeiten beide Cores bei 100%, wenn eine Datei länger braucht, sieht man wie nach kurzer zeit die Last vom immer noch komprimierenden Core wieder auf beide verteilt wird.

Ich weiß, das ist nicht unbedingt hohe Programmierkunst, aber ich musste mich auch in .NET erstmal einarbeiten :p Es sieht auch alles sehr schick aus, es blinkt, es tut sich was, Progressbars, CPU-Graphen usw. und als Bonus kann man beobachten was der Scheduler mit den beiden Threads so alles treibt :)

Johnny
2007-09-19, 10:15:30
Hätte Interesse daran. Kannst ja mal uppen, wenn das so geil ist?

PatTheMav
2007-09-25, 18:02:12
Ja wenn der Prof das abgenommen hat, kann ich das mal zur Verfügung stellen. Is aber bestimmt nich so toll, wie du es dir vorstellst ;)