cameron <cdor...@gmail.com> writes:

> There does seem to be something unusual about conj and
> clojure.lang.PersistentList in this parallel test case and I don't
> think it's related to the JVMs memory allocation.

I’ve got a few more data-points, but still no handle on what exactly is
going on.

My last benchmark showing the `conj*` speedup for `Cons` objects
degrading as soon as it was used on a `PersistantList` was incomplete.
In fact, the speedup degrades after it is used on objects of more than
one type.  The effect just appears immediately when used with
`PersistantList` because '() is in fact a different a
`PersistantList$EmptyList`.  Using `conj*` first in vector
implementation then results in the same inverse speedup on `Cons`s.

Even without your near-optimal speedup using Java standard library
types, I think your earlier benchmarks are enough to demonstrate that
this isn’t an issue with allocation alone.  All of the implementations
based on `reduce` with `conj` must allocate and return a new object for
each iteration.  If parallel allocation were the sole issue, I’d expect
all of the implementations to demonstrate the same behavior.

Unfortunately I have no idea what to connect from these facts:

  - Parallel allocation of `Cons` and `PersistentList` instances through
    a Clojure `conj` function remains fast as long as the function only
    ever returns objects of a single concrete type

  - Parallel allocation speed for `PersistentVector` instances is
    unaffected by `conj` returning multiple types, and does not
    demonstrate the inverse speedup seen for the previous types.

At this point I believe the symptoms point to cache contention, but I
don’t know where or why.  Using OpenJDK 7 with -XX:+UseCondMark didn’t
appear to produce any improvement.  Creating a private copy of
`PersistentList` which contained additional padding fields likewise
didn’t appear to produce any improvement.

So, Lee Spector: I think it’s possible to work around this though by
just not using `conj` on lists.  It’s suboptimal, but at least solves
the problem in your original benchmark.  Further improvements are
obviously possible, but that’s a start.

-Marshall

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en

Reply via email to