By: Tzvetan Mikov (tzvetanmi.delete@this.yahoo.com), October 23, 2006 11:38 pm
Room: Moderated Discussions
S. Rao (sonny@burdell.org) on 10/23/06 wrote:
---------------------------
>I guess I'm somewhat confused, are you sure that this
>barrier is always added in current implementations
>or is it a conjecture that it is always added because
>there isn't a better way to guarantee consistency?
>
>All I'm saying is that the implementation might have
>enough info to be smart about when it's added or not,
>I'm not sure what has been implemented in reality,
>but I'd be surprised if this wasn't optimized somehow.
>
I am sorry - I am terrible at explaining what I have in mind . In practice all implementation will have to add the barrier in most cases, because most object escape. So, if we assume that a barrier is slow, all allocation will have to be slow in a multi-threaded environment. This is in contrast with single-threaded environment where an allocation can be made to be fast.
I am reacting to the realization that in a multi-threaded environment all safe languages will have to suffer the penalty of an obilgatory memory barrier after every allocation.
On the other hand after reading Linus'es post, it seems that the write barrier is not that terribly expensive, so may be there isn't a big problem after all.
>Thinking about it more, since Java constructors are all
>chained, we would end up with several barriers for
>every object creation... this seems like it would be
>incredibly slow -- contradicting your assertion below that
>object creation must be as fast as a stack alloc.
No - you don't need more than one barrier. The problem is only with the object's metadata because it can violate the language's safety invariants. The metadata is written only once.
>
>>>If it's locally scoped and the creating thread interacts
>>>with the object before its reference escapes, then the
>>>barrier isn't needed at all (mostly).
>>
>>I don't really see how. Having the local thread interact with an object does nothing
>>for the visibility of this object from other threads. When does a write become globally
>>visible - after a 100 instructions ? We still end up needing a memory barrier in
>>all cases when the compiler cannot prove that an object is used only locally (which is practically all cases).
>
>Well, having the local thread interact with the object
>means that proper ordering is forced, since that thread's
>code must see everything in a consistent state.
>
>The creating thread's loads will always get the correct
>data without an explicit barrier (maybe not on Alpha ?,
>but everywhere else). If that happens before the creating
>thread allows the reference to escape, I think we're okay
>to proceed without adding an explicit barrier.
No, I think you there us some confusion here. The local thread always sees the memory in a consistent state (it wouldn't be possible to write software otherwise) - the memory consistency model is only relevant to other threads.
>>Again, I disagree. Object creation is supposed to be an extremely cheap operation,
>>ideally comparable in cost to literally pushing the object onto the stack. In a
>>single threaded environment with a compacting GC this is an attainable goal.
>
>I've never heard this before.. I've always thought
>object allocation was an expensive proposition, how
>could it possibly be as cheap as a simple stack allocation,
>and why would Java have primitive types if that were true
>(maybe a big can of worms here :-))?
It is true. For example, in a functional language like ML allocation is supposed to be very cheap.
Java's primitive types solve a different problem. Even if allocation was entirely free, accessing a variable indirectly through a pointer has at least a 10-fold penalty.
---------------------------
>I guess I'm somewhat confused, are you sure that this
>barrier is always added in current implementations
>or is it a conjecture that it is always added because
>there isn't a better way to guarantee consistency?
>
>All I'm saying is that the implementation might have
>enough info to be smart about when it's added or not,
>I'm not sure what has been implemented in reality,
>but I'd be surprised if this wasn't optimized somehow.
>
I am sorry - I am terrible at explaining what I have in mind . In practice all implementation will have to add the barrier in most cases, because most object escape. So, if we assume that a barrier is slow, all allocation will have to be slow in a multi-threaded environment. This is in contrast with single-threaded environment where an allocation can be made to be fast.
I am reacting to the realization that in a multi-threaded environment all safe languages will have to suffer the penalty of an obilgatory memory barrier after every allocation.
On the other hand after reading Linus'es post, it seems that the write barrier is not that terribly expensive, so may be there isn't a big problem after all.
>Thinking about it more, since Java constructors are all
>chained, we would end up with several barriers for
>every object creation... this seems like it would be
>incredibly slow -- contradicting your assertion below that
>object creation must be as fast as a stack alloc.
No - you don't need more than one barrier. The problem is only with the object's metadata because it can violate the language's safety invariants. The metadata is written only once.
>
>>>If it's locally scoped and the creating thread interacts
>>>with the object before its reference escapes, then the
>>>barrier isn't needed at all (mostly).
>>
>>I don't really see how. Having the local thread interact with an object does nothing
>>for the visibility of this object from other threads. When does a write become globally
>>visible - after a 100 instructions ? We still end up needing a memory barrier in
>>all cases when the compiler cannot prove that an object is used only locally (which is practically all cases).
>
>Well, having the local thread interact with the object
>means that proper ordering is forced, since that thread's
>code must see everything in a consistent state.
>
>The creating thread's loads will always get the correct
>data without an explicit barrier (maybe not on Alpha ?,
>but everywhere else). If that happens before the creating
>thread allows the reference to escape, I think we're okay
>to proceed without adding an explicit barrier.
No, I think you there us some confusion here. The local thread always sees the memory in a consistent state (it wouldn't be possible to write software otherwise) - the memory consistency model is only relevant to other threads.
>>Again, I disagree. Object creation is supposed to be an extremely cheap operation,
>>ideally comparable in cost to literally pushing the object onto the stack. In a
>>single threaded environment with a compacting GC this is an attainable goal.
>
>I've never heard this before.. I've always thought
>object allocation was an expensive proposition, how
>could it possibly be as cheap as a simple stack allocation,
>and why would Java have primitive types if that were true
>(maybe a big can of worms here :-))?
It is true. For example, in a functional language like ML allocation is supposed to be very cheap.
Java's primitive types solve a different problem. Even if allocation was entirely free, accessing a variable indirectly through a pointer has at least a 10-fold penalty.