[vector] Vector API -- alignment with value types

Vladimir Ivanov vladimir.x.ivanov at oracle.com
Wed Feb 20 23:58:13 UTC 2019


> Please find below the updated webrev where the fromArray methods are moved from Species to XxxVector:
> http://cr.openjdk.java.net/~sviswanathan/vectorIntrinsics/Brian/zero/webrev.01/

Overall, looks fine.

Looking at the changes in tests/benchmarks, the new API form looks more 
verbose:

http://cr.openjdk.java.net/~sviswanathan/vectorIntrinsics/Brian/zero/webrev.01/test/jdk/jdk/incubator/vector/benchmark/src/main/java/benchmark/jdk/incubator/vector/PopulationCount.java.udiff.html

-        var acc = L128.zero(); // IntVector
+        var acc = LongVector.zero(L128); // IntVector

-            var bacc = B128.zero();
+            var bacc = ByteVector.zero(B128);

-                var v1 = L128.fromArray(data, i + j);
+                var v1 = LongVector.fromArray(L128, data, i + j);

The latter doesn't benefit from type information available for Species 
and requires XxxVector to avoid redundant casts.

But I agree that while moving from one high-energy state to another, you 
can't avoid leaving the local maximum.

> The tests and benchmark directories are also updated accordingly. All the tests continue to pass with this webrev.
> 
> In this webrev, I have also made the change suggested by Vladimir regarding XxxVector.zero() method.
> 
> Your review and feedback is welcome.
> 
> After this the following public methods remain on Species and $Type$Species:
>       public abstract Class<E> elementType();
>       public abstract int elementSize();
>       public abstract Shape shape();
>       public int length();
>       public int bitSize();

I believe the following methods can be moved away (or hidden) from 
Species in the same vein:

>       public static <E> Vector.Species<E> of(Class<E> c, Shape s);
>       public static <E> Vector.Species<E> ofPreferred(Class<E> c);

Statics on Vector/XxxVector?

>       public abstract Vector<E> zero();

Package-private (for implementation purposes)?

>       public abstract <F> Mask<E> cast(Mask<F> m);
>       public abstract <F> Shuffle<E> cast(Shuffle<F> s);

Move to Mask/Shuffle?

>       public abstract $abstractvectortype$ broadcast($type$ e);
>       public final $abstractvectortype$ single($type$ e);
>       public $abstractvectortype$ random();
>       public abstract $abstractvectortype$ scalars($type$... es);

> The last four could be a candidate to move to XxxVector. Please let me know your thoughts.

Yes, agree.

Best regards,
Vladimir Ivanov

> -----Original Message-----
> From: Vladimir Ivanov [mailto:vladimir.x.ivanov at oracle.com]
> Sent: Tuesday, February 12, 2019 10:23 AM
> To: Brian Goetz <brian.goetz at oracle.com>
> Cc: Viswanathan, Sandhya <sandhya.viswanathan at intel.com>; panama-dev at openjdk.java.net; John Rose <john.r.rose at oracle.com>
> Subject: Re: [vector] Vector API -- alignment with value types
> 
> 
>> Sure, for now.  When vectors are values, we probably won’t need such inspection?
> 
> In general, I don't think it changes much with value types: special
> support on JIT-compiler side is still needed to strength-reduce vector
> construction operation. Otherwise, a memory load (even from a flattened
> representation) is needed to materialize a value unless JIT knows what
> the value is.
> 
> But for particular case of Vector.zero() default value can be used
> (instead of caching).
> 
> Best regards,
> Vladimir Ivanov
> 
>>> On Feb 11, 2019, at 8:12 PM, Vladimir Ivanov <vladimir.x.ivanov at oracle.com> wrote:
>>>
>>>
>>>> I thought this might be the case; zeros are so common that we may well want to just instantiate a zero vector as a species field, which can be shared.  Then we just expose “species.zero()” as a method (which ByteVector.zero() can delegate to.)
>>>
>>> FTR zero() is not cached, but backed by an intrinsic, because it's easier to optimize: it doesn't require JIT-compiler to inspect the boxed value to be able to use faster idiom when constructing vector value at runtime (e.g., xor vs load).
>>>
>>> Best regards,
>>> Vladimir Ivanov
>>>
>>>> I didn’t want to do this in my first patch because I was mostly intent on providing that we will get the same inlining with a more value-friendly API, but this makes sense to me.
>>>
>>>>> On Feb 8, 2019, at 7:23 PM, Vladimir Ivanov <vladimir.x.ivanov at oracle.com> wrote:
>>>>>
>>>>>
>>>>>> http://cr.openjdk.java.net/~sviswanathan/vectorIntrinsics/Brian/zero/webrev.00/
>>>>>
>>>>> I have one comment on implementation:
>>>>>
>>>>> src/jdk.incubator.vector/share/classes/jdk/incubator/vector/ByteVector.java:
>>>>>
>>>>> +    public static ByteVector zero(ByteSpecies species) {
>>>>> +        return VectorIntrinsics.broadcastCoerced((Class<ByteVector>) species.boxType(), byte.class, species.length(),
>>>>> +                                                 0,
>>>>> +                                                 (z -> species.zero()));
>>>>> +    }
>>>>>
>>>>> There's a slight change in behavior compared to "species.zero()" call and that's because not all arguments to VectorIntrinsics.broadcastCoerced() are guaranteed to be constant.
>>>>>
>>>>> If JIT can't devirtualize & inline "species.boxType()", intrinsification fails and falls back to default implementation.
>>>>>
>>>>> In case of species.zero(), a failure to inline callee leads to a virtual call, but callee contains intrinsified operation.
>>>>>
>>>>> Overall, I believe it shouldn't matter from performance perspective right now, because a call breaks vector box elimination anyway, but in a longer term it may become important.
>>>>>
>>>>> But I'd still prefer to see calls to VectorIntrinsics be fully specialized. In the particular case I referred to, IMO it's better to just call species.zero().
>>>>>
>>>>> Best regards,
>>>>> Vladimir Ivanov
>>


More information about the panama-dev mailing list