RFR: JDK-8277175 : Add a parallel multiply method to BigInteger [v2]

kabutz duke at openjdk.java.net
Wed Nov 17 20:06:43 UTC 2021


On Wed, 17 Nov 2021 19:11:35 GMT, Paul Sandoz <psandoz at openjdk.org> wrote:

> > I also do not like potentially non-obvious default behavior, nor a command line flag, nor a (static) setting on `BigInteger`. Thus I think the original `parallelMultiply()` (or perhaps `multiplyParallel()`) would be preferable.
> 
> For the parallel supported features we added in Java 8 we made it explicit for the reasons you and others have stated.
> 
> > Would adding a parameter in the nature of `maxProcessors` make any sense?
> 
> Kind of but i would recommend not doing it. That's hard to express in a manner that developers will choose appropriate values across all deployments. This is why you don't see such configuration for parallel streams or the parallel array operations. It's controlled by the common pool parallelism configuration (developers have learnt the trick of running within some constrained F/J task to limit parallelism but that is unsupported behaviour). 

The "unsupported behavior" is described in the fork() method of ForkJoinTask:

"Arranges to asynchronously execute this task in the pool the current task is running in, if applicable, or using the {@link ForkJoinPool#commonPool()} if not {@link #inForkJoinPool}"

So yes, there is that workaround if someone really wants more threads for the calculation. Or they can increase the common pool parallelism with the system property.

> The closest we get to anything configurable is a parallelism threshold for methods on `ConcurrentHashMap`, where the developer can assess the cost of transformation per element in combination with how many elements to be processed (likely assessed empirically from performance measurements).

AFAIK that concurrencyLevel is not really used anymore for the CHM since Java 8, except to have at least that many initial bins:


        if (initialCapacity < concurrencyLevel)   // Use at least as many bins
            initialCapacity = concurrencyLevel;   // as estimated threads


> --
> > I would like to get a sense of how common it might be that developers operate on very large numbers that this becomes worthwhile while supporting.
> 
> The implementation looks reasonable and quite cleverly minimal, but I think it would be useful to get a sense of whether the recursion goes beyond some proportion of # runtime processors after which there is likely no point in creating more recursive tasks e.g. from the size in bits of the inputs can we determine a useful approximate threshold?

I will look at this and get back to you. Usually by the time we get to Toom Cook 3, the chunks that we are working with are so large that the RecursiveTask costs are probably not significant in comparison. But I will check.

-------------

PR: https://git.openjdk.java.net/jdk/pull/6409


More information about the core-libs-dev mailing list