并行冒泡排序性能

时间:2015-02-08 19:16:17

标签: java multithreading performance algorithm sorting

我的目标是使用Thread实现排序算法Bubble-sort,该程序似乎运行正常。然而,表演很糟糕,所以我想知道如何让代码运行得更快,为什么它运行得如此糟糕。

代码基于以下算法:

PARALLEL BUBBLE SORT(A) - 算法

> 1.For k = 0 to n-2
> 2.If k is even then
> 3.  for i = 0 to (n/2)-1 do in parallel
> 4.     if A[2i] > A[2i+1] then
> 5.        Exchange A[2i] <-> A[2i+1]
> 6.Else
> 7.  for i = 0 to (n/2)-2 do in parallel
> 8.   if A[2i+1] > A[2i+2] then
> 9.     Exchange A[2i+1] <-> A[2i+2]
> 10.Next k

public static void sort(){
    int n = input.length; //length of the array to sort
    Thread[] thr1 = new Thread[(int)n/2];
    Thread[] thr2 = new Thread[(int)n/2];
    int count1;
    int count2;

    for(int i = 0; i<n-1;i++){
        if(i % 2 == 0){ // i even
        count1 = 0;

        for(int j = 0; j<n/2; j++){
            final int tmp = j;
            count1++;
            thr1[tmp] = new Thread(){ 
                public void run(){
                    if (input[2*tmp]>input[2*tmp+1]) 
                        swap(2*tmp,2*tmp+1);
                }
            };
            thr1[tmp].start();
        }
        //waiting for threads to finish
        for(int m = 0; m<count1; m++){
            try {
                thr1[m].join();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }}
        }   
        else{ // i odd
        count2 = 0;
        for(int k = 0; k<n/2-1;k++){
            final int tmp = k;
            count2++;
            thr2[tmp] = new Thread(){
                public void run(){
                    if (input[2*tmp+1]>input[2*tmp+2])
                        swap(2*tmp+1,2*tmp+2);
                }
            };
            thr2[tmp].start();
        }
        // Waiting for threads to finish
        for(int m = 0; m<count2; m++){
            try {
                thr2[m].join();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }}          
    }
}

编辑:

不幸的是,这是使用ExecutorService的新版本,正如预测的那样,它仍然运行得非常糟糕,比顺序版本慢。

public static void sort(){
    int n = input.length; //length of the array to sort
    ExecutorService executor = Executors.newFixedThreadPool(8);

    for(int i = 0; i<n-1;i++){
        if(i % 2 == 0){ // i even

        for(int j = 0; j<n/2; j++){
            final int tmp = j;
            executor.submit(new Runnable(){ 
                public void run(){
                    if (input[2*tmp]>input[2*tmp+1]) 
                        swap(2*tmp,2*tmp+1);}
            });}
        }   

        else{ // i odd
        for(int k = 0; k<n/2-1;k++){
            final int tmp = k;
            executor.submit(new Runnable(){
                public void run(){
                    if (input[2*tmp+1]>input[2*tmp+2])
                        swap(2*tmp+1,2*tmp+2);}
            });}
        }       
    }
executor.shutdown();
try {
    executor.awaitTermination(1, TimeUnit.DAYS);
} catch (InterruptedException e) {
    e.printStackTrace();}
}

1 个答案:

答案 0 :(得分:2)

它之所以如此慢的原因是new Thread()的调用非常昂贵。启动另一个线程来完成部分排序需要数千倍的时钟周期,而不是在原始线程中进行所有排序。

另外,即使new Thread()不那么昂贵,你仍然看不到太多(或任何)性能改进,因为排序是一个内存绑定操作,你很可能试图在单CPU,多核系统,但CPU只有一个地址总线和一个数据总线,因此核心将主要是等待彼此放开数据总线。