long volatile* nach void* casten?



  • FrEEzE2046 schrieb:

    Ich greife lesend von mehreren Threads auf eine Variable zu. Ich denke schon volatile zu brauchen.

    Falsch. Dafür sind "Atomics" bzw "Locks" da. Das hat mit dem volatile aus C und C++ wenig zu tun.

    http://ddj.com/high-performance-computing/212701484
    http://www.kernel.org/doc/Documentation/volatile-considered-harmful.txt

    kk



  • Du musst aber Schreiben und Lesen locken. Ansonsten ist der Wert beim Lesen möglicherweise undefiniert.

    Um das möglichst "verlustarm" zu gestalten gibt es read/write locks.



  • krümelkacker schrieb:

    Falsch.

    Nein 😉
    Es ist vom Programmablauf her nicht möglich, dass an den Stellen wo ich lese auch gleichzeitig geschrieben wird. Daher muss ich nur dafür sorgen, dass der Prozessor keine "falsche Sicht" auf den Inhalt der Variablen hat.



  • Und wie kommst du zu der Annahme, dass volatile z.B. Cache-Effekten o.ä. entgegenwirkt? Es ist lediglich eine Anweisung an den Compiler, dass er Zugriffe auf die Variable nicht optimieren soll. Mit Threads oder CPUs oder Caches hat das aber sehr wenig zu tun.

    http://en.wikipedia.org/wiki/Volatile_variable schrieb:

    The volatile keyword is basically worthless as a portable threading construct.

    Edit: verwechselst du das eventuell mit Java? Dort hat volatile den von dir gewünschten Effekt.



  • im neuen standars ist volatile mit einer ähnlichen bedeutung wie in java vorgesehen. (EDIT: oops, anscheinend doch nicht 😞 /EDIT)
    davon abgesehen: wenn *nur* gelesen wird braucht man volatile vermutlich wirklich nicht, sondern nur eine (explizite oder implizite) barrier die nach der letzten veränderung kommt aber natürlich noch vor dem ersten lesen.

    eine solche barrier ergibt sich normalerweise automatisch, wenn man ohne selbstgebastelte konstrukte sicherstellt, dass der programmablauf so synchronisiert ist, dass beim lesen kein anderer schreiben kann. irgendwo wartet man auf irgendwas, und im warten ist die barrier drin 🙂



  • Tut mir leid, wenn ich das falsch verstehe, aber ich möchte folgenden Effekt erzielen:

    variable == 4711;
    do {
    	DoAwesomeStuffWithVariable();   // MT
    }
    while( variable == 4711 );
    
    mov eax, OFFSET variable
    mov [eax], 4711
    
    @loop:
    ;
    ; call StartThread etc.
    ;
    mov eax, OFFSET variable
    mov eax, [eax]
    cmp eax, 4711
    je  @loop
    

    Zeile 8-9 sind entscheidend. Ich möchte nicht, dass der Compiler denkt den Wert von variable sowieso im Register zu haben.



  • hustbaer schrieb:

    im neuen standars ist volatile mit einer ähnlichen bedeutung wie in java vorgesehen.

    Das halte ich für eine sehr kühne Behauptung. Kannst Du das belegen? Wozu soll denn dann bitte Kapitel 29 ("Atomic operations library") des FCDs sein? Siehe auch Herb Sutter's Artikel mit dem Titel "volatile vs volatile".

    kk



  • @FrEEzE2046:
    Woher weiss denn DoAwesomeStuffWithVariable(); dass die Threads alle fertig sind?



  • krümelkacker schrieb:

    hustbaer schrieb:

    im neuen standars ist volatile mit einer ähnlichen bedeutung wie in java vorgesehen.

    Das halte ich für eine sehr kühne Behauptung. Kannst Du das belegen? Wozu soll denn dann bitte Kapitel 29 ("Atomic operations library") des FCDs sein? Siehe auch Herb Sutter's Artikel mit dem Titel "volatile vs volatile".

    kk

    Hm.
    Dann hab' ich irgendwo wohl Mist aufgeschnappt.

    Ich kann nur hoffen dass die Jungs noch ihre Meinung ändern, denn alles andere wäre IMO total doof.



  • FrEEzE2046 schrieb:

    krümelkacker schrieb:

    Das sollte eine Daumenregel sein: "Wenn Du glaubst, volatile benutzen zu müssen, liegst Du wahrscheinlich falsch."

    Ich greife lesend von mehreren Threads auf eine Variable zu. Ich denke schon volatile zu brauchen.

    Das ist leider ein Irrglaube, der sich hartnäckig hält. Insbesondere von Leuten, die IO-Ports programmiert haben.

    Volatile darf man nicht verwechseln mit einem Cache-Write-Back. Teilweise nimmt man für solche Zwecke auch "MemoryFences" oder "MemoryBarriers".

    http://msdn.microsoft.com/en-us/library/ms684208%28VS.85%29.aspx

    Insbesondere auf nicht cache-cohärenten Systemen muss man dafür Sorge tragen.

    Ansonsten gibts ja noch conditions und signals, die man für sowas verwendet anstatt n volatile.



  • @nurf:
    Ich würde auf anderem Weg argumentieren.

    Woher soll/kann er wissen dass die Threads mit ihrer Arbeit fertig sind, und der Wert der Variable sich nichtmehr ändern kann?

    Wenn er dazu Standardmechanismen wie WaitForSingleObject oder Condition-Variablen verwendet, dann beinhalten diese Mechanismen (also WaitForSingleObject bzw. die Condition-Variablen) bereits die nötigen Konstrukte (also Barriers/...).

    Wenn er sich dazu selbst was gestrickt hat sieht die Sache natürlich anders aus. Dann müsste er genau wissen was er tun muss, um die Cache-Coherency sicherzustellen. Mit einigen Compilern (wie MSVC ab Version 8 - kann sein schon ab 7.1, weiss ich nimmer) reicht hier volatile, da diese acquire/release Semantik ala Java mit volatile verknüpfen.

    Kurz: wer fragt ob er volatile braucht, sollte volatile nicht verwenden (und braucht es auch nicht), sondern lieber die Standardmechanismen zur Synchronisierung verwenden. Die dann auch sicherstellen dass man volatile eben nicht braucht, und auch keine expliziten Barriers o.ä.


Anmelden zum Antworten