Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java Integer Comparison: greater than

I have an array of a million integers because I am experimenting with parallel quicksort. I have the following strange behaviour sometimes:

To check wether the array was sorted correctly I entered the following code after sorting:

for(int j=0; j < array_parallel.length-1; ++j)
   if(array_parallel[j] > array_parallel[j+1])
    System.out.println("ERROR! NOT SORTED CORRECTLY!");

In some cases I get the error output that it was not sorted correctly, and when I debug I find the following (example, always different):

j=1942 array_parallel[1942] = 6000; array_parallel[1943] = 6000;

(try ignoring the numbers, its not any specific value or range) So its always in the cases where the left value equals the right value. Well, for comparison of greater this should return in false, but I definetely get the output.

What the hell is wrong!?

I even cross checked the array and it is sorted correctly. If I plot a small array(around 100) its also fine. Did I miss something my mind tricks me?

Edited 21:32 (UTC+1):

private static int ANZAHL = 1000000;        // Größe des Arrays

    public static void main(String[] args) {
        // TODO Auto-generated method stub

        int array_single[] = new int[ANZAHL];
        int array_parallel[] = new int[ANZAHL];

        Speedmeasure sp_single = new Speedmeasure();
        Speedmeasure sp_parallel = new Speedmeasure();
        ArrayReader ar = null;

        try {
            ar = new ArrayReader(array_single, array_parallel);
        } catch (FileNotFoundException e1) {
            // TODO Auto-generated catch block
            e1.printStackTrace();
        } catch (IOException e1) {
            // TODO Auto-generated catch block
            e1.printStackTrace();
        } catch (ClassNotFoundException e1) {
            // TODO Auto-generated catch block
            e1.printStackTrace();
        }

        if(ar == null) {
            System.err.println("Großes Problem. Lass es sein!");
            System.exit(-1);
        }
        else {

            for(int i=0; i < 5; ++i) {
                Quicksort_Single qs = new Quicksort_Single();
                sp_single.setStart(System.currentTimeMillis());

                qs.quicksort_start(array_single);
                sp_single.setStop(System.currentTimeMillis());

                //printArray(array);
                PrintSpeed(sp_single.getSpeed(), "Single");


                System.out.print("\nUnd jetzt treiben wir es parallel! \n\n");
                Thread t1 = new Thread(new Quicksort_Parallel(0, array_parallel.length-1, array_parallel));

                sp_parallel.setStart(System.currentTimeMillis());
                t1.start();

                try {
                    t1.join();
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }

                sp_parallel.setStop(System.currentTimeMillis());

                //printArray(array_parallel);
                PrintSpeed(sp_parallel.getSpeed(),"Parallel");

                System.out.println("Speed up was: "+sp_parallel.calcSpeedup(sp_single.getSpeed(), sp_parallel.getSpeed()));
                System.out.println("******************************************");

                for(int j=0; j < array_single.length-1; ++j)
                    if(array_single[j] > array_single[j+1])
                        System.out.println("ERROR! NICHT SORTIERT KORREKT BEI SINGLE!");

                for(int j=0; j < array_parallel.length-1; ++j)
                    if(array_parallel[j] > array_parallel[j+1])
                        System.out.println("ERROR! NICHT SORTIERT KORREKT BEI PARALLEL!");



                ar.copyArray(array_single, array_parallel);
            }
        }
    }

I do a join on the thread that initiates the parallel sort. The first Thread than spawns up to 4 threads maximum at the same time. I am not 100% sure what concurrency it could be, as I can see in the debugger the array is sorted. I'll add the output of the two integers and have another look.

Edited 23/05/12 16:46 UTC+1

I was changing the whole thing to work with the new, and really easy, ForkJoinPool from JDK 1.7. Tested with integer arrays up to 10 mio integers and got interesting results: I have tested it on a Core2Duo (2010) MacBook Pro and Core-i5 (2011) Windows 7:

core2duo and i5 can do hyperthreading, so i tested now with availableProcessors()*2 -> the core2duo got a little boost for speedup to 1.8 and 1.7 for 2 threads; i5 is currently around speedup of 3.2 with up to 8 threads per availableProcessors()*2

Still experimenting the shit out of my machine. All tests were done with the same arrays and the average was calculated from 1000 sorting iterations over each array size.

like image 227
Stefan Avatar asked May 22 '12 19:05

Stefan


3 Answers

Looking through your code, you spawn a thread but then immediately join it back to the main execution thread:

        Thread t1 = new Thread(new Quicksort_Parallel(0, array_parallel.length-1, array_parallel));

        sp_parallel.setStart(System.currentTimeMillis());
        t1.start();

        try {
            t1.join();

The question becomes - what are you doing w/in the Quicksort_Parallel routine? Are you spawning additional threads? Are you doing a join on all of them? If not, you have created a race condition that would explain the results your are seeing.

like image 192
Mike Avatar answered Oct 28 '22 06:10

Mike


You might be a victim of a race condition, this means your output is dependent on the sequence of other events. So if you have one thread that is working faster you will get a race condition. A way to stop this is using semaphores or divide your loop among the threads. How are you doing your sort? Are you using a reduction?

like image 22
ewein Avatar answered Oct 28 '22 08:10

ewein


If you're using Java SE 7, consider to use the new fork/ join API:

http://docs.oracle.com/javase/tutorial/essential/concurrency/forkjoin.html

http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/ForkJoinPool.html

http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/ForkJoinTask.html

http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/ForkJoinWorkerThread.html

like image 43
Puce Avatar answered Oct 28 '22 08:10

Puce