Java 阶乘函数-并行处理

Java 阶乘函数-并行处理,java,parallel-processing,Java,Parallel Processing,我需要在EREW-PRAM系统上的并行计算中编写析因函数。 假设我们有n个处理器。 复杂性应为logn。 我该怎么做 我们有n台处理器。复杂性应为logn 这个问题毫无意义,因为您正在寻找的算法的复杂性(logn)随着处理器的增加而增加(即增加n) 我猜您要做的是将乘积1*2*3*..*k分割成大小相等的n块,在单独的处理器上计算每个子乘积,然后将n结果相乘。一般来说,您可以将n个处理器的功分为n次,然后独立计算每个处理器。您可以通过将每项工作的答案相乘来组合结果。e、 g.执行的第一个任务m!

我需要在EREW-PRAM系统上的并行计算中编写析因函数。 假设我们有n个处理器。 复杂性应为logn。 我该怎么做

我们有n台处理器。复杂性应为logn

这个问题毫无意义,因为您正在寻找的算法的复杂性(
logn
)随着处理器的增加而增加(即增加
n


我猜您要做的是将乘积
1*2*3*..*k
分割成大小相等的
n
块,在单独的处理器上计算每个子乘积,然后将
n
结果相乘。

一般来说,您可以将n个处理器的功分为n次,然后独立计算每个处理器。您可以通过将每项工作的答案相乘来组合结果。e、 g.执行的第一个任务m!,下一个(2米)/M第三个(3米!)/(2米!)等。当你将结果乘以n

顺便说一句:对于
n
的小值(例如小于1000),您不会这样做,因为启动新线程/任务的开销可能大于在单个线程中执行此操作所需的时间


我怀疑伪代码是不够的,所以这里有一个例子

public enum CalcFactorial {;

    public static BigInteger factorial(long n) {
        BigInteger result = BigInteger.ONE;
        for (long i = 2; i <= n; i++)
            result = result.multiply(BigInteger.valueOf(i));
        return result;
    }

    public static BigInteger pfactorial(long n) {
        int processors = Runtime.getRuntime().availableProcessors();
        if (n < processors * 2)
            return factorial(n);
        long batchSize = (n + processors - 1) / processors;
        ExecutorService service = Executors.newFixedThreadPool(processors);
        try {
            List<Future<BigInteger>> results = new ArrayList<Future<BigInteger>>();
            for (long i = 1; i <= n; i += batchSize) {
                final long start = i;
                final long end = Math.min(n + 1, i + batchSize);
                results.add(service.submit(new Callable<BigInteger>() {
                    @Override
                    public BigInteger call() throws Exception {
                        BigInteger n = BigInteger.valueOf(start);
                        for (long j = start + 1; j < end; j++)
                            n = n.multiply(BigInteger.valueOf(j));
                        return n;
                    }
                }));
            }
            BigInteger result = BigInteger.ONE;
            for (Future<BigInteger> future : results) {
                result = result.multiply(future.get());
            }
            return result;
        } catch (Exception e) {
            throw new AssertionError(e);
        } finally {
            service.shutdown();
        }
    }
}

public class CalcFactorialTest {
    @Test
    public void testFactorial() {
        final int tests = 200;
        for (int i = 1; i <= tests; i++) {
            BigInteger f1 = factorial(i * i);
            BigInteger f2 = pfactorial(i * i);
            assertEquals(f1, f2);
        }
        long start = System.nanoTime();
        for (int i = 1; i <= tests; i++) {
            BigInteger f1 = factorial(i * i);
        }
        long mid = System.nanoTime();
        for (int i = 1; i <= tests; i++) {
            BigInteger f2 = pfactorial(i * i);
        }
        long end = System.nanoTime();
        System.out.printf("Single threaded took %.3f sec, multi-thread took %.3f%n",
                (mid - start) / 1e9, (end - mid) / 1e9);
    }
}

让我们从最基本的开始:你至少要尝试一下吗?如果是,你得到了什么?你知道这是怎么回事吗?你知道为什么你的解决方案不起作用吗?你有什么代码可以分享吗?这是家庭作业吗?我认为OP表达自己的时候很不幸。他/她可能的意思是:我们有p处理器,复杂性应该是logn@DallaRosa当前位置我们只能猜测OP的意思。在您建议的更正中,复杂性(
logn
)与处理器数量无关(
p
)。对我来说,这也没什么意义。如果n=8,那么:1*2*3*4*5*6*7*8=p[1]计算1*2,p[2]计算3*4。。。现在我们有四个结果。继续这样做,最后我们得到log n。你怎么认为?
Single threaded took 58.702 sec, multi-thread took 11.391