Mehrere CPU Kerne in C nutzen

#2858254
Lesenswert?

> z.b mit threats

Ich bekomme Angst ;)

Unter Unixoiden in plain-C sind pthreads das Mittel der Wahl für 
allgemeine Parallelisierung:

https://computing.llnl.gov/tutorials/pthreads/

In C++ kann man pthreads auch nutzen, muss aber mit Wrappern arbeiten, 
damit man wieder ein this-Pointer bekommt. Da kann man dann gleich die 
Threads aus einem Toolkit nehmen (Qt, ...).

Wenn es in Richtung High-Performance-Computing zur Parallelisierung von 
Algorithmen geht: OpenMP

http://openmp.org/wp/

Kann der gcc auch schon: http://gcc.gnu.org/wiki/openmp
Dazu gibt man im Code selbst per pragmas Hinweise auf parallel 
ausführbare Teile (for-Schleifen, etc.).
#2858362
Lesenswert?

an der uni haben wir mal in einer vorlesung mpi und openmp miteinander 
kombiniert. das macht spaß - und wenn man nicht aufpasst hat man sehr 
schnell einen knoten im hirn ;-)

kommt darauf an was du machen willst. für eine shared-memory-maschine 
würde ich openmp empfehlen, ist recht einfach zu handlen. wenns 
hauptsächlich um den lerneffekt geht: selber machen (threads, signals, 
shared memory, semaphoren, ...)
Persönliche Seite #2858609
Lesenswert?

Georg A. schrieb:
> Unter Unixoiden in plain-C sind pthreads das Mittel der Wahl für
> allgemeine Parallelisierung

Die ernstgemeinten Windows-Versionen bieten seit 1993 ihre eigene 
Variante von Threads an und sind seitdem auch in der Lage, diese 
automatisch auf mehrere Kerne bzw. mehrere CPUs zu verteilen.

Threads werden entweder mit der Win32-API-Funktion CreateThread oder (je 
nach Compiler und Runtime-Unterstützung) mit _beginthread resp. 
_beginthreadex erzeugt.

Wenn hingegen tatsächlich Prozesse im Sinne eigenständiger Programme 
gemeint ist, dann heißt die zu verwendende Win32-API-Funktion 
CreateProcess.

Mit den Win32-API-Funktionen SetProcessAffinityMask und 
SetThreadAffinityMask lässt sich die Verteilung von Prozessen und 
Threads auf einzelne Kerne/Prozessoren beeinflussen.
#2860133
Lesenswert?

> Was ist das schnellste von diesen Verfahren?

Schnell im Sinne von schnell zu schreiben: pthreads

Allerdings solltest du dich auch mit den Synchronisationsmechanismen 
zwischen den Threads auseinandersetzen. Irgendwie müssen die Daten ja 
die Threads wechseln... Da gibt es viele Stolperfallen, wenn man es das 
erste Mal macht. Die pthreads haben dazu auch ein paar hilfreiche Calls.
#2861276
Lesenswert?

> Für die Kommunikation zwischen den Threads bieten sich Pipes an.

Hängt von der Art der notwendigen Kommunikation ab. Nicht alles lässt 
sich gut auf ein so Stream-Modell übertragen. Das kann in ein ziemliches 
Kommandorumgeschiebe ausarten, dann gibts noch das Problem von Blocking 
und potentieller De-Synchronisation.

Pipes sind auch nicht besonders effizient, weil sie trotz selbem 
Adressraum durch den Kernel gehen. Bei grösseren Datenmengen ist es 
deutlich effizienter, das FIFO selber zu schreiben. Solange ein(1) 
Prozess nur schreibt und einer(1) nur liest, kommt man auch ohne 
Semaphore&Co aus.
#2861307
Lesenswert?

Konrad S. schrieb:
> Interessante Hypothese! Cache-Kohärenz?

Ist das gleiche Verfahren, mit dem man auch Puffer von UARTs im 
Interrupt-Betrieb betreiben kann, ohne im Hauptprogramm die Interrupts 
abschalten zu müssen. Voraussetzung dafür ist, dass Cache-Kohärenz 
gewährleistet ist, Lese- und Schreiboperationen der Indizes atomar sind 
und das memory ordering model gewissen Ansprüchen genügt. Ein meist 
harmloser Nebeneffekt ist, dass ein N Bytes grosser Puffer nur maximal 
N-1 Bytes aufnehmen kann.

Bei PC-Systemen sind diese Vorbedingungen gewährleistet. Allerdings kann 
die Kohärenz auf die Performance drücken, wenn auf die Indizes in sehr 
kurzen Abständen durch verschiedene Cores zugegriffen wird. Das kann 
Thrashing zur Folge haben, d.h. Cache-Lines wandern in schneller Folge 
zwischen den Caches der Cores hin und her. Das ist nicht ganz billig.

Hat man es also mit hohen Datenraten zu tun, bei denen dieser Effekt 
relevant wird, dann können andere Verfahren sinnvoller sein.
#2861312
Lesenswert?

Konrad S. schrieb:
> Sind ja 'ne ganze Menge Nebenbedingungen.

Geht so. Wer in der Doku von 32-Bit Cores wie den Cortex-M schon mal 
über das Thema memory ordering models stolperte, der weiss jetzt 
wenigstens an welcher Stelle so etwas relevant ist. ;-)

> Mutexes und Condition-Variablen und es funktioniert auch auf 'nem großen
> Hobel ohne Probleme.

So arg viele deutlich grössere shared memory Hobel als PCs und PC-Server 
gibts andererseits nicht mehr. Bei den wirklich grossen Clustern mit 
hunderten von Prozessoren (oder mehr) funktioniert die Kommunikation 
ohnehin nicht mehr über shared memory. Und dann muss man das betreffende 
System genau kennen und sich im Vorfeld klare Gedanken über das 
Zeitverhalten der Kommunikation machen, sonst kann es passieren, dass 
die daneben stehende PC-Workstation schneller fertig ist.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren