Re: JavaMemoryModel: Idiom for safe, unsynchronized reads

From: Raymie Stata (stata@pa.dec.com)
Date: Mon Jun 28 1999 - 12:04:58 EDT


In keeping with the structure of my original message, I'd like to follow up
from two perspectives: the programmer's and the implementor's. In the
interest of brevity, I have paraphrased previous postings; please excuse
any inaccuracies.

**** Programmer's perspective

>> Raymie originally wrote that at SRC it's common knowledge that
>> the idiom of publishing
>> a read-only object and allowing synch-free reads does not
>> generally work. Armed with this information, it's not hard to
>> find alternative solutions.

> Josh Bloch wrote back that he "strongly disagreed" with me. He
> said that while the problem with synch-free reads may be well
> known among the "hacker studs" at SRC, it's not well known outside
> of SRC. He points out that people on comp.threads, people who
> wrote the JDK, and people who wrote Encina all make use of this
> idiom. If they don't know about the problems with this idiom,
> then the "unwashed masses" have no hope.

I agree that not many people understand the problem with the idiom under
discussion. The problem is, as Josh points out elsewhere in his posting,
that not many people write multithreaded code for multiprocessors. Most
write for single processors. The bulk of the Encina code base was written
before production, multiprocessor servers were a serious consideration; I
suspect MP wasn't given much consideration when the JDK was written either.

In the late 80's, SRC built multiprocessor workstations and put them on
most people's desktops; in the 90's, SRC did lots of MP work with the
Digital Alpha. Although I wasn't here for much of that work, it has been
really easy to pick up the main lesson learned: multi-threaded programming
on MP systems is _very_ difficult. It's not something with which one wants
to be clever; in particular, leaving out synchronization is not something
with which one wants to play. To use Josh's terminology: If even the
"hacker studs" at SRC couldn't get non-synchronized MP idioms to work
(believe me, they tried), what chance do the "unwashed masses of
programmers" have?

I think we're doing programmers a great disservice by providing a tight
threading spec that tempts people to write code outside of the simple
synchronized-block idiom. It is much easier to understand the injunction
"do not access shared variables outside synchronization blocks" than it is
to understand a menu of idioms that allow unsynchronized access. Those
idioms increase the chances of introducing race errors -- which are very
difficult to debug -- and they don't offer that much of a performance
improvement over other optimizing transformations (such as reducing the
number of shared objects).

Josh quoted Gosling in describing Java as "a working man's language." I
very much agree with this sentiment, which is why I don't think we should
be trying to support fancy idioms in Java's semantics. For the sake of the
"working programmer", the simple injunction "do not access shared variables
outside synchronization blocks" is the direction in which we should be
pushing.

**** Implementor's perspective

>> Raymie wrote that implementing a semantics that would support the
>> idiom in question would be expensive on some platforms because it
>> would require a memory barrier on the reader's side as well as the
>> writer's side.

> Bill Pugh pointed out that such a re-ordering would not be a
> problem on SPARC, even under RMO. However, he conceded that if
> it was a problem for other architectures, then he would revisit
> his commitment to this idiom. Josh held a stronger position.
> He said that such re-orderings are a non-issue: most people run
> on single processors and that SPARC is _not_ run in RMO mode. He
> pointed to a paper that questioned the performance benefit of
> value of agressively reordering memory operations. Although Josh
> acknowledged that Alpha _does_ this kind of agressive reordering,
> he didn't seem to think this was a problem.

In response to Bill's posting I can say that the Alpha _does_ do the kind
of "aggressive" reordering that would make this idiom difficult to
implement. (Although I'm not a SPARC expert, a friend says the only thing
that saves SPARC/RMO is that they have special rules regarding the ordering
of dependent loads, rules the Alpha does not have.)

In response to Josh's posting, as a Compaq (formally Digital) employee who
really likes the Alpha architecture, I'm a little concerned about the
cavalier dismissal of the implementation issues we would face.
Fortunately for Alpha fans, there's another architecture with much more
marketing clout that may be in the same position as us: Intel's IA-64.
Although it's a little to early to tell, my reading of the _Application
Developer's Architecture Guide_ suggests that they too will be doing
"aggressive" reordering of memory operations (see section 4.4.7 starting pg
4-23).

(By the way, I think it's interesting that Bill and Josh think of
Alpha-like memory models as aggressively _re_-ordering memory operations.
I think of MP memory operations to different memory locations by different
processors as being _unordered_ unless there is a specific rule in the
architecture establishing an order. Thus, to me, it's not that Alpha
"aggressively reorders" memory operations, but rather that SPARC/TSO and
even SPARC/RMO "aggressively order" memory operations.)

**** Conclusion

I still think that the Java community should drop idioms that involve
unsynchronized reads to objects that are not accessed through static, final
fields. I say this because it's better for both programmers and
implementors.

>From the programmer's perspective, multithreaded programming is much easier
if one isn't tempted into optimizations that can introduce races. The best
we could do for programmers is insist on the injunction "do not access
shared variables without synchronization."

>From the implementor's perspective, for those of us who need to implement
Java on architectures like Alpha and IA-64 that "aggressively reorder"
memory operations, we would be much happier with a looser semantics that
didn't assume much ordering of memory operations in the absence of
synchronizing operations. (BTW, "synchronizing operations" needs to be
expanded beyond "lock" and "unlock" to include things like thread creation
and class loading. But this is a story for another post...)

Regards,
  Raymie
-------------------------------
This is the JavaMemoryModel mailing list, managed by Majordomo 1.94.4.

To send a message to the list, email JavaMemoryModel@cs.umd.edu
To send a request to the list, email majordomo@cs.umd.edu and put
your request in the body of the message (use the request "help" for help).
For more information, visit http://www.cs.umd.edu/~pugh/java/memoryModel



This archive was generated by hypermail 2b29 : Thu Oct 13 2005 - 07:00:13 EDT