Encounter order

Joe Bowbeer joe.bowbeer at gmail.com
Mon Oct 22 23:07:19 PDT 2012


Inline.

On Mon, Oct 22, 2012 at 10:24 PM, Brian Goetz <brian.goetz at oracle.com>wrote:

> I don't have any assumptions about ordering after .parallel().
>>
>> list.parallel().toArray() is analogous to a parallel-ized for-loop.
>>   (See Parallel.ForEach in C#.)
>>
>
> Certainly, list.parallel().forEach() is analogous to a parallelized
> for-loop.
>
>
>  If I wanted it to execute in order, I wouldn't parallel() it.
>>
>
> But I didn't anything about *executing* in order.  The question was, to
> what extent should order be preserved.
>
> For example, array.parallel().map().**toArray() parallelizes perfectly
> while preserving encounter order, though does not execute in order.



I didn't know that.

In PLINQ, for example, asParallel() is unordered, but asOrdered() can be
added to preserve the order.

http://msdn.microsoft.com/en-us/library/dd460677.aspx

(But I am not advocating for asOrdered.)



>  Or, if I wanted to "preserve" the order, I would zip-with-index before
>> parallel execution.
>>
>
> Does that mean you assume that reducing functions passed to reduce are
> necessarily commutative?
>
> What about
>
>   array.parallel().sorted().**toArray()
>
> ?  Would you expect the result to appear in the array in sorted order?
>


After .parallel(), I would make no assumptions about order, but after
.sorted(), I would expect the order to be sorted.

I'm curious to know what other people think.



>
>
>> --Joe
>>
>> On Mon, Oct 22, 2012 at 9:05 PM, Brian Goetz <brian.goetz at oracle.com
>> <mailto:brian.goetz at oracle.com**>> wrote:
>>
>>     For parallel calculations, there are several different things we
>>     might mean by order.  In the context of bulk operations, I'll (try
>>     to) use these terms:
>>
>>       - Encounter order.  A source is said to have an encounter order
>>     when the order in which elements are yielded by iterator / forEach
>>     is predictable and meaningful.  (This is a generalization of spatial
>>     order, since some sources may be purely generative rather than
>>     representing data structures.)
>>
>>     Sources such as arrays, lists, queues, sorted collections, and IO
>>     channels have an encounter order; sources like HashSets or the key
>>     set of a HashMap do not (though their implementation may have a
>>     predictable iteration order anyway.)
>>
>>       - Arrival order.  Arrival order (aka temporal order) is the time
>>     order in which elements may arrive at a stage of an operation
>>     pipeline.  In sequential calculations, the encounter order is
>>     generally the arrival order, but in parallel calculations may not
>>     be.  Sometimes this is good, sometimes not.
>>
>>     It is easy to track (via the stream flags mechanism) whether a
>>     stream source has (or more precisely, supports) an encounter order,
>>     and similarly easy to track whether an operation preserves that
>>     order.  We also don't start any processing until we've seen the
>>     whole pipeline.
>>
>>     Some operations have intrinsic semantic constraints that require us
>>     to produce a result that is consistent with processing the elements
>>     in encounter order.  For example, a fold/reduce operation across a
>>     list using an associative but not commutative operation.  (Though
>>     this can still be parallelized efficiently.)  Others should probably
>>     be constrained to preserve order just because this is consistent
>>     with user expectations (e.g., applying the map function x -> x*2 to
>>     [ 1, 2, 3 ] should probably yield [ 2, 4, 6 ], not [ 4, 6, 2 ].)
>>     Other operations, such as forEach, may have neither constraint.
>>
>>     Like any other constraint, requiring processing to be done
>>     consistently with encounter order has a cost.
>>
>>     Finally, some operations have targets (like into or toArray), which
>>     might themselves support or not support an encounter order.
>>
>>     What I am trying to accomplish here is to identify reasonable user
>>     expectations about order preservation for the (source, operation,
>>     target) combinations we have, and whether we want to / need to add
>>     additional operations to give users more control over ordering.
>>
>>     Here are some starter questions.  Let "list" contain the numbers
>>     1..10.  What should the following expressions compute?
>>
>>        list.parallel().toArray()
>>
>>        list.parallel().filter(e -> e > 5).toArray();
>>
>>        list.parallel().into(new ArrayList<>());
>>
>>        List target = new ArrayList();
>>        list.parallel().forEach(e -> target.add(e));
>>
>>     I think the first one "obviously" should result in an array [ 1..10
>>     ].  And the last should "obviously" not be constrained at all as to
>>     order, only that it print the numbers 1 through 10 in some order.
>>     The third one, though, isn't completely obvious what the right
>>     answer is.
>>
>>     What about this:
>>
>>        Map m = list.parallel().groupBy(e -> e % 2 == 0);
>>
>>     This partitions the list into two parts; should the elements in each
>>     part be in the encounter order from the original list?  (In other
>>     words, should this result in { 0 -> [ 2, 4, 6, 8, 10 ], 1 -> [ 1, 3,
>>     5, 7, 9 ] } ?)
>>
>>     The model I'm targeting is: IF the source has an encounter order AND
>>     the operation must preserve encounter order, then we need to be
>>     sensitive to encounter order, otherwise anything goes.  Is this the
>>     right model?  If so, what are the preservation settings for each
>>     operation?
>>
>>     (A secondary consideration is that there are often situations where
>>     the computation structurally suggests an encounter order, but the
>>     user doesn't actually care, and then is paying for ordering he
>>     doesn't want.  But there are fixes for this.)
>>
>>     Lots of more detailed questions but I'll let people respond to these.
>>
>>
>>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://mail.openjdk.java.net/pipermail/lambda-libs-spec-experts/attachments/20121022/ba320850/attachment.html 


More information about the lambda-libs-spec-experts mailing list