Synchronisation question
-
I have two threads and one will indicate to the other that it should perform some operation through a boolean flag. To set this flag I know it is necessary to have mutual exclusion so I use a monitor to restrict access to the flag and then exit the monitor. Here is my question: a long time ago I remember that sometimes processors will cache their own copy of a variable and only fetch or write this value again when it is evicted from the cache (or memory or whatever) or when it knows something is volatile. My question is, do i have to indicate this boolean flag I am using in my monitor is volatile? Regards,
Did I post well? Rate it! Did I post badly? Rate that too!
-
I have two threads and one will indicate to the other that it should perform some operation through a boolean flag. To set this flag I know it is necessary to have mutual exclusion so I use a monitor to restrict access to the flag and then exit the monitor. Here is my question: a long time ago I remember that sometimes processors will cache their own copy of a variable and only fetch or write this value again when it is evicted from the cache (or memory or whatever) or when it knows something is volatile. My question is, do i have to indicate this boolean flag I am using in my monitor is volatile? Regards,
Did I post well? Rate it! Did I post badly? Rate that too!
Rather than use a boolean flag why not use a ManualResetEvent or AutoResetEvent?
only two letters away from being an asset
-
Rather than use a boolean flag why not use a ManualResetEvent or AutoResetEvent?
only two letters away from being an asset
-
I have two threads and one will indicate to the other that it should perform some operation through a boolean flag. To set this flag I know it is necessary to have mutual exclusion so I use a monitor to restrict access to the flag and then exit the monitor. Here is my question: a long time ago I remember that sometimes processors will cache their own copy of a variable and only fetch or write this value again when it is evicted from the cache (or memory or whatever) or when it knows something is volatile. My question is, do i have to indicate this boolean flag I am using in my monitor is volatile? Regards,
Did I post well? Rate it! Did I post badly? Rate that too!
Esmo2000 wrote:
do i have to indicate this boolean flag I am using in my monitor is volatile?
Yes. Declare it like
volatile bool yourFlag = false;
Other option is to work with Thread.VolatileRead[^]. In fact, in C# if you use volatile keyword, it will be usingVolatileRead
andVolatileWrite
. As Mark suggested, you can tryEventWaitHandle
as well. Make sure you understand the difference ofAutoResetEvent
andManualResetEvent
before you make a choice. :)Navaneeth How to use google | Ask smart questions
-
I have two threads and one will indicate to the other that it should perform some operation through a boolean flag. To set this flag I know it is necessary to have mutual exclusion so I use a monitor to restrict access to the flag and then exit the monitor. Here is my question: a long time ago I remember that sometimes processors will cache their own copy of a variable and only fetch or write this value again when it is evicted from the cache (or memory or whatever) or when it knows something is volatile. My question is, do i have to indicate this boolean flag I am using in my monitor is volatile? Regards,
Did I post well? Rate it! Did I post badly? Rate that too!
No offense but most of what you said is untrue on some level.. You don't need mutual exclusion for a bool x86's don't care about "volatile" and have no notion of it (MTRRs control caching, but the cache is coherent anyway), the "volatile" keyword makes sure that the value is actually fetched (that can be from the cache, but it doesn't matter, since it's coherent anyway) instead of reused if it is already in a register (and the same for writing) and guarantees that those operations won't be reordered by the compiler (the CPU can still reorder it, but only under some circumstances) It's all very complicated. Unless you want to do assembly programming it usually isn't even relevant, especially if you'd just use the existing synchronization primitives.. see below. Just making the bool volatile should usually be enough, since it's just a bool, and you may not even need that (usually works anyway, but better be safe than sorry) However, I don't have a lot of information here go to on, but usually you should use normal synchronization primitives when dealing with synchronization, instead of making one up out of a bool. Like ManualResetEvent, or one of the static functions in
Interlocked
(if you need something low-level). At least, that's what I got told :) ps: I'm sorry for any inaccuracies in this post, it is a complex subject, and I'm not even an expert on this :) -
I have two threads and one will indicate to the other that it should perform some operation through a boolean flag. To set this flag I know it is necessary to have mutual exclusion so I use a monitor to restrict access to the flag and then exit the monitor. Here is my question: a long time ago I remember that sometimes processors will cache their own copy of a variable and only fetch or write this value again when it is evicted from the cache (or memory or whatever) or when it knows something is volatile. My question is, do i have to indicate this boolean flag I am using in my monitor is volatile? Regards,
Did I post well? Rate it! Did I post badly? Rate that too!
yes, you need one of two things: - either make the flag volatile, i.e. non-cacheable, to make sure you aren't using stale data. The disadvantage is you still have to poll it, wasting a lot of CPU cycles; - or use a real synchronization primitive such as a Manual/AutoResetEvent, as Mark indicated. :)
Luc Pattyn [Forum Guidelines] [My Articles]
The quality and detail of your question reflects on the effectiveness of the help you are likely to get. Show formatted code inside PRE tags, and give clear symptoms when describing a problem.
-
yes, you need one of two things: - either make the flag volatile, i.e. non-cacheable, to make sure you aren't using stale data. The disadvantage is you still have to poll it, wasting a lot of CPU cycles; - or use a real synchronization primitive such as a Manual/AutoResetEvent, as Mark indicated. :)
Luc Pattyn [Forum Guidelines] [My Articles]
The quality and detail of your question reflects on the effectiveness of the help you are likely to get. Show formatted code inside PRE tags, and give clear symptoms when describing a problem.
Luc Pattyn wrote:
i.e. non-cacheable
While it's not actually wrong (it can't be cached in a register anymore), it might give the impression that it has something to do with the cache.. Bit a nitpick maybe, but it would a shame if people were to assume that "volatile" makes uncachable memory ranges (which is AFAIK the only way to not cache something at all, non-temporal hints are just hints)
-
Luc Pattyn wrote:
i.e. non-cacheable
While it's not actually wrong (it can't be cached in a register anymore), it might give the impression that it has something to do with the cache.. Bit a nitpick maybe, but it would a shame if people were to assume that "volatile" makes uncachable memory ranges (which is AFAIK the only way to not cache something at all, non-temporal hints are just hints)
the exact meaning of volatile is a well-kept secret, manuals aren't clear on the subject; the best description would be: each read or write operation in code must result in an actual read or write from/to actual memory (in the same order), so all registers, and cache levels are to be ignored/disabled somehow. Another way of putting it is: the compiler should assume the current code is NOT the only one operating on the data, hence every time the data is touched, it has to be fetched/written. :)
Luc Pattyn [Forum Guidelines] [My Articles]
The quality and detail of your question reflects on the effectiveness of the help you are likely to get. Show formatted code inside PRE tags, and give clear symptoms when describing a problem.
-
the exact meaning of volatile is a well-kept secret, manuals aren't clear on the subject; the best description would be: each read or write operation in code must result in an actual read or write from/to actual memory (in the same order), so all registers, and cache levels are to be ignored/disabled somehow. Another way of putting it is: the compiler should assume the current code is NOT the only one operating on the data, hence every time the data is touched, it has to be fetched/written. :)
Luc Pattyn [Forum Guidelines] [My Articles]
The quality and detail of your question reflects on the effectiveness of the help you are likely to get. Show formatted code inside PRE tags, and give clear symptoms when describing a problem.
Luc Pattyn wrote:
Another way of putting it is: the compiler should assume the current code is NOT the only one operating on the data, hence every time the data is touched, it has to be fetched/written.
It's worth noting that, at least in C, any time the value of a variable is read the compiler is required to generate a read instruction [i]even if the value is ignored[/i]. On hardware platforms with memory-mapped I/O (very rare for the X86, but common with microcontrollers) reads certain addresses will trigger various effects. For example, on some machines reading the lower byte of a multi-byte hardware counter will latch the read registers for all bytes; even if code is only interested in the upper bytes of the counter, it may have to read the lower byte to trigger the latch. Even though such hardware is rare in the PC world, accessing a memory location while ignoring the value may have two potentially-useful effects: -1- Forcing the page containing that location to be loaded into memory. -2- Validating the address as pointing to something accessible. Most programs won't worry about #1, but in some cases it may be good to minimize the likelihood of a page fault occurring while a resource is held. Pre-accessing a memory location before acquiring the resource may be helpful; even though there'd be no guarantee the page holding the location wouldn't get swapped out before it was actually used, the likelihood of a page fault occurring before the resource was allocated would be reduced.