Ich portiere Code in Windows und finde Threading extrem langsam. Die Aufgabe dauert 300 Sekunden unter Windows (mit zwei xeon E5-2670 8-Core 2.6 GHz = 16 Core) und 3,5 Sekunden unter Linux (Xeon E5-1607 4 Core 3 GHz). Mit vs2012 Express.Portieren von Threads zu Fenstern. Kritische Abschnitte sind sehr langsam
Ich habe 32 Threads alle aufrufen EnterCriticalSection(), einen 80-Byte-Job von einem std :: stack, LeaveCriticalSection und einige Arbeit (250k Jobs insgesamt). Ich drucke die Thread-ID und die aktuelle Uhrzeit
Vor und nach jedem kritischen Abschnitt Anruf.
- Die Wartezeit für eine Sperre des einzelnen Thread ist ~ 160ms
- den Job Pop-off der Stapel ~ 3 ms
- Aufruf Urlaub nimmt ~ 3 ms
- Der Job ~ nimmt 1ms
(ungefähr gleich für Debug/Release, Debug dauert ein wenig länger. Ich würde gerne in der Lage sein, den Code richtig Profil: P)
Kommentieren Der Job-Aufruf dauert 2 Sekunden (immer noch mehr als Linux).
Ich habe versucht, sowohl die Queryperformancecounter und timeGetTime, beide geben ca. das gleiche Ergebnis.
AFAIK den Job macht nie sync Anrufe, aber ich kann die Verlangsamung nicht erklären, es sei denn, es tut.
Ich habe keine Ahnung, warum das Kopieren von einem Stapel und ruft Pop so lange dauert. Eine weitere sehr verwirrende Sache ist, warum ein Anruf zu verlassen() so lange dauert.
Kann jemand darüber spekulieren, warum es so langsam läuft?
würde ich nicht den Unterschied in dem Prozessor habe gedacht, einen 100x Performance-Unterschied geben, aber könnte es überhaupt zu Dual-CPUs zusammenhänge? (Synchronisation zwischen separaten CPUs als internen Kernen).
By the way, ich bin mir dessen bewusst std :: thread aber meine Bibliothek Code wollen mit pre C++ 11 zu arbeiten.
bearbeiten
//in a while(hasJobs) loop...
EVENT qwe1 = {"lock", timeGetTime(), id};
events.push_back(qwe1);
scene->jobMutex.lock();
EVENT qwe2 = {"getjob", timeGetTime(), id};
events.push_back(qwe2);
hasJobs = !scene->jobs.empty();
if (hasJobs)
{
job = scene->jobs.front();
scene->jobs.pop();
}
EVENT qwe3 = {"gotjob", timeGetTime(), id};
events.push_back(qwe3);
scene->jobMutex.unlock();
EVENT qwe4 = {"unlock", timeGetTime(), id};
events.push_back(qwe4);
if (hasJobs)
scene->performJob(job);
und der Mutex-Klasse, mit Sachen Linux #ifdef entfernt ...
CRITICAL_SECTION mutex;
...
Mutex::Mutex()
{
InitializeCriticalSection(&mutex);
}
Mutex::~Mutex()
{
DeleteCriticalSection(&mutex);
}
void Mutex::lock()
{
EnterCriticalSection(&mutex);
}
void Mutex::unlock()
{
LeaveCriticalSection(&mutex);
}
Was verwendeten Sie unter Linux? Schützen Sie nur den Zugriff auf den std :: stack mit den kritischen Abschnitten? – xanatos
Wo drucken Sie die Thread-ID und die aktuelle Zeit? – avakar
Wählen Sie eine Sprache. Und das scheint seltsam. Es klingt sicher * einfach * genug für eine [SSCCE] (http://www.sscce.org) um praktikabel zu sein. Ich stimme zu, dass meine Erfahrung mit Windows im Vergleich zu einer vergleichbar ausgestatteten Linux-Distribution etwas glanzlos war, aber das scheint wirklich eine ziemlich große Kluft zu sein. – WhozCraig