wann braucht man volatile?



  • wenn die hardware dei speicherstell verändert



  • Also ich kann dazu nur sagen: Ich hab's noch nie gebraucht und mir fällt auch spontan kein Anwendungsfall ein 🙂



  • JustAnotherNoob schrieb:

    Hi
    Ich habe dieses Schlüsselwort nun schon in C++ und C# gefunden und frage mich wozu man es eigentlich braucht?
    Also ich habe mir schon durchgelesen was es denn bewirkt, aber wann braucht man sowas?

    Interruptprogrammierung (keine dämliche Antwort!!) 😉





  • Fürs Multithreading braucht man es unter C++ nicht.



  • Badestrand schrieb:

    Also ich kann dazu nur sagen: Ich hab's noch nie gebraucht und mir fällt auch spontan kein Anwendungsfall ein 🙂

    dann hast du wohl noch nie hardware nah programmiert



  • Multithreading. Damit sagt man dem Compiler, dass er für diese Variable keine
    Code-Optimierung vornehmen darf.
    Anwendungsbeispiel aus dem Lehrbuch:
    Stell dir eine for-Schleife vor mit einer globalen Zählvariable i.
    Jetzt sollen 2 Threads diese Schleife von i=0 bis i=1000 gemeinsam abarbeiten.
    Also z.B. Thread 1 macht 100 Durchläufe (von i=0 bis i=99) und danach Thread 2 die nächsten 100 (von i=100 bis i=199) usw.
    Wenn man die globale variable nicht als volatile deklariert, könnte der Compiler den Code so optimieren, dass die variable i in einem Prozessorregister ablegt wird. Dies könnte dann so aussehen: Wenn Thread 1 mit der Abarbeitung der Schleife startet wird die Variable nicht jedesmal vom Arbeitsspeicher in ein Register geladen, inkrementiert und wieder zurück in den ASP geschrieben sondern verbleibt in einem Register bis der Thread mit den kompletten Schleife fertig ist. Das gleiche macht Thread 2 wenn er in die Schleife eintritt. Somit arbeiten beide Threads die Schleife von i=0 bis i=1000 ab. Was wir ja eigentlich nicht wollten.
    Kennzeichnet man die Variable i als volatile, wird bei der Code-Optimierung die Variable i nicht angerührt. Unser Programm funktioniert so wie wir das wollten.

    Allerdings muss ich auch sagen, dass ich das Schlüsselword volatile auch noch nie gebraucht habe.

    Gruß Tom



  • Einzigste Anwendung auch bei mir wegen Interrupts bei Microcontrollerprogrammierung.



  • Hi,

    soweit ich mich erinnere dient es auch noch dazu, bei komplett konstanten Klassen einzelne Elemente als nicht konstant zu markieren. Hatte sowas mal bei Scott Myers gelesen.

    Gruß Mümmel



  • TomTom85 schrieb:

    Multithreading.

    Nein, siehe zB den Link den ich gepostet habe.

    muemmel schrieb:

    soweit ich mich erinnere dient es auch noch dazu, bei komplett konstanten Klassen einzelne Elemente als nicht konstant zu markieren. Hatte sowas mal bei Scott Myers gelesen.

    Ganz anderes Schlüsselwort :p. Was du meinst nennt sich mutable .



  • @ rüdiger
    http://www.imb-jena.de/~gmueller/kurse/c_c++/c_volat.html
    man beachte den 1. Absatz und dann lese man meinen Beitrag. Dann wirst du feststellen, dass das für Multithreading schon von Bedeutung ist.

    Gruß Tom



  • Hier nochmal der relevante Absatz für alle:
    Das Schlüsselwort volatile teilt dem Compiler mit, daß die mit name bezeichnete Variable mit dem Datentyp typ durch Ereignisse außerhalb der Kontrolle des Programms verändert werden kann.
    Der Wert der Variablen muß deshalb vor jedem Zugriff neu aus dem Hauptspeicher eingelesen werden, d.h. er darf nicht in einem Register des Prozessors zwischengespeichert werden.



  • Um auch mal ein konkretes Anwendungsbeispiel zu nennen:
    Ich erinnere mich, dass ich bei der Soundausgabe (Wave) unter Windows bei waveOutWrite und waveOutProc Probleme bekam, wenn nicht gewisse Variblen volatile waren. (Interrupt wird ausgelöst, wenn sich der Soundbuffer dem Abspielende neigt, und neu beschrieben werden soll.)



  • TomTom85 schrieb:

    Multithreading. Damit sagt man dem Compiler, dass er für diese Variable keine
    Code-Optimierung vornehmen darf.
    Anwendungsbeispiel aus dem Lehrbuch:
    Stell dir eine for-Schleife vor mit einer globalen Zählvariable i.
    Jetzt sollen 2 Threads diese Schleife von i=0 bis i=1000 gemeinsam abarbeiten.
    Also z.B. Thread 1 macht 100 Durchläufe (von i=0 bis i=99) und danach Thread 2 die nächsten 100 (von i=100 bis i=199) usw.
    Wenn man die globale variable nicht als volatile deklariert, könnte der Compiler den Code so optimieren, dass die variable i in einem Prozessorregister ablegt wird. Dies könnte dann so aussehen: Wenn Thread 1 mit der Abarbeitung der Schleife startet wird die Variable nicht jedesmal vom Arbeitsspeicher in ein Register geladen, inkrementiert und wieder zurück in den ASP geschrieben sondern verbleibt in einem Register bis der Thread mit den kompletten Schleife fertig ist. Das gleiche macht Thread 2 wenn er in die Schleife eintritt. Somit arbeiten beide Threads die Schleife von i=0 bis i=1000 ab. Was wir ja eigentlich nicht wollten.
    Kennzeichnet man die Variable i als volatile, wird bei der Code-Optimierung die Variable i nicht angerührt. Unser Programm funktioniert so wie wir das wollten.
    Gruß Tom

    Nein, das ist nicht der Fall. Denn volatile stellt nicht sicher, dass die Veränderungen der Variable auch von allen Prozessoren gesehen wird. Das ist unabhängig von Optimierungen des Kompilers. Um es richtig zu machen, braucht man Dinge wie Memory-Barriers. Und bevor man damit anfängt, nimmt man lieber das richtige Synchronisationskonstrukt. Ebenso verhindert volatile keine unerwünschten Instruktionreorderings.



  • TomTom85 schrieb:

    Hier nochmal der relevante Absatz für alle:
    Das Schlüsselwort volatile teilt dem Compiler mit, daß die mit name bezeichnete Variable mit dem Datentyp typ durch Ereignisse außerhalb der Kontrolle des Programms verändert werden kann.
    Der Wert der Variablen muß deshalb vor jedem Zugriff neu aus dem Hauptspeicher eingelesen werden, d.h. er darf nicht in einem Register des Prozessors zwischengespeichert werden.

    Aber das hat nichts mit Multithreading zu tun. Siehe Pontos Beitrag oder lies einfach mal den Link, den ich gepostet habe!



  • Dass volatile primär nicht für Multithreading gemacht wurde ist schon klar. Aber es kann in solchen Fällen schon Anwendung finden.



  • TomTom85 schrieb:

    Dass volatile primär nicht für Multithreading gemacht wurde ist schon klar. Aber es kann in solchen Fällen schon Anwendung finden.

    Das Problem ist aber, dass volatile für die Synchronisation nicht ausreicht. Andersherum kann man aber ohne volatile synchronisieren. Deshalb ist es sinnlos diese Performanzbremse zu verwenden.



  • TomTom85 schrieb:

    Dass volatile primär nicht für Multithreading gemacht wurde ist schon klar. Aber es kann in solchen Fällen schon Anwendung finden.

    Nein!
    Aus dem Link den ich gepostet habe

    Using volatile does not mean that the variable is accessed atomically; no locks are used. Using volatile does not mean that other cores in a multi-core system will see the memory accesses; no cache flushes are used. While volatile writes are guaranteed to occur in the program order for the core which is executing them, there is no guarantee that any other core will see the writes in the same order. Using volatile does not imply any sort of memory barrier; the processor can and will rearrange volatile memory accesses (this will not happen for address ranges used for memory mapped hardware, but it will for ordinary memory).

    http://www.airs.com/blog/archives/154


Anmelden zum Antworten