Vectorizing POPCNT (Long.bitCount)

Paul Sandoz paul.sandoz at oracle.com
Tue Sep 6 21:39:54 UTC 2022


AFAICT AMD 4700s only supports AVX2:

  http://valid.x86.fr/cevdtl

Where as vpopcntq requires CPUID flags AVX512VPOPCNTDQ

  https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#ig_expand=5436,5436,5427,5418,5433,5424,5436&text=vpopcntq

The code looks good, but you could also perform the reduction outside the loop e.g. before entering the loop initialize a sum vector to zero and add the bit count to that. On supporting hardware that should improve things.

Paul.

> On Sep 6, 2022, at 2:21 PM, Stefan Reich <stefan.reich.maker.of.eye at googlemail.com> wrote:
> 
> I did try vectorizing my method with JDK 19 just now... but sadly I got a ~25% speed decrease over the unvectorized version. I have an AMD 4700s.
> 
> Vectorized function:
> 
> import jdk.incubator.vector.*;
> 
> static int countDifferingBits_vectorAPI(long[] array1, long[] array2, int i1) {
>   VectorSpecies<Long> SPECIES = LongVector.SPECIES_PREFERRED;
>   
>   int diff = 0;
>   int n = array1.length;
>   var upperBound = SPECIES.loopBound(n);
> 
>   var i = 0;
>   for (; i < upperBound; i += SPECIES.length()) {
>     var vector1 = LongVector.fromArray(SPECIES, array1, i);
>     var vector2 = LongVector.fromArray(SPECIES, array2, i1+i);
>     var xored = vector1.lanewise(VectorOperators.XOR, vector2);
>     var bitCount = xored.lanewise(VectorOperators.BIT_COUNT);
>     diff += (int) bitCount.reduceLanes(VectorOperators.ADD);
>   } 
>   
>   // Compute elements not fitting in the vector alignment.
>   for (; i < n; i++)
>     diff += Long.bitCount(array1[i]^array2[i]);
> 
>   return diff;
> }
> 
> Unvectorized function (faster):
> 
> static int countDifferingBits
> (long[] array1, long[] array2, int i1) {
>   int n = array1.length;
>   int diff = 0;
>   for i to n:
>     diff += Long.bitCount(array1[i]^array2[i1+i]);
>   
> return
>  diff;
> }
> 
> 
> Did I do anything wrong or is it the nature of the game that sometimes vectorization doesn't help? The length of array1 is 16, maybe that's too short. I could merge multiple calls of the method into one and see again.
> 
> Greetings,
> Stefan
> 
> On Tue, 6 Sept 2022 at 20:57, Stefan Reich <stefan.reich.maker.of.eye at googlemail.com> wrote:
> Hi Paul,
> 
> that's excellent.
> 
> Thanks,
> Stefan
> 
> On Tue, 6 Sept 2022 at 20:47, Paul Sandoz <paul.sandoz at oracle.com> wrote:
> Hi Stefan,
> 
> We added, on supporting hardware, vectorized bit count to the soon to be released API in JDK 19.
> 
>   https://download.java.net/java/early_access/jdk19/docs/api/jdk.incubator.vector/jdk/incubator/vector/VectorOperators.html#BIT_COUNT
> 
> You should be able to experiment with the EA build if you don’t want to wait:
> 
>   https://jdk.java.net/19/
> 
> See here for an overview in the history section:
> 
>   https://openjdk.org/jeps/426
> 
> Paul.
> 
> > On Sep 2, 2022, at 5:59 PM, Stefan Reich <stefan.reich.maker.of.eye at googlemail.com> wrote:
> > 
> > Hey tthere,
> > 
> > I'd like to parallelize this function:
> > 
> > static int countDifferingBits(long[] array1, long[] array2) {
> >   int n = array1.length;
> >   int diff = 0;
> >   for (int i = 0; i < n; i++)
> >     diff += Long.bitCount(array1[i]^array2[i]);
> >   return diff;
> > }
> > 
> > The function calculates the difference between two shapes (pixel by pixel) and is the central piece of an image recognition I am making.
> > 
> > Example for a bunch of shapes (these are all the shapes found in the extended latin alphabet, in fact): https://botcompany.de/images/1103149
> > Example for a shape comparison: https://botcompany.de/images/1103151
> > 
> > The routine above is already mega-fast as is (thanks to HotSpot!), I can compare two 256 byte arrays in 29 CPU cycles. That's less than one cycle per 64 bit!
> > 
> > But I'd still like to try to vectorize it.
> > 
> > However, I think the bitCount function will prevent this because it doesn't seem to exist in a vectorized form. Or does it? (That would be my main question here.)
> > 
> > Many greetings,
> > Stefan
> > 
> > -- 
> > == Gaz.AI ==
> 
> 
> 
> -- 
> == Gaz.AI ==
> 
> 
> -- 
> == Gaz.AI ==



More information about the panama-dev mailing list