Interlocked - Routinen



  • masm schrieb:

    Genau so kannst du dir das s/lfence sparen.

    Könntest du das erläutern? In einer Multi-Processor Umgebung, ist Acquire bzw. Release Semantik von nöten.



  • Welche Schreib/Lesezugriffe sollen in deinem Schnipseln unbedingt vor s/lfence ausgeführt werden?
    Die Synchronisation erfolgt doch durch das LOCK-Präfix, d.h. hier wird sichergestellt, dass die catches und der Speicher alle auf dem gleichen stand sind.(?)



  • masm schrieb:

    Die Synchronisation erfolgt doch durch das LOCK-Präfix, d.h. hier wird sichergestellt, dass die catches und der Speicher alle auf dem gleichen stand sind.(?)

    Nein!

    Intel schrieb:

    In a multiprocessor environment, the LOCK# signal ensures that the processor has exclusive use of any shared memory while the signal is asserted

    Es ist folgendermaßen: Schreib-Zugriffe auf ausgerichtete Adressen sind immer atomar. Wenn du dich darauf jedoch nicht verlassen willst und keine Instruktion verwendest die automatisch das LOCK-Signal veranlasst (wie z.B. XCHG), dann musst du das LOCK-Präfix benutzen um sicherzustellen, dass der ausführende Prozessor exklusiven Zugriff hat und die Operation somit atomar vollzogen werden kann.
    Welche Sicht ein anderer Prozessor hat und vor allem was mit vor- bzw. nachgelagerten Schreibzugriffen in einem Multi-Prozessor-System ist, steht auf einem ganz anderen Blatt (Stichwort weak-memory-ordering).

    Siehe dazu auch:
    http://msdn.microsoft.com/en-us/library/ff540496.aspx
    und
    http://stackoverflow.com/questions/4442934/acquire-release-pair-out-of-order-execution

    Meine Snippets sollen Implementationen für ein InterockedIncrement sein. Was Acquire oder Release Semantik benötigt ist vor bzw.- nachgelagert.



  • Für die Speicherstelle, auf die durch xadd zugreifst, ist sichergestellt, das während der Operation, sich der Wert nicht von 'außen', d.h. durch eine Anderen Prozessor ändert. Zugriffe mittels Lock werden, laut Intel, in absoluter Reihenfolge ausgeführt - d.h. meines Verständnis nach, das l/sfence keine Einfluss hat, da der Zugriff durch xadd sowieso später ausgeführt wird.



  • masm schrieb:

    Für die Speicherstelle, auf die durch xadd zugreifst, ist sichergestellt, das während der Operation, sich der Wert nicht von 'außen', d.h. durch eine Anderen Prozessor ändert

    Dem ist so. Aber wer garantiert dir, dass ein anderer Prozessor nicht eine andere Sicht auf die Speicherstelle hat (z.B. durch den L1 Cache)?
    Wie dem auch sei. Es gibt die FENCE Instruktionen ja nicht grundlos. Ebenso wenig wie die Interlocked-Routinen mit Acquire bzw. Release Suffix.
    Was wäre deine Meinung wo der Unterschied zwischen diesen liegt?



  • Intel schrieb:

    A locked instruction is guaranteed to lock only the area of memory defined by the destination operand, but may be interpreted by the system as a lock for a larger memory area.

    Okay, dementsprechend sind die Operationen für die Zieladresse definitiv geschützt und nach der Ausführung global sichtbar.

    Dennoch bräuchte ich die FENCE Instruktionen gerade in dem Fall, dass eine "Critical Section" betreten bzw. verlassen werden soll. Es ist entscheidend, dass ein "Lock" - Objekt erst dann signalisiert einen Bereich sicher betreten bzw. verlassen zu können, wenn alle schreib bzw. lese Operationen auf die Critical Section abgeschlossen sind.



  • Implementiert man locks nicht ab besten über cmpxchg?



  • dot schrieb:

    Implementiert man locks nicht ab besten über cmpxchg?

    Wie gesagt, ggf. ist nicht sichergestellt ob alle Read/Write Operationen auf eine geteilte Resource (ich meine NICHT 'den lock') global bekannt sind.



  • FrEEzE2046 schrieb:

    Wie gesagt, ggf. ist nicht sichergestellt ob alle Read/Write Operationen auf eine geteilte Resource (ich meine NICHT 'den lock') global bekannt sind.

    Wenn das ein Problem ist dann muss man eine solche Ressource eben durch ein lock schützen, genau dafür hat man ja locks 😕



  • komisch nur, das auf meinem System (Win7-x64, Core2Duo) InterlockedIncrementAcquire als InterlockedIncrement implementiert ist. Hierzu ein interessanter Satz:

    msdn schrieb:

    On processors that do not support acquire-semantics operations, InterlockedIncrementAcquire is identical to InterlockedIncrement. On processors such as Intel Itanium-based processors, which do support these operations, InterlockedIncrementAcquire runs faster.



  • masm schrieb:

    msdn schrieb:

    On processors that do not support acquire-semantics operations, InterlockedIncrementAcquire is identical to InterlockedIncrement. On processors such as Intel Itanium-based processors, which do support these operations, InterlockedIncrementAcquire runs faster.

    Ich kenne diesen Satz. Jedoch heißt "not supported" nicht "not needed". Ich glaube wir verstehen uns falsch: Dieser Artikel beschreibt den Nuten der Acquire bzw. Release Semantik hinsichtlich dem Memory-Ordering ziemlich gut:
    http://blogs.msdn.com/b/kangsu/archive/2007/07/16/volatile-acquire-release-memory-fences-and-vc2005.aspx



  • ok - vieleicht missversteh ich das wirklich ... aber wie ich schon sagte, erzwingen LOCKs eine 'total order' (nur für WB Speicher)


Anmelden zum Antworten