How is the Great Central Dispatcher so fast? (For this Quicksort algorithm)

In an attempt to figure out some multi-threaded / sorting fun, I decided to put together a Quicksort test (written in Objective-C) that uses Grand Central Dispatch to determine how much faster it will use multi-core machines.

main.m

QuickSort.m

This is the generated result:

2011-11-27 13:10:55.595 Quicksort[1583:707] Took 4.731876 seconds to sort 1000000 elements with NO GCD
2011-11-27 13:10:55.670 Quicksort[1583:707] Took 0.070753 seconds to sort 1000000 elements WITH GCD

This is a fairly simple algorithm using the Simple version mentioned on the Wikipedia page:

Quicksort on Wikipedia

I am running this on an i7 machine, so expect a performance increase of around 8 or more. Instead, when using Grand Central Dispatch, the algorithm is about 60-70x faster .

, , GCD, ?

+5
2

- ,

    NSLog(@"Took %f seconds to sort %lu elements WITH GCD", duration, NUM_ELEMENTS);

    NSLog(@"Took %f seconds to sort %lu elements WITH GCD", duration, [sorted count]);

2011-11-27 18:40:28.020 qs[37855:707] Took 5.412689 seconds to sort 1000000 elements with NO GCD
2011-11-27 18:40:28.104 qs[37855:707] Took 0.082455 seconds to sort 1 elements WITH GCD

, ...

+2

. () .

. dispatch_semaphore_create (0) , SL- GCD, , , : 500 . .

.

...

. , , , . , dispatch_async() dispatch_semaphore_wait()

    // Create semaphore and sort the left side
    __block NSArray*  lessSorted = nil;
    dispatch_semaphore_t  lessSem = dispatch_semaphore_create(0);

    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW, 0), ^{
        lessSorted = [QuickSort sort:less useGCD:useGCD];

        [lessSorted retain];
        dispatch_semaphore_signal(lessSem);
    });

    // Create semaphore and sort the right side
    __block NSArray*  moreSorted = nil;
    dispatch_semaphore_t  moreSem = dispatch_semaphore_create(0);

    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW, 0), ^{
        moreSorted = [QuickSort sort:more useGCD:useGCD];

        [moreSorted retain];
        dispatch_semaphore_signal(moreSem);
    });

    // Wait for both sides to finish sorting
    dispatch_semaphore_wait(lessSem, DISPATCH_TIME_FOREVER);
    dispatch_semaphore_wait(moreSem, DISPATCH_TIME_FOREVER);

    // Merge
    [concat addObjectsFromArray:lessSorted];
    [concat addObject:pivotObj];
    [concat addObjectsFromArray:moreSorted];

    dispatch_release(lessSem);            
    dispatch_release(moreSem);
    [lessSorted release];
    [less release];
    [moreSorted release];
    [more release];
+1

All Articles