2017-01-08 8 views
2

Ich bin verwirrt der Geschwindigkeit unterscheidet zwischen der Verwendung der Mutex lock() und entsperren() innerhalb und außerhalb einer for-Schleife. Ich habe einen globalen Variablenwert und eine Funktion, die es 1000000 mal erhöht. Diese Funktion wird parallel von 5 Threads ausgeführt. Ich maß die verstrichene Zeit und bekam diese Ergebnisse:Mutex Lock Geschwindigkeit Unterschied innerhalb und außerhalb der foor Schleife

mutex.lock(); 
    for(int i = 0; i < 1000000; i++) 
    { 
     value++; 
    } 
    mutex.unlock(); 

0,160921 Sekunden lang

und:

for(int i = 0; i < 1000000; i++) 
    {   
     mutex.lock(); 
     value++; 
     mutex.unlock(); 
    } 

2,10521 Sekunden lang

ich mit der zweiten inneren Mutex Anordnung übernehmen die Steuerung zu Gut und viel Zeit wird zwischen den Threads verbracht? oder gibt es noch etwas anderes?

Antwort

3

Das Sperren und Entsperren eines Mutex dauert einige Zeit. Insbesondere dauert es viel länger als eine ganze Zahl inkrementieren. Das zweite Beispiel testet nur die Geschwindigkeit für das Sperren/Entsperren und fügt auch den Overhead für das Task-Switching hinzu, da an jedem Punkt, an dem der Mutex entsperrt ist, ein anderer Thread das Kommando übernehmen könnte.

Und in der ersten könnte der Compiler nur die Schleife durch eine einzige Ergänzung ersetzen. Und da die gesamte Funktion des Threads vom Mutex abgedeckt wird, gibt es keine parallele Ausführung. Alle Threads außer einem werden nur blockiert, bis die Schleife des einen abgeschlossen ist, was bedeutet, dass der Code gleichbedeutend damit ist, dass die Schleife fünf Mal hintereinander in einem einzelnen Thread ausgeführt wird.

Dies hat wenig mit Fein- und Grobkorn-Verriegelung zu tun. Bei diesen Strategien geht es darum, ob Sie nur wenige Sperren für viele Ressourcen oder viele Sperren für wenige Ressourcen haben. Sie haben nur eine Ressource (das globale int) und somit keine Entscheidung zu treffen. Stattdessen geht es darum, den Mutex nur für kurze Zeit zu sperren, damit er den Rest der Zeit für andere Threads offen bleibt, um Arbeit zu verrichten, oder ihn für längere Zeit sperren, um Overhead zu vermeiden, aber Parallelität zu reduzieren. Da Ihre Threads jedoch nur Zugriff auf die geschützte Ressource haben, gibt es keine "rest of the time". Ihr Problem (Inkrementieren einer Integer 5000000 mal) hat inhärent keine inhärente Parallelität und somit nichts für mehrere Threads auszunutzen.

Verwandte Themen