MultiThreaded Fibonacci

时间:2017-02-08 18:50:09

标签: java multithreading algorithm

public class Fibonacci {

public static class PFibo extends Thread {
    private int x;
    public long answer;

    public PFibo(int x) {
        this.x = x;
    }

    public void run() {
        if (x <= 2)
            answer = 1;
        else {
            try {
                PFibo t = new PFibo(x - 1);
                t.start();

                long y = RFibo(x - 2);

                t.join();
                answer = t.answer + y;

            } catch (InterruptedException ex) {
            }
        }
    }
}

public static long RFibo(int no) {
    if (no == 1 || no == 2) {
        return 1;
    }
    return RFibo(no - 1) + RFibo(no - 2);
}

public static void main(String[] args) throws Exception {
    try {
        long start = System.currentTimeMillis();
        PFibo f = new PFibo(30);
        f.start();
        f.join();
        long end = System.currentTimeMillis();
        System.out.println("Parallel-Fibonacci:" + f.answer + "\tTime:" + (end - start));

        start = System.currentTimeMillis();
        long result = RFibo(30);
        end = System.currentTimeMillis();
        System.out.println("Normal-Fibonacci:" + result + "\tTime:" + (end - start));


    } catch (Exception e) {
    }
}

}

我目前正在阅读多线程算法&#39;来自&#39;算法导论&#39;。我尝试实现一个基本的多线程程序来计算第n个斐波纳契数。对于n = 30,程序给出了以下输出:

Parallel-Fibonacci:832040   Time:10
Normal-Fibonacci:832040     Time:3

为什么并行版本比非并行版本慢。有线程切换或者线程数太多&#39;放慢了速度?

加速并行版本必须遵循什么方法?

2 个答案:

答案 0 :(得分:1)

  

是否有线程切换或者线程数太多&#39;放慢了速度?

当然可以。在许多方面 -
正如评论中已经指出的那样

  1. 您正在为每次通话创建新主题,即
    PFibo t = new PFibo(x - 1); t.start();
  2. 有效地,您为PFibo(30)创建了大约28个主题,这意味着用于评估每个词的一个上下文切换

    1. 其次,由于PFibo(x)的评估依赖于PFibo(x - 1),它要求你在那里调用join()方法,每次你创建/开始一个新线程,即最终它已成为连续剧。
    2. 所以最终费用 =实际序列方法的成本RFibo(n) +围绕n个上下文切换+同步时间(join()所用的时间)

        

      加速并行版本必须遵循什么方法?

      我会说,不要这样做。斐波那契系列&#39;解决方案模式不适合通过并行性进行优化。只需依靠串行版本(您可以实现迭代版本以提高效率)。

答案 1 :(得分:0)

您的输入太小,无法从并行性中获得任何好处。尽管如此,并行化版本的Fibonacci算法还是有意义的。您的算法是指数的。通过创建新线程,您可以在线程之间分配指数级工作。但是请注意,确实存在一个线性时间算法来计算斐波那契数,正如这里的人们已经说过的那样,最好按顺序运行。因此,在您的实现中使用较大的输入,我得到的是Intel 2.3GHz:

$ java Fib 30
Parallel-Fib:832040     Time:0.026805616
Sequential-Fib:832040   Time:0.002786453

$ java Fib 33
Parallel-Fib:3524578    Time:0.012451416
Sequential-Fib:3524578  Time:0.012420652

$ java Fib 36
Parallel-Fib:14930352   Time:0.035997556
Sequential-Fib:14930352 Time:0.056066557

$ java Fib 44
Parallel-Fib:701408733   Time:2.037292083
Sequential-Fib:701408733 Time:3.050315551