diff 3__Intelligence_gathering/Bitonic_Sort.mht @ 0:a8cd65eca9a9

Initial add
author Me@portablequad
date Sun, 25 Dec 2011 14:39:36 -0800
parents
children
line diff
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/3__Intelligence_gathering/Bitonic_Sort.mht	Sun Dec 25 14:39:36 2011 -0800
     1.3 @@ -0,0 +1,423 @@
     1.4 +From: <Saved by Microsoft Internet Explorer 5>
     1.5 +Subject: Bitonic Sort
     1.6 +Date: Mon, 4 Jun 2007 10:57:06 -0700
     1.7 +MIME-Version: 1.0
     1.8 +Content-Type: text/html;
     1.9 +	charset="Windows-1252"
    1.10 +Content-Transfer-Encoding: quoted-printable
    1.11 +Content-Location: http://www.tools-of-computing.com/tc/CS/Sorts/bitonic_sort.htm
    1.12 +X-MimeOLE: Produced By Microsoft MimeOLE V6.00.2900.2962
    1.13 +
    1.14 +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
    1.15 +<HTML><HEAD><TITLE>Bitonic Sort</TITLE>
    1.16 +<META http-equiv=3DContent-Type content=3D"text/html; =
    1.17 +charset=3Dwindows-1252">
    1.18 +<META content=3D"MSHTML 6.00.2900.2963" name=3DGENERATOR></HEAD>
    1.19 +<BODY text=3D#000000 vLink=3D#6699cc aLink=3D#ff3300 link=3D#3333cc =
    1.20 +bgColor=3D#ffcc99>
    1.21 +<H1 align=3Dcenter>Bitonic Sort</H1>
    1.22 +<P align=3Dcenter>Abstract</P>
    1.23 +<BLOCKQUOTE>
    1.24 +  <BLOCKQUOTE>
    1.25 +    <BLOCKQUOTE>
    1.26 +      <BLOCKQUOTE>
    1.27 +        <P align=3Dleft>Continuing a tutorial on sorting algorithms, =
    1.28 +this page=20
    1.29 +        animates bitonic =
    1.30 +sort.</P></BLOCKQUOTE></BLOCKQUOTE></BLOCKQUOTE></BLOCKQUOTE>
    1.31 +<P align=3Dcenter>Author<BR>Thomas W. Christopher<BR></P>
    1.32 +<P>Bitonic sort is a sorting algorithm designed specially for parallel=20
    1.33 +machines.</P>
    1.34 +<P>A sorted sequence is a monotonically non-decreasing (or =
    1.35 +non-increasing)=20
    1.36 +sequence. A bitonic sequence is composed of two subsequences, one =
    1.37 +monotonically=20
    1.38 +non-decreasing and the other monotonically non-increasing. A "V" and an =
    1.39 +A-frame=20
    1.40 +are examples of bitonic sequences.</P>
    1.41 +<P>I get tired of saying "non-decreasing" and "non-increasing." They are =
    1.42 +clunky=20
    1.43 +and throw an extra negative into sentences. I will use "ascending" to =
    1.44 +mean=20
    1.45 +"non-decreasing" and "descending" to mean "non-increasing."</P>
    1.46 +<P>Moreover, any rotation of a bitonic sequence is a bitonic sequence, =
    1.47 +or if you=20
    1.48 +prefer, one of the subsequences can wrap around the end of the bitonic=20
    1.49 +sequence.</P>
    1.50 +<P>Of course, a sorted sequence is itself a bitonic sequence: one of the =
    1.51 +
    1.52 +subsequences is empty.</P>
    1.53 +<P>Now we come to a strange property of bitoinic sequences, the property =
    1.54 +that is=20
    1.55 +uses in bitonic sort: </P>
    1.56 +<BLOCKQUOTE>
    1.57 +  <P>Suppose you have a bitonic sequence of length 2n, that is, elements =
    1.58 +in=20
    1.59 +  positions [0,2n). You can easily divide it into two halves, [0,n) and =
    1.60 +[n,2n),=20
    1.61 +  such that
    1.62 +  <UL>
    1.63 +    <LI>each half is a bitonic sequence, and=20
    1.64 +    <LI>every element in half [0,n) is less than or equal to each =
    1.65 +element in=20
    1.66 +    [n,2n). (Or greater than or equal to, of course.) =
    1.67 +</LI></UL></BLOCKQUOTE>
    1.68 +<P>What is this easy method? Simply compare elements in the =
    1.69 +corresponding=20
    1.70 +positions in the two halves and exchange them if they are out of =
    1.71 +order.</P>
    1.72 +<BLOCKQUOTE>
    1.73 +  <P>&nbsp;&nbsp;&nbsp; for (i=3D0;i&lt;n;i++)=20
    1.74 +  {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if =
    1.75 +(get(i)&gt;get(i+n))=20
    1.76 +  exchange(i,i+n);<BR>&nbsp;&nbsp;&nbsp; }</P></BLOCKQUOTE>
    1.77 +<P>This is sometimes called a bitonic merge.</P>
    1.78 +<P>Why does it work? I'm not sure I could do a concise and clear enough =
    1.79 +proof to=20
    1.80 +fit in with these pages. Let's just leave it without a proof, but =
    1.81 +true.</P>
    1.82 +<P>So here's how we do a bitonic sort:=20
    1.83 +<UL>
    1.84 +  <LI>We sort only sequences a power of two in length, so we can always =
    1.85 +divide a=20
    1.86 +  subsequence of mnore than one element into two halves.=20
    1.87 +  <LI>We sort the lower half into ascending (=3Dnon-decreasing, =
    1.88 +remember) order=20
    1.89 +  and the upper half into descending order. This gives us a bitonic =
    1.90 +sequence.=20
    1.91 +  <LI>We perform a bitonic merge on the sequence, which gives us a =
    1.92 +bitonic=20
    1.93 +  sequence in each half and all the larger elements in the upper half.=20
    1.94 +  <LI>We recursively bitonically merge each half until all the elements =
    1.95 +are=20
    1.96 +  sorted. </LI></UL>
    1.97 +<P><APPLET height=3D200 archive=3Dsorts3.jar width=3D400 align=3Dleft=20
    1.98 +code=3Dcom.toolsofcomputing.SortApplets.BitonicSort.class>
    1.99 +Bitonic Sort</APPLET> <B>Bitonic Sort</B> This first version actually =
   1.100 +uses=20
   1.101 +recursion. It uses methods sortup, sortdown, mergeup, and mergedown, to =
   1.102 +sort=20
   1.103 +into ascending order or descending order and to recursively merge into =
   1.104 +ascending=20
   1.105 +or descending order.</P>
   1.106 +<P>Method <EM>void sortup(int m, int n)</EM> will sort the n elements in =
   1.107 +the=20
   1.108 +range [m,m+n) into ascending order. It uses method <EM>void mergeup(int =
   1.109 +m, int=20
   1.110 +n)</EM> to merge the n elements in the subsequence [m,m+n) into =
   1.111 +ascending order.=20
   1.112 +Similarly for <EM>void sortdown(int m, int n)</EM> and <EM>void =
   1.113 +mergedown(int m,=20
   1.114 +int n)</EM>.</P>
   1.115 +<P>The overall sort is performed by a call:</P>
   1.116 +<BLOCKQUOTE>
   1.117 +  <P>&nbsp;&nbsp;&nbsp; sortup(0,N);</P></BLOCKQUOTE>
   1.118 +<P>Both sortup and sortdown recursively sort each half to produce an =
   1.119 +A-frame=20
   1.120 +shape and then recursively merge that into an ascending or descending=20
   1.121 +sequence.</P>
   1.122 +<BLOCKQUOTE>
   1.123 +  <P>void sortup(int m, int n) {//from m to m+n<BR>&nbsp;&nbsp;&nbsp; if =
   1.124 +(n=3D=3D1)=20
   1.125 +  return;<BR>&nbsp;&nbsp;&nbsp; sortup(m,n/2);<BR>&nbsp;&nbsp;&nbsp;=20
   1.126 +  sortdown(m+n/2,n/2);<BR>&nbsp;&nbsp;&nbsp; =
   1.127 +mergeup(m,n/2);<BR>}<BR>void=20
   1.128 +  sortdown(int m, int n) {//from m to m+n<BR>&nbsp;&nbsp;&nbsp; if =
   1.129 +(n=3D=3D1)=20
   1.130 +  return;<BR>&nbsp;&nbsp;&nbsp; sortup(m,n/2);<BR>&nbsp;&nbsp;&nbsp;=20
   1.131 +  sortdown(m+n/2,n/2);<BR>&nbsp;&nbsp;&nbsp;=20
   1.132 +mergedown(m,n/2);<BR>}</P></BLOCKQUOTE>
   1.133 +<P>Methods mergeup and mergedown are fairly straightfoward. They compare =
   1.134 +
   1.135 +elements in the two halves, exchange them if they are out of order, and=20
   1.136 +recursively merge the two halves. Call mergeup( m,&nbsp; n) sorts into =
   1.137 +ascending=20
   1.138 +order the 2*n elements in the range [m,2n).</P>
   1.139 +<BLOCKQUOTE>
   1.140 +  <P>void mergeup(int m, int n) {<BR>&nbsp;&nbsp;&nbsp; if (n=3D=3D0)=20
   1.141 +  return;<BR>&nbsp;&nbsp;&nbsp; int i;<BR>&nbsp;&nbsp;&nbsp; for=20
   1.142 +  (i=3D0;i&lt;n;i++) {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if=20
   1.143 +  (get(m+i)&gt;get(m+i+n)) exchange(m+i,m+i+n);<BR>&nbsp;&nbsp;&nbsp;=20
   1.144 +  }<BR>&nbsp;&nbsp;&nbsp; mergeup(m,n/2);<BR>&nbsp;&nbsp;&nbsp;=20
   1.145 +  mergeup(m+n,n/2);<BR>}<BR>void mergedown(int m, int n) =
   1.146 +{<BR>&nbsp;&nbsp;&nbsp;=20
   1.147 +  if (n=3D=3D0) return;<BR>&nbsp;&nbsp;&nbsp; int =
   1.148 +i;<BR>&nbsp;&nbsp;&nbsp; for=20
   1.149 +  (i=3D0;i&lt;n;i++) {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if=20
   1.150 +  (get(m+i)&lt;get(m+i+n)) exchange(m+i,m+i+n);<BR>&nbsp;&nbsp;&nbsp;=20
   1.151 +  }<BR>&nbsp;&nbsp;&nbsp; mergedown(m,n/2);<BR>&nbsp;&nbsp;&nbsp;=20
   1.152 +  mergedown(m+n,n/2);<BR>}</P></BLOCKQUOTE>
   1.153 +<P>&nbsp;</P>
   1.154 +<P><APPLET height=3D200 archive=3Dsorts3.jar width=3D400 align=3Dleft=20
   1.155 +code=3Dcom.toolsofcomputing.SortApplets.BitonicSort2.class>
   1.156 +Bitonic Sort2</APPLET> <B>Bitonic Sort2</B> Bitonic sort is perfect for=20
   1.157 +parallelization. The recursive calls of merge can be done in parallel. =
   1.158 +The loops=20
   1.159 +in the merges, comparing and conditionally exchanging elements (m+i) and =
   1.160 +(m+i+n)=20
   1.161 +can also be run in parallel.</P>
   1.162 +<P>However, getting it to run efficiently in parallel requires turning =
   1.163 +the=20
   1.164 +algorithm upside down. The algorithm is expressed in terms of recursive =
   1.165 +calls.=20
   1.166 +What we need is an algorithm in terms of each individual element.</P>
   1.167 +<P>Let's examine what the elements are doing. We will use an =
   1.168 +eight-element array=20
   1.169 +and identify the elements by their positions in binary.</P>
   1.170 +<BLOCKQUOTE>
   1.171 +  <DIV align=3Dleft>
   1.172 +  <TABLE borderColorDark=3D#000000 borderColorLight=3D#ff9933 =
   1.173 +border=3D1>
   1.174 +    <TBODY>
   1.175 +    <TR>
   1.176 +      <TD>index</TD>
   1.177 +      <TD align=3Dmiddle>0</TD>
   1.178 +      <TD align=3Dmiddle>1</TD>
   1.179 +      <TD align=3Dmiddle>2</TD>
   1.180 +      <TD align=3Dmiddle>3</TD>
   1.181 +      <TD align=3Dmiddle>4</TD>
   1.182 +      <TD align=3Dmiddle>5</TD>
   1.183 +      <TD align=3Dmiddle>6</TD>
   1.184 +      <TD align=3Dmiddle>7</TD></TR>
   1.185 +    <TR>
   1.186 +      <TD>in binary</TD>
   1.187 +      <TD align=3Dmiddle>0000</TD>
   1.188 +      <TD align=3Dmiddle>0001</TD>
   1.189 +      <TD align=3Dmiddle>0010</TD>
   1.190 +      <TD align=3Dmiddle>0011</TD>
   1.191 +      <TD align=3Dmiddle>0100</TD>
   1.192 +      <TD align=3Dmiddle>0101</TD>
   1.193 +      <TD align=3Dmiddle>0110</TD>
   1.194 +      <TD =
   1.195 +align=3Dmiddle>0111</TD></TR></TBODY></TABLE></DIV></BLOCKQUOTE>
   1.196 +<P>The bits in the addresses are numbered from 0 on the right: the =
   1.197 +rightmost bit=20
   1.198 +is bit 0, the bit to its left is bit 1, etc. Bit j contributes =
   1.199 +2<SUP>j</SUP> to=20
   1.200 +the value of the binary number.</P>
   1.201 +<P>Here is the sequence of operations that can be performed in parallel: =
   1.202 +
   1.203 +<OL>
   1.204 +  <LI>All elements are sorted single element subsequences.=20
   1.205 +  <LI>Pairs of elements are sorted into ascending or descending =
   1.206 +subsequences:
   1.207 +  <DIV align=3Dleft>
   1.208 +  <TABLE borderColorDark=3D#000000 borderColorLight=3D#ff9933 =
   1.209 +border=3D1>
   1.210 +    <TBODY>
   1.211 +    <TR>
   1.212 +      <TD>[0000,0001]</TD>
   1.213 +      <TD>ascending</TD></TR>
   1.214 +    <TR>
   1.215 +      <TD>[0010,0011]</TD>
   1.216 +      <TD>descending</TD></TR>
   1.217 +    <TR>
   1.218 +      <TD>[0100,0101]</TD>
   1.219 +      <TD>ascending</TD></TR>
   1.220 +    <TR>
   1.221 +      <TD>[0110,0111]</TD>
   1.222 +      <TD>descending</TD></TR></TBODY></TABLE></DIV></LI></OL>
   1.223 +<BLOCKQUOTE>
   1.224 +  <UL>
   1.225 +    <LI>Pairs of elements whose numbers differ in bit 0, the lowest bit, =
   1.226 +are=20
   1.227 +    compared and conditionally exchanged.=20
   1.228 +    <LI>Pairs of numbers whose bit 1 is zero are sorted in ascending =
   1.229 +order.=20
   1.230 +    Those whose bit 1 is one are sorted into descending order.=20
   1.231 +</LI></UL></BLOCKQUOTE>
   1.232 +<OL start=3D3>
   1.233 +  <LI>These pairs are compared and conditionally exchanged: </LI></OL>
   1.234 +<BLOCKQUOTE>
   1.235 +  <P>First, corresponding to the top level merge call:</P></BLOCKQUOTE>
   1.236 +<BLOCKQUOTE>
   1.237 +  <DIV align=3Dleft>
   1.238 +  <TABLE borderColorDark=3D#000000 borderColorLight=3D#ff9933 =
   1.239 +border=3D1>
   1.240 +    <TBODY>
   1.241 +    <TR>
   1.242 +      <TD>0000&lt;-&gt;0010</TD>
   1.243 +      <TD>ascending</TD></TR>
   1.244 +    <TR>
   1.245 +      <TD>0001&lt;-&gt;0011</TD>
   1.246 +      <TD>ascending</TD></TR>
   1.247 +    <TR>
   1.248 +      <TD>0100&lt;-&gt;0110</TD>
   1.249 +      <TD>descending</TD></TR>
   1.250 +    <TR>
   1.251 +      <TD>0101&lt;-&gt;0111</TD>
   1.252 +      <TD>descending</TD></TR></TBODY></TABLE></DIV></BLOCKQUOTE>
   1.253 +<BLOCKQUOTE>
   1.254 +  <P>Second, corresponding to the recursive merge =
   1.255 +calls:</P></BLOCKQUOTE>
   1.256 +<BLOCKQUOTE>
   1.257 +  <DIV align=3Dleft>
   1.258 +  <TABLE borderColorDark=3D#000000 borderColorLight=3D#ff9933 =
   1.259 +border=3D1>
   1.260 +    <TBODY>
   1.261 +    <TR>
   1.262 +      <TD>0000&lt;-&gt;0001</TD>
   1.263 +      <TD>ascending</TD></TR>
   1.264 +    <TR>
   1.265 +      <TD>0010&lt;-&gt;0011</TD>
   1.266 +      <TD>ascending</TD></TR>
   1.267 +    <TR>
   1.268 +      <TD>0100&lt;-&gt;0101</TD>
   1.269 +      <TD>descending</TD></TR>
   1.270 +    <TR>
   1.271 +      <TD>0110&lt;-&gt;0111</TD>
   1.272 +      <TD>descending</TD></TR></TBODY></TABLE></DIV></BLOCKQUOTE>
   1.273 +<BLOCKQUOTE>
   1.274 +  <P>In both cases, bit 2 determines whether the elements are sorted =
   1.275 +ascending=20
   1.276 +  (bit 2 equals 0) or descending (=3D1).</P>
   1.277 +  <P>In the first level recursive call of mergeup or mergedown, the =
   1.278 +elements=20
   1.279 +  compared have positions that differ in bit 1. In the second level =
   1.280 +calls, the=20
   1.281 +  elements compared differ in bit 0.</P></BLOCKQUOTE>
   1.282 +<OL start=3D4>
   1.283 +  <LI>The final series of merges that puts the array in order =
   1.284 +corresponds to=20
   1.285 +  three levels of calls to mergeup.=20
   1.286 +  <P>First level call of mergeup:</P>
   1.287 +  <DIV align=3Dleft>
   1.288 +  <TABLE borderColorDark=3D#000000 borderColorLight=3D#ff9933 =
   1.289 +border=3D1>
   1.290 +    <TBODY>
   1.291 +    <TR>
   1.292 +      <TD>0000&lt;-&gt;0100</TD>
   1.293 +      <TD>ascending</TD></TR>
   1.294 +    <TR>
   1.295 +      <TD>0001&lt;-&gt;0101</TD>
   1.296 +      <TD>ascending</TD></TR>
   1.297 +    <TR>
   1.298 +      <TD>0010&lt;-&gt;0110</TD>
   1.299 +      <TD>ascending</TD></TR>
   1.300 +    <TR>
   1.301 +      <TD>0011&lt;-&gt;0111</TD>
   1.302 +      <TD>ascending</TD></TR></TBODY></TABLE></DIV></LI></OL>
   1.303 +<BLOCKQUOTE>
   1.304 +  <P>Two second level recursive calls of mergeup:</P></BLOCKQUOTE>
   1.305 +<BLOCKQUOTE>
   1.306 +  <DIV align=3Dleft>
   1.307 +  <TABLE borderColorDark=3D#000000 borderColorLight=3D#ff9933 =
   1.308 +border=3D1>
   1.309 +    <TBODY>
   1.310 +    <TR>
   1.311 +      <TD>0000&lt;-&gt;0010</TD>
   1.312 +      <TD>ascending</TD></TR>
   1.313 +    <TR>
   1.314 +      <TD>0001&lt;-&gt;0011</TD>
   1.315 +      <TD>ascending</TD></TR>
   1.316 +    <TR>
   1.317 +      <TD>0100&lt;-&gt;0110</TD>
   1.318 +      <TD>ascending</TD></TR>
   1.319 +    <TR>
   1.320 +      <TD>0101&lt;-&gt;0111</TD>
   1.321 +      <TD>ascending</TD></TR></TBODY></TABLE></DIV></BLOCKQUOTE>
   1.322 +<BLOCKQUOTE>
   1.323 +  <P>Four third level recursive calls of mergeup:</P></BLOCKQUOTE>
   1.324 +<BLOCKQUOTE>
   1.325 +  <DIV align=3Dleft>
   1.326 +  <TABLE borderColorDark=3D#000000 borderColorLight=3D#ff9933 =
   1.327 +border=3D1>
   1.328 +    <TBODY>
   1.329 +    <TR>
   1.330 +      <TD>0000&lt;-&gt;0001</TD>
   1.331 +      <TD>ascending</TD></TR>
   1.332 +    <TR>
   1.333 +      <TD>0010&lt;-&gt;0011</TD>
   1.334 +      <TD>ascending</TD></TR>
   1.335 +    <TR>
   1.336 +      <TD>0100&lt;-&gt;0101</TD>
   1.337 +      <TD>ascending</TD></TR>
   1.338 +    <TR>
   1.339 +      <TD>0110&lt;-&gt;0111</TD>
   1.340 +      <TD>ascending</TD></TR></TBODY></TABLE></DIV></BLOCKQUOTE>
   1.341 +<BLOCKQUOTE>
   1.342 +  <P>In all cases, bit 3 determines that the elements are sorted =
   1.343 +ascending (bit=20
   1.344 +  3 equals 0).</P>
   1.345 +  <P>In the first level recursive call of mergeup or mergedown, the =
   1.346 +elements=20
   1.347 +  compared have positions that differ in bit 2. In the second level =
   1.348 +calls, the=20
   1.349 +  elements compared differ in bit 1. In the third level calls, the =
   1.350 +elements=20
   1.351 +  compared differ in bit 0.</P>
   1.352 +  <P>So here's the code:</P>
   1.353 +  <BLOCKQUOTE><PRE>   <FONT face=3DCourier> </FONT>int i,j,k;
   1.354 +    for (k=3D2;k&lt;=3DN;k=3D2*k) {
   1.355 +      for (j=3Dk&gt;&gt;1;j&gt;0;j=3Dj&gt;&gt;1) {
   1.356 +        for (i=3D0;i&lt;N;i++) {
   1.357 +          int ixj=3Di^j;
   1.358 +          if ((ixj)&gt;i) {
   1.359 +            if ((i&amp;k)=3D=3D0 &amp;&amp; get(i)&gt;get(ixj)) =
   1.360 +exchange(i,ixj);
   1.361 +            if ((i&amp;k)!=3D0 &amp;&amp; get(i)&lt;get(ixj)) =
   1.362 +exchange(i,ixj);
   1.363 +          }
   1.364 +        }
   1.365 +      }
   1.366 +    }</PRE></BLOCKQUOTE>
   1.367 +  <P>In this code, k selects the bit position that determines whether =
   1.368 +the pairs=20
   1.369 +  of elements are to be exchanged into ascending or descending order. =
   1.370 +Variable j=20
   1.371 +  corresponds to the distance apart the elements are that are to be =
   1.372 +compared and=20
   1.373 +  conditionally exchanged. &nbsp; Variable i goes through all the =
   1.374 +elements; ixj=20
   1.375 +  is the element that is the pair of element i (the exclusive-or of i =
   1.376 +and j, the=20
   1.377 +  element whose position differs only in bit position (log<SUB>2</SUB> =
   1.378 +j)). We=20
   1.379 +  only compare elements i and ixj if i&lt;ixj. This avoids comparing =
   1.380 +them=20
   1.381 +  twice.</P></BLOCKQUOTE>
   1.382 +<P><APPLET height=3D200 archive=3Dsorts3.jar width=3D400 align=3Dleft=20
   1.383 +code=3Dcom.toolsofcomputing.SortApplets.BitonicSort3.class>
   1.384 +Bitonic Sort3</APPLET> <B>Bitonic Sort3</B><STRONG>.</STRONG> The third =
   1.385 +version=20
   1.386 +of bitonic sort is the same as the second except that the array is shown =
   1.387 +after=20
   1.388 +each iteration of the <EM>for i</EM> loop. This gives the appearance of =
   1.389 +a=20
   1.390 +parallel algorithm.</P>
   1.391 +<P>In this version, the delay between each showing of the array is set =
   1.392 +to five=20
   1.393 +times the delay following exchanges of single elements in the other =
   1.394 +versions.=20
   1.395 +There are two reasons: first, it simulates the longer time required to =
   1.396 +exchange=20
   1.397 +elements between nodes of a distributed memory parallel computer, and =
   1.398 +second, it=20
   1.399 +slows down the simulation enough that you will be able to make sense of =
   1.400 +it. </P>
   1.401 +<P>&nbsp;</P>
   1.402 +<P>&nbsp;</P>
   1.403 +<P><STRONG>Parallel bitonic sort.&nbsp; </STRONG>Here is a version of =
   1.404 +bitonic=20
   1.405 +sort that uses the Tools of Computing thread package. A version of the =
   1.406 +first=20
   1.407 +bitonic sort algorithm builds a task graph to do the sorting. The tasks =
   1.408 +are=20
   1.409 +placed in a RunQueue when they become runnable. Tasks become runnable =
   1.410 +when all=20
   1.411 +tasks in a predecessor set have terminated. There are a limited number =
   1.412 +of=20
   1.413 +Threads (4) running tasks from the queue. When tasks complete, they =
   1.414 +signal a=20
   1.415 +TerminationGroup. When all tasks in a TerminationGroup have signaled =
   1.416 +their=20
   1.417 +completion, the tasks waiting for the termination of that group are made =
   1.418 +
   1.419 +runnable.</P>
   1.420 +<P><APPLET height=3D200 archive=3Dsorts3.jar width=3D768=20
   1.421 +code=3Dcom.toolsofcomputing.SortApplets.ParBitonicSort.class>
   1.422 +    ParBitonicSort  </APPLET> </P>
   1.423 +<P><A=20
   1.424 +href=3D"http://www.tools-of-computing.com/tc/CS/Sorts/SortAlgorithms.htm"=
   1.425 +>Back to=20
   1.426 +beginning of the tutorial</A></P></BODY></HTML>