0

I use a multithread quicksort Java function from cern.colt.ParallelQuickSort library(http://incanter.org/docs/parallelcolt/api/cern/colt/ParallelQuickSort.html and https://github.com/Danimoth/Parallel-Colt/blob/master/src/cern/colt/ParallelQuickSort.java). I want to test how much time elapse when choosing different number of threads. I use System.nanoTime() to keep track of the run time. However, even when the number of threads I choose and unsorted array is the same for multiple runs, the run time are quite different. I think it is because the quicksort() provided in cern.colt.ParallelQuickSort library has no wait for threads to complete. I would like to know how I can write code to wait for all threads to complete so that I can measure the run time outside the function the library provided? Something like below:?

ParallelQuickSort qs=new ParallelQuickSort();
long startTime = System.nanoTime();
qs.quickSort(unsorted_array, 0, array_size, comp, number_threads);

//java code to wait for all threads to complete

long time_elapse= System.nanoTime() - startTime;

Edit: Below is my code: Originally, my code is to run quicksort with threads number from 1 to 15 for array size 2^10, 2^15, 2^20, 2^25 and 2^28 and for each case I run 30 times. In order to debug, I changed my code to only run array size=2^10 using 1 thread and run it for 10 times.

import cern.colt.ParallelQuickSort;
import cern.colt.function.tint.IntComparator;
import cern.colt.Timer;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileWriter;
import java.io.IOException;
import java.lang.System.*;
import java.util.*;


public class quick_sort {

    static void readData(int dst[], int nitems, int num) throws IOException{ 
        String s="mydata"+Integer.toString(num)+".txt";
        //System.out.println(s);
        Scanner scanner = new Scanner(new File(s));
        int i = 0;
        while(scanner.hasNextInt())
        {
            dst[i++] = scanner.nextInt();
        }

    }



public static void main(String [ ] args) throws IOException
{

    //for(int i=0; i<n;i++) dst[i]=n-i;


    /*
    System.out.println("Unsorted: ");
    for(int i=0; i<n; i++) System.out.print(dst[i]+" ");
    System.out.println(" ");
    */

    IntComparator comp=new IntComparator(){
        public int compare(int a, int b){
            if(a>b) return 1;
            else if(a<b) return -1;
            else return 0;
        }
      };




    int iter=10;
    int thread_num=1;
    //FileWriter fw = new FileWriter("out.txt");

    int num[]={10, 15, 20, 25, 28};
for(int m=0; m<1; m++){         
    for(int k=1; k<=thread_num; k++){
    long estimatedTime=0;
    for(int i=0; i<iter; i++){
        int n=1<<num[m];
        int dst[]=new int[n];
        readData(dst, n, num[m]);

        ParallelQuickSort qs=new ParallelQuickSort();

        long startTime = System.nanoTime();

        qs.quickSort(dst, 0, n, comp, k);

        long temp= System.nanoTime() - startTime;
        estimatedTime+=temp;



        System.out.println("Time="+temp*0.000001);

    }
    System.out.println(num[m]+"Wall Clock Time when thread number="+k+": "+estimatedTime/iter*0.000001);
    //fw.write(num[m]+"Wall Clock Time when thread number="+k+": "+estimatedTime/iter*0.000001+'\n');
}   


    //System.out.println("Sorted: ");
    //for(int i=0; i<n; i++) System.out.print(dst[i]+" ");
    //System.out.println(" ");




}
//fw.close();
System.out.println("Finish!");

}   

}

The result is shown below:

Time=0.755289
Time=0.632124
Time=0.502016
Time=0.502922
Time=0.100524
Time=0.076072
Time=0.073657
Time=0.073355
Time=0.074261
Time=0.076374
10Wall Clock Time when thread number=1: 0.286659
Finish!
weidan
  • 23
  • 5
  • http://docs.oracle.com/javase/7/docs/api/java/lang/Thread.html#join%28%29 - Hope this is helpful. – BatScream Feb 16 '15 at 23:47
  • I have no way to obtain threads created in side that function, how do I use join? – weidan Feb 16 '15 at 23:49
  • Use an `ExecutorService` – MadProgrammer Feb 16 '15 at 23:59
  • You should indeed use a `CountDownLatch`. Define a `CountDownLatch` with a size equal to the amount of threads, and `countDownLatch.countdown()` in every thread, and `countDownLatch.await()` to wait for every thread. – MeetTitan Feb 17 '15 at 00:05
  • Do I need to change library code if using CountDownLatch? ParallelQuickSort.java is library code and I don't think I can change it. – weidan Feb 17 '15 at 00:10
  • No. You need to invoke your quick sort in a separate thread in your main program. This thread is on a latch. When it finishes then your main thread will resume and execute your timing calculation. –  Feb 17 '15 at 00:26
  • If I invoke 5 threads in the quicksort and I start a new thread for that quicksort, how many threads I should specify when I define CountDownLatch? 5 or 6 or 1? – weidan Feb 17 '15 at 00:34
  • 1, since the latch will not have any control over the threads create in that Cern library. You just want to wait for your main worker thread that calls quick sort to finish. –  Feb 17 '15 at 00:44
  • Thus, you mean the thread I create for running quicksort will wait for all the threads invoked inside the quicksort function, am I correct? – weidan Feb 17 '15 at 00:58
  • Integer.compare already exists, you don't need to reimplement it. – Adrian Leonhard Feb 17 '15 at 01:35
  • I would like to know how do I use Integer.compare in this quicksort method? Integer.compare needs to provide two integer arguments. – weidan Feb 17 '15 at 01:47
  • I changed IntComparator comp to the build-in integer.compare, but the performance is still unstable. – weidan Feb 17 '15 at 14:26

1 Answers1

1

The function ParallelQuickSort.quicksort returns only once all threads/sub operations are complete. You do not need to manually wait until all threads are finished.

This can be confirmed by looking into the code (look for other.get()) and that it is the only reasonable behavior.

EDIT: Testing performance can be deceivingly hard, see Java Performance Testing and many other places for details.

Community
  • 1
  • 1
Adrian Leonhard
  • 7,040
  • 2
  • 24
  • 38
  • Then why under the same condition(that is same unsorted array, same number of threads) running for multiple times such as 30 times. I got the run time has a great difference? – weidan Feb 17 '15 at 01:08
  • @weidan It could be a number of factors, probably other processes running on your pc. I've updated my answer. Try using a larger array/ more iterations or posting your testing code if you want more accurate answers. – Adrian Leonhard Feb 17 '15 at 01:13