Ich bin nicht sicher, warum OpenMP so viele Threads verwendet. Es scheint nicht mit der Microsoft-Implementierung verwandt zu sein, da ich auch die Intel-Bibliothek ausprobiert habe, die das gleiche Verhalten zeigt. Ich habe einige parallele Abschnitte in meinem Code, die compute-gebunden sind und nicht mehr Threads erstellen und verwenden sollten als ich Kerne habe. Aber was ich beobachtet habe, ist, dass OpenMP für n initiierende Threads n * Cores-Threads erstellt. Das sieht für mich wie ein großer Thread aus.OpenMP erstellt zu viele Threads
Wenn ich eine "kleine" 32-Bit-Anwendung auf einem Server ausführen, kann es fehlschlagen, da 1000 OpenMP-Threads 2 GB Adressraum bereits keinen Speicher für die Anwendung benötigen. Das sollte nicht passieren. Ich würde von einem State-of-the-Art-Thread-Pool erwarten, seine Threads wiederzuverwenden und nicht mehr verwendete Threads zu entfernen.
Ich habe versucht, omp_set_num_threads (8) verwenden, um die Thread-Pool-Größe auf 8 Kerne zu begrenzen, aber das scheint nur die Anzahl der Threads pro initiierenden Thread-Instanz zu begrenzen. Mache ich alles falsch oder soll OpenMP nicht so verwendet werden?
Auf meinem 8-Core-Maschine 5 gestartet Threads in meiner AsyncWorker-Klasse wird 38 Threads von OpenMP erstellt zuweisen. Ich würde erwarten, dass nur 8 Threads erstellt werden und diese sollten über alle 5 initiierenden Threads wiederverwendet werden.
#include <atomic>
#include <thread>
#include <omp.h>
#include <chrono>
#include <vector>
#include <memory>
class AsyncWorker {
private:
std::vector<std::thread> threads;
public:
AsyncWorker()
{
}
void start() // add one thread that starts an OpenMP parallel section
{
threads.push_back(std::thread(&AsyncWorker::threadFunc, this));
}
~AsyncWorker()
{
for (auto &t : threads)
{
t.join();
}
}
private:
void threadFunc()
{
std::atomic<int> counter;
auto start = std::chrono::high_resolution_clock::now();
std::chrono::milliseconds durationInMs;
while (durationInMs.count() <5000l)
{
// each instance seems to get its own thread pool.
// Why? And how can I limit the threadpool to the number of cores and when will the threads be closed?
#pragma omp parallel
{
counter++;
auto stop = std::chrono::high_resolution_clock::now();
durationInMs = std::chrono::duration_cast<std::chrono::milliseconds>(stop - start);
}
}
}
};
int main() {
//omp_set_dynamic(0);
//omp_set_nested(0);
//omp_set_num_threads(8);
{
AsyncWorker foo;
foo.start(); // 1
foo.start(); // 2
foo.start(); // 3
foo.start(); // 4
foo.start(); // 5
system("pause");
}
return 0;
}
Also unter welchen Umständen sind die Threads freigegeben? Bis jetzt sieht es nie aus. Die initiierenden Threads enden und der zugehörige Threadpool bleibt glücklich. Wie soll ich Ressourcen auf großen Kisten mit Hunderten von Kernen verwalten, wo dies den Speicherbedarf aufgrund tausender zugewiesener Thread-Stacks wirklich beeinträchtigt. Ist das Design von OpenMP wirklich so, dass es nur einen initiierenden Thread von parallelen Aktionen geben muss? Ich kann nicht glauben, dass C++ noch so weit zurückliegt, um echtes Multithreading zu unterstützen. –
Ich denke, ich werde mit set OMP_THREAD_LIMIT =% NUMBER_OF_PROCESSORS% gehen, um die Anzahl der OpenMP-Threads zu begrenzen. Dies scheint eine vernünftige Wahl für CPU-gebundene parallele Operationen zu sein, die möglicherweise mehrere parallele Operationen gleichzeitig erzeugen können. –
Übrigens ist es sicher, OMP_THREAD_LIMIT https://software.intel.com/en-us/node/522775 zu verwenden. Laut Intel könnte es manchmal Ihren Prozess zum Absturz bringen? "... Wenn dieses Limit erreicht ist und ein anderer nativer Betriebssystem-Thread auf OpenMP * API-Aufrufe oder -Konstrukte stößt, kann das Programm mit einer Fehlermeldung abbrechen ....". Bedeutet das, dass ich die Anzahl der OpenMP-Threads nicht sicher begrenzen kann? –