Frage

Ist Interlocked.Increment(ref x) schneller oder langsamer als x++ für ints und sehnt sich auf verschiedenen Plattformen?

War es hilfreich?

Lösung

Es ist langsamer, da es die Aktion zwingt atomar auftreten und es fungiert als eine Speicherbarriere, die Fähigkeit des Prozessors Beseitigung neu zu ordnen den Befehlsspeicher zugreift um.

Sie sollten Interlocked.Increment verwenden, wenn Sie die Aktion wollen Zustand Atom sein, die zwischen den Threads gemeinsam genutzt werden können -. Es ist kein vollwertiger Ersatz für x sein ist bestimmt ++

Andere Tipps

Nach unserer Erfahrung der InterlockedIncrement () et al unter Windows sind ganz erhebliche Auswirkungen. In einer Probe Fall konnten wir die Verriegelung beseitigen und verwendet ++ / - statt. Dies allein reduzierte Laufzeit von 140 Sekunden bis 110 Sekunden. Meine Analyse ist, dass die Verriegelung eine Speicherumlauf zwingt (sonst wie andere Kerne sehen konnte?). Ein L1-Cache-Lese / Schreib etwa 10 Taktzyklen, sondern ein Speicher-Lese / Schreib mehr wie 100.

In diesem Beispiel Fall schätzte ich die Anzahl der Inkrement / Dekrement-Operationen bei etwa 1 Milliarde. So auf einem 2GHz CPU ist dies etwas, wie 5 Sekunden für die ++ / -, und 50 Sekunden für die Verriegelung. Verbreiten Sie die Differenz über mehrere Threads und seine knapp 30 Sekunden.

Denken Sie darüber für einen Moment, und du wirst ein Increment Anruf erkennen, nicht schneller als eine einfache Anwendung des Inkrementoperator sein kann. Wenn es so wäre, dann wäre die Implementierung des Compilers des Inkrementoperator ruft Increment intern, und sie würden das gleiche durchführen.

Aber, wie Sie durch Testen Sie es selbst sehen können, sie führen nicht das gleiche.

Die beiden Optionen haben unterschiedliche Zwecke. Verwenden Sie im Allgemeinen die Inkrementoperator. Verwenden Sie Increment, wenn Sie den Betrieb müssen atomar sein und Sie sind sicher, dass alle anderen Benutzer dieser Variablen werden ebenfalls verzahnten Operationen. (Wenn sie nicht alle zusammenarbeiten sind, dann ist es nicht wirklich helfen.)

Es ist langsamer. Doch es ist die performante allgemeine Weise, die ich kenne für das Erreichen Thread-Sicherheit auf Skalarvariablen.

Es wird immer langsamer, weil es gegen nur die Aktualisierung eines Registers einen CPU-Bus Sperre auszuführen hat. Allerdings moderner CPUs in der Nähe von Registern Leistung erzielen, so dass es unerheblich ist auch in Echtzeitverarbeitung.

Mein Perfomance-Test:

flüchtig: 65174400

lock: 62428600

verzahnt: 113248900

TimeSpan span = TimeSpan.FromSeconds(5);

object syncRoot = new object();
long test = long.MinValue;

Do(span, "volatile", () => {

    long r = Thread.VolatileRead(ref test);

    r++;

    Thread.VolatileWrite(ref test, r);
});

Do(span, "lock", () =>
{
    lock (syncRoot)
    {
        test++;
    }
});

Do(span, "interlocked", () =>
{
    Interlocked.Increment(ref test);
});
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top