mikrocontroller.net

Forum: PC-Programmierung Windows c++ multicore


Announcement: there is an English version of this forum on EmbDev.net. Posts you create there will be displayed on Mikrocontroller.net and EmbDev.net.
Autor: Günther G. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo

gibt es eine einfache Möglichkeit ein bereits bestehendes und 
rechenintensives Programm in c++ auf Multicore zu optimieren? Momentan 
wird laut taskmanager jeweils ein core (abwechselnd) zu 100 % 
ausgelastet während die anderen "schlafen"

Autor: Keiner N. (nichtgast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Kommt drauf an

OpenMP
Boost::threading
Modernes C++ mit seinen threads

Nur so als Schlagwörter in den Raum geworfen. Ob es es hilft oder ob es 
geht hängt von deinem Programm ab.

Autor: Random .. (thorstendb) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Du kannst schauen, welche Teile sich parallelisieren lassen. Beachte 
aber den gemeinsam genutzten Speicher, ggf. werden Mutexe und andere 
Techniken beim Speicher benötigt.
Ganze Teile kannst du z.B. einfach mit AfxBeginThread() auslagern, 
arbeitsintensive Schleifen gewinnen ggf. durch parallel_for(), wenn die 
einzelnen Durchläufe voneinander unabhängig sind.
Warscheinlich musst du dafür deine Programmarchitektur überarbeiten.

: Bearbeitet durch User
Autor: Dr. Sommer (Gast)
Datum:

Bewertung
1 lesenswert
nicht lesenswert
Günther G. schrieb:
> gibt es eine einfache Möglichkeit ein bereits bestehendes und
> rechenintensives Programm in c++ auf Multicore zu optimieren?

Nein. Parallelisierung ist prinzipbedingt eine (sehr) komplizierte 
Angelegenheit. Wenn das "einfach" ginge wären ganze Zweige der 
Informatik arbeitslos.

Es gibt eine ganze Reihe von Paradigmen und Werkzeugen zur 
Parallelisierung. Je nach Aufgabe kann es mit den richtigen Werkzeugen 
sehr einfach sein oder eben auch nicht. Das Problem bei den 
"klassischen" Paradigmen (Threading+Locks) ist, dass es schnell sehr 
schwierig wird, ein korrektes Programm zu erstellen - es gibt sehr viele 
fiese Sonderfälle und Details zu beachten, und wenn man alles richtig 
gemacht hat stellt man fest, dass es durch die Parallelisierung 
langsamer geworden ist...

Etwas Literatur:
https://www.amazon.com/dp/1933988770/
https://www.amazon.com/dp/1937785653/
https://www2.eecs.berkeley.edu/Pubs/TechRpts/2006/EECS-2006-1.pdf

Vielleicht ist es sinnvoll als Erstes mal festzustellen, warum das 
Programm langsam ist. Vielleicht gibt es ja noch einige gute 
Optimierungsmöglichkeiten.

Autor: Jim M. (turboj)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Günther G. schrieb:
> ein bereits bestehendes und
> rechenintensives Programm in c++ auf Multicore zu optimieren?

Wenn es wirklich rechenintensiv ist, wäre auch das Auslagern auf die GPU 
via CUDA/OpenCL zu betrachten. Moderne GPUs haben erheblich mehr 
Leistung als CPUs.

Das wird aber alles andere als billig was Hirnschmalz und 
Programmieraufwand betrifft.

Autor: Dirk K. (merciless)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Günther G. schrieb:
> Hallo
>
> gibt es eine einfache Möglichkeit ein bereits bestehendes und
> rechenintensives Programm in c++ auf Multicore zu optimieren? Momentan
> wird laut taskmanager jeweils ein core (abwechselnd) zu 100 %
> ausgelastet während die anderen "schlafen"

Wenn das Rechenintensive ein Algorithmus ist,
der sich parallelisieren lässt, ja. Wobei:
"einfach" ist da relativ.

merciless

Autor: Irgend W. (Firma: egal) (irgendwer)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Jim M. schrieb:
> Wenn es wirklich rechenintensiv ist, wäre auch das Auslagern auf die GPU
> via CUDA/OpenCL zu betrachten. Moderne GPUs haben erheblich mehr
> Leistung als CPUs.

Aber nur wenn es um numerische Rechenleistung geht.
"Rechenintensiv" kann noch eine ganze Menge mehr bedeuten und Sachen 
dabei sein wo eine GPU maximalst ungeeignet dafür ist.
Das "dumme" an GPU ist das die nur einige wenige Sachen gut können, 
diese dafür aber halt richtig gut. Vieles andere können sie eben nicht, 
bzw. können es aber nur extrem langsam im Vergleich zu einer CPU. Wenn 
es nicht so wäre, wären die CPU schon lange ausgestorben und nur noch 
GPU im Einsatz.

Auf jeden Fall, einfach bei dem ganze Thema Parallelisierung fast 
nichts.
Und noch lange nicht alles was man da mit teilweise vielen Hunderten von 
Arbeitsstunden ausprobiert führt am ende auch zum Erfolg:-(

Autor: Oliver S. (oliverso)
Datum:

Bewertung
-2 lesenswert
nicht lesenswert
Irgend W. schrieb:
> Auf jeden Fall, einfach bei dem ganze Thema Parallelisierung fast
> nichts.

Wenn die Aufgabe einfach parallelisierbar ist, ist die Umsetzung auch 
einfach. Wenn nicht, dann nicht.

Seltsam ist beim TO allerdings, daß da jetzt schon mehrere Cores 
abwechselnd aktiv werden. Von alleine tut ein einzelnes C++-Program so 
etwas nicht, da muß schon eine Multithreading-lib im Hintergrund 
werkeln.

Oliver

: Bearbeitet durch User
Autor: Dr. Sommer (Gast)
Datum:

Bewertung
1 lesenswert
nicht lesenswert
Oliver S. schrieb:
> Seltsam ist beim TO allerdings, daß da jetzt schon mehrere Cores
> abwechselnd aktiv werden. Von alleine tut ein einzelnes C++-Program so
> etwas nicht, da muß schon eine Multithreading-lib im Hintergrund
> werkeln.

Nö, das macht das OS (Windows, Linux) ganz von alleine. Es verschiebt 
die Prozesse zwischen den Cores um die Hitzeentwicklung zu verteilen. 
Das kann man auch konfigurieren...

Autor: Oliver S. (oliverso)
Datum:

Bewertung
-2 lesenswert
nicht lesenswert
Unabhängige Prozessse natürlich, aber einen einzigen 
Single-Thread-Prozeß verschiebt kein Betriebsssystem mitten im Lauf von 
einem auf einen anderen Core. Ich verstehe ich die Ausage des TO so,daß 
da bei laufendem Programm die Cores abwechseln belastet werden. Das geht 
nur mit (schlecht gemachtem) Multithreading in der Applikation.

Oliver

Autor: Dr. Sommer (Gast)
Datum:

Bewertung
1 lesenswert
nicht lesenswert
Oliver S. schrieb:
> Unabhängige Prozessse natürlich,

Was ist denn ein abhängiger Prozess?

Oliver S. schrieb:
> aber einen einzigen
> Single-Thread-Prozeß verschiebt kein Betriebsssystem mitten im Lauf von
> einem auf einen anderen Core.

Doch, Windows macht das definitiv. Kompiliere dieses Programm:
int main () {
  while (1);
}
und siehe da, der Prozess wird regelmäßig über die Cores verschoben. 
Macht ja auch Sinn, denn wenn das die ganze Zeit auf einem Core hängt 
wird der  heiß und muss runtergetaktet werden.

Oliver S. schrieb:
> Das geht
> nur mit (schlecht gemachtem) Multithreading in der Applikation.

Das geht auch wenn der OS-Scheduler den Single-Thread-Prozess 
verschiebt...

https://docs.microsoft.com/en-us/windows/win32/procthread/multiple-processors
https://stackoverflow.com/a/28921779/4730685

Autor: mh (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Oliver S. schrieb:
> Unabhängige Prozessse natürlich, aber einen einzigen
> Single-Thread-Prozeß verschiebt kein Betriebsssystem mitten im Lauf von
> einem auf einen anderen Core. Ich verstehe ich die Ausage des TO so,daß
> da bei laufendem Programm die Cores abwechseln belastet werden. Das geht
> nur mit (schlecht gemachtem) Multithreading in der Applikation.
>
> Oliver

Dann muss ich wohl suchen, wo in meinen Projekten das schlecht gemachte 
Multithreading versteckt ist. Muss ganz vergessen haben, dass ich es 
eingebaut habe.

Autor: Oliver S. (oliverso)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ok, ich nehme alles zurück, und behaupte das Gegenteil. Macht Windows 
tatsächlich.

Oliver

Autor: mh (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Oliver S. schrieb:
> Ok, ich nehme alles zurück, und behaupte das Gegenteil. Macht Windows
> tatsächlich.

Nicht nur Windows

Autor: Johann L. (gjlayde) Benutzerseite
Datum:

Bewertung
1 lesenswert
nicht lesenswert
Günther G. schrieb:
> gibt es eine einfache Möglichkeit ein bereits bestehendes und
> rechenintensives Programm in c++ auf Multicore zu optimieren?

Schau mal nach OpenMP.

Eine einfache, parallelisierbare Schleife ist da ein Klacks, einfach das 
entsprechende Pragma dazu und fertig.  Auch wie die Cores zugeordnet 
werden kann man einfach angeben.

Mit GCC das Programm mit -fopenmp compilieren und fertig...

http://gcc.gnu.org/onlinedocs/libgomp/
https://www.openmp.org/
void simple (int n, float *a, float *b)
{
    int i;

#pragma omp parallel for
    for (i = 1; i < n; i++) /* i is private by default */
        b[i] = (a[i] + a[i-1]) / 2.0;
}

Aus: https://www.openmp.org/wp-content/uploads/OpenMP4.0.0.Examples.pdf

Threads nehme ich etwa um GUI-Elemente unabhängig zu halten, z.B. würde 
die obige Routine in einem eigenen Thread laufen, damit andere 
GUI-Elemente nicht "einfrieren" und aktiv bleiben während gerechnet 
wird.

Ob diese Threads auf unterschiedlichen Cores laufen oder per Time-Slice 
auf dem gleichen ist dann Wurscht.

Autor: Ergo70 (Gast)
Datum:

Bewertung
1 lesenswert
nicht lesenswert
Oder Intel TBB. Funktioniert auch mit AMD CPUs und ist oft etwas 
schneller als OpenMP, bei minimal höherem Programmieraufwand.

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.