Note
Access to this page requires authorization. You can try signing in or changing directories.
Access to this page requires authorization. You can try changing directories.
Since there was some requests to get the code for the parallel QuickSort mentioned here I decided to post the code I used. This is not a complete listing. You need the samples that can be downloaded from here. This listing is an extension to the Sort class in Chapter6/ParallelSort/Sort.cs.
1: private static DispatcherQueue queue =
2: new DispatcherQueue("CcrQueue");
3: private static Port<SortInfo> infoPort = new Port<SortInfo>();
4: private static Port<int> resultPort = new Port<int>();
5: private static EventWaitHandle done =
6: new EventWaitHandle(false, EventResetMode.ManualReset);
7: private static int remaining = 0;
8: private static int[] theArray = null;
9:
10: class SortInfo
11: {
12: public int from;
13: public int to;
14: public int depth;
15: }
16:
17: public static void CcrQuickSort(int[] array)
18: {
19: theArray = array;
20: remaining = array.Length;
21: Arbiter.Activate(queue,
22: Arbiter.Receive(true, infoPort, CcrSortPart));
23: Arbiter.Activate(queue,
24: Arbiter.Receive(false, resultPort, CcrSortPartDone));
25: infoPort.Post(
26: new SortInfo
27: {
28: from = 0,
29: to = array.Length,
30: depth =
31: (int) Math.Log(Environment.ProcessorCount,2)+4
32: });
33: done.WaitOne();
34: }
35:
36: private static void CcrSortPartDone(int count)
37: {
38: remaining -= count;
39: if (remaining <= 0)
40: done.Set();
41: else
42: Arbiter.Activate(queue,
43: Arbiter.Receive(false, resultPort, CcrSortPartDone));
44: }
45:
46: private static void CcrSortPart(SortInfo info)
47: {
48: if (info.from == info.to)
49: return;
50: if (info.to - info.from <= Threshold)
51: {
52: InsertionSort(theArray, info.from, info.to);
53: resultPort.Post(info.to - info.from);
54: }
55: else
56: {
57: int pivot = info.from;
58: pivot = Partition(theArray, info.from, info.to, pivot);
59: if (info.depth > 0)
60: {
61: infoPort.Post(new SortInfo
62: {
63: from = info.from,
64: to = pivot,
65: depth = info.depth - 1
66: });
67: infoPort.Post(new SortInfo
68: {
69: from = pivot + 1,
70: to = info.to,
71: depth = info.depth - 1
72: });
73: }
74: else
75: {
76: CcrSortPart(new SortInfo
77: {
78: from = info.from,
79: to = pivot
80: });
81: CcrSortPart(new SortInfo
82: {
83: from = pivot + 1,
84: to = info.to
85: });
86: }
87: resultPort.Post(1);
88: }
89: }
The use of a static array and remaining counter are obviously not a great design for your typical application, but sneaked in there in the hunt for a saving a few microseconds. Didn't really matter...