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"
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.
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.
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.
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.
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
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:-(
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
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...
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
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:
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.
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/
1
voidsimple(intn,float*a,float*b)
2
{
3
inti;
4
5
#pragma omp parallel for
6
for(i=1;i<n;i++)/* i is private by default */
7
b[i]=(a[i]+a[i-1])/2.0;
8
}
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.