Re: C#, Threads, Events, and DataGrids/DataSets
From: Valery Pryamikov (Valery.Pryamikov_at_invalid.sm.siemens.no.nospam)
Date: 02/25/04
- Next message: Cor: "Re: DataGrid - Headertext Issue"
- Previous message: Tian Min Huang: "RE: Please Help! How I can know that file is in use"
- In reply to: Jon Skeet [C# MVP]: "Re: C#, Threads, Events, and DataGrids/DataSets"
- Next in thread: Jon Skeet [C# MVP]: "Re: C#, Threads, Events, and DataGrids/DataSets"
- Reply: Jon Skeet [C# MVP]: "Re: C#, Threads, Events, and DataGrids/DataSets"
- Messages sorted by: [ date ] [ thread ]
Date: Wed, 25 Feb 2004 10:51:32 +0100
Volatile has meanings both for compiler and runtime. Runtime meaning is
release/acquire, while as compiler's meaning "don't drop load to register
out of cycle body" menaing. Whatever optimizing compiler is, it would never
try optimization that is proven to be unacceptable by compiler optimization
theory. Non-inlined method call makes cycle body to be considered
non-trivial because it adds too many factors that prohibits making
assumption that variable isn't modified by its location in the cycle body
(including but not limited to possibility of runtime weaveing some sort of
call processing).
When I said that I can give prove for both x86 and .Net memory models I
meant I can prove it separately for each of them (+ for Itanium and Athlon
64 memory models too btw).
The only place where using instance field on the class that we are
discussing could present a problem is during first access to 'this' pointer
after constructing new class instace. But at this point instance isn't
shared and this is never a problem for single thread. At the pointg when
thread runs (Thread.Start()), there is guarantee that there were quite a few
memory barriers in the middle (when OS starts thread it will be a lot of
LOCKs and any LOCK means complete memory barrier with processor caches being
syncronized). So, all processor caches are guaranteed to be synchronized for
'this' and stopProcessing. After that "write - to - read" order doesn't
matter for that usage of stopProcessing sinced its assignment/read from
memory location will be atomic (bool is promoted to native integer and
aligned to the native integer boundary). And non-trivial cycle body assures
that JIT would never drop loading field from memory location to the register
out of the cycle body... I can even draw Petri Nets diagram with prove of
this...
-Valery.
See my blog at:
http://www.harper.no/valery
"Jon Skeet [C# MVP]" <skeet@pobox.com> wrote in message
news:MPG.1aa6778dcc171df98a22c@msnews.microsoft.com...
> Valery Pryamikov <Valery.Pryamikov@invalid.sm.siemens.no.nospam> wrote:
> > Jon, for God sake, go read some docs and try to reflect it!
>
> Um, I *have* read the specification. I have seen no guarantee of the
> type you're implying exists.
>
> > JIT compiler just compiles IL to x86 (or whatever platform it is
developed
> > for).
>
> Yup.
>
> > Some optimizing compilers could optimize away loading variable into
register
> > for cycles with trivial cycle body as optimization technique, but no
> > compiler will do it for non-trivial cycle body (there are books on
compiler
> > optimization theory if you are interesting).
>
> They could, however. That's the point - they could, and on some
> architectures they may do. Yes, it won't be a problem on x86, but I
> don't believe the spec guarantees it won't be *in general*.
>
> > Volatile has several meanings
> > (overloaded semantic) and one of these meanings is to signal optimizing
> > compiler that it can't use that particular type of optimization.
>
> No, it's more than that. Volatile in the .NET CLI has a very clear
> meaning, to do with memory barriers. A volatile read/write affects more
> than just the variable being read/written - it affects the whole
> "stream" of memory accesses.
>
> > However any
> > non-inlined method call is one of the criteria that rules off that
> > optimization too (non-trivial cycle body) and delegate call is never
inlined
> > (not speaking about other things).
>
> I don't see where inlining is actually relevant here.
>
> > Other meaning of volatile is defined by .Net spec where it adds
> > release/acquire semantic for variable reads/writes.
>
> That's the meaning I'm talking about, seeing as I'm talking about the
> specification.
>
> > This is important only
> > for non-trivial memory objects with non atomic assignment and
consistency
> > requirements. For example if we speak of some class that has some
instance
> > fields, then volatile could be important to guarantee that all memory
writes
> > from class constructor will be completed before memory read on 'this'.
But
> > with usage pattern that we discuss here it could never make that
problem. I
> > can even give you exact prove of this fact based both on x86 and .Net
memory
> > models (but I rather would not do it for not wasting time of the
newsgroup
> > readers on something they probably isn't interesting to read anyhow).
>
> Any proof *cannot* be based on the x86 memory model, as the .NET memory
> model doesn't refer to the x86 memory model at all, and is indeed much
> weaker than it.
>
> > As I already said - regardless of processor architecture and memory
model,
> > it is always guaranteed that memory write from one thread will be seen
by
> > all other threads. This is a general rule of computing. period.
>
> Not really. The general rule (to my mind) is that there is some way of
> enforcing visibility, but that's not necessary what happens
> immediately.
>
> > Order isn't guaranteed, but visibility is!
>
> Nope. It really isn't - not without memory barriers. If you're saying
> that there isn't a single memory model which pretty much explicitly
> states that the code posted might not work, I refer you to the Java
> memory model. Choice quotes are:
>
> <quote>
> Best practice is that if a variable is ever to be assigned by one
> thread and used or assigned by another, then all accesses to that
> variable should be enclosed in synchronized methods or synchronized
> statements.
> </quote>
>
> <quote>
> Each thread has a working memory, in which it may keep copies of the
> values of variables from the main memory that is shared between all
> threads. To access a shared variable, a thread usually first obtains a
> lock and flushes its working memory. This guarantees that shared values
> will thereafter be loaded from the shared main memory to the threads
> working memory. When a thread unlocks a lock it guarantees the values
> it holds in its working memory will be written back to the main memory.
> </quote>
>
> Now, as I said before, the Java memory model isn't quite the same as
> the CLI memory model, but both are relatively weak in terms of the
> guarantees they give.
>
> Here's another quote, this time from .NET - the Thread.MemoryBarrier
> method documentation:
>
> <quote>
> Synchronizes memory. In effect, flushes the contents of cache memory to
> main memory, for the processor executing the current thread.
> </quote>
>
> Now, that suggests that there is the idea of a "cache" and "main
> memory" and that they won't necessarily be in sync. Some kind of
> flushing may be required in some situations. Where is the *guarantee*
> that such a flush occurs in the posted code?
>
> > Jon, I've used several years of my life learning and programming
symmetric
> > multiprocessing and I'm not going to argue here with you about things
that
> > you apparently don't know well. You can have you last word if you want,
> > however be warned that trying to argue about something that you are not
> > really familiar could just harm your reputation as a specialist.
>
> If it really is guaranteed, why not just post the relevant parts of the
> the CLI specification? If I really am wrong, I'd *really* like to be
> proven wrong. For one thing, it would make my life easier when writing
> similar code!
>
> I'm certainly *not* an expert in the x86 memory model, or indeed any
> specific processor's memory model. I wouldn't even say I'm an *expert*
> in the CLI memory model, although I know more about that than about any
> specific processor model.
>
> I'm not trying to argue that under the current .NET implementation, the
> posted code won't always work. It may well work for all future
> implementations on every architecture, too - but I don't believe it's
> guaranteed to. All I'm after is some evidence of that guarantee, or an
> acknowledgement that it doesn't exist.
>
> --
> Jon Skeet - <skeet@pobox.com>
> http://www.pobox.com/~skeet
> If replying to the group, please do not mail me too
- Next message: Cor: "Re: DataGrid - Headertext Issue"
- Previous message: Tian Min Huang: "RE: Please Help! How I can know that file is in use"
- In reply to: Jon Skeet [C# MVP]: "Re: C#, Threads, Events, and DataGrids/DataSets"
- Next in thread: Jon Skeet [C# MVP]: "Re: C#, Threads, Events, and DataGrids/DataSets"
- Reply: Jon Skeet [C# MVP]: "Re: C#, Threads, Events, and DataGrids/DataSets"
- Messages sorted by: [ date ] [ thread ]
Relevant Pages
|