Sorting Network (C # simulation)

Source: Internet
Author: User

The sorting network uses a comparator for simple combination to form a sorting network. The parallel execution can achieve efficient sorting algorithms. If the sorting network is implemented using software, it actually has no major significance, although the current computer has multiple cores, it can also use multiple threads to achieve true parallelism to a certain extent, but its parallel capabilities are limited compared with a slightly larger sorting network. the hardware implementation of the sorting network is very advantageous. The basic unit comparator of the sorting network is very simple, suitable for large-scale applications, and can be modularized. after a comparative sorting network is formed, the input sequence can be sorted under a limited clock cycle sequence (parallel in general sense is not required ). in a sorting network with a scale of N, the sequence with a length of 1-N is the same. of course, one disadvantage of the hardware implementation of the sorting network is that it is difficult to expand the sorting scale N. for modern computers, if there is a built-in sorting Network Module (with a size of 2 ^ 32), the cost is not very high, and the software can be used to merge and sort on this basis, the sorting performance of hundreds of millions of sequences can be greatly improved.

The following algorithm is just a simulation (although parallel simulation can be performed, it doesn't make much sense. Here we just want to understand the implementation of the algorithm Principles ):

/// <Summary> // input event, used to trigger input events in the input pipeline of the comparator. /// </Summary> Public Delegate void inputevent (); /// <summary> /// input/output pipeline of the comparator /// </Summary> Public Class Pipeline {/// <summary> // pipeline value /// </Summary> Public int value {Get; set ;}//< summary> /// next pipe line ///</Summary> Public pipeline nextpipe {Get; set ;} /// <summary> /// enter the trigger event, which is delegated here. No event is required, because the object to be mounted to this event is less than or equal to 1 // </Summary> private inputevent _ inpute Vent; /// <summary> /// pipe structure, event processing when an input is required in the MPs queue /// </Summary> /// <Param name = "inputevent"> </param> Public pipeline (inputevent) {This. _ inputevent = inputevent ;} /// <summary> /// MPs queue Transmission Value /// </Summary> /// <Param name = "avalue"> value </param> Public void transfervalue (int avalue) {This. value = avalue; // if there is a pipeline, pass the value to If (nextpipe! = NULL) {nextpipe. transfervalue (avalue);} // a value input event exists in the trigger tube. This code is used when I use the trigger mechanism to implement. If (_ inputevent! = NULL) {_ inputevent () ;}/// <summary> // MPs queue transfer value /// </Summary> Public void transfervalue () {transfervalue (this. value) ;}/// <summary> // comparator, composed of two input and two output pipelines and comparison components /// </Summary> public class comparator {private int operandcount = 0; /// <summary> /// enter the MPs queue A /// </Summary> Public pipeline inputA {Get; private set ;} /// <summary> /// enter the MPs queue B /// </Summary> Public pipeline inputb {Get; priv Ate set;} // <summary> // output pipeline a // </Summary> Public pipeline outputa {Get; private set ;} /// <summary> /// output pipe B /// </Summary> Public pipeline outputb {Get; private set;} private comparenetwork _ comparenetwork; /// <summary> /// reset the input count /// </Summary> private void reset () {operandcount = 0 ;} /// <summary> /// constructor, which must be passed in to the comparison Network (you can skip this operation. The main purpose is to do some tests, so the entire network reference will be passed in) /// </Summary> /// <para M name = "acomparenets"> comparison Network </param> Public comparator (comparenetwork acomparenets) {This. _ comparenetwork = acomparenets; // inputA = new pipeline (New inputevent (docompare); // inputb = new pipeline (New inputevent (docompare); // events are not triggered, inputA = new pipeline (null); inputb = new pipeline (null); outputa = new pipeline (null); outputb = new pipeline (null ); reset () ;}//< summary> /// compare the action /// </Summary> Public void docompare () {operandcount ++; // The actual comparison is performed only when both input pipelines have values. // If (operandcount <= 1) // {// return; //} If (inputA. value> inputb. value) {outputa. value = inputb. value; outputb. value = inputA. value;} else {outputa. value = inputA. value; outputb. value = inputb. value;} outputa. transfervalue (); outputb. transfervalue (); reset (); this. _ comparenetwork. comparetimes ++ ;}/// <summar Y> // compare the sorting network. Here it is only a simulation algorithm, and it does not implement parallel comparison in the true sense. // It is not of great significance to use software to implement such a comparison network, dedicated hardware is used to realize its true advantages. /// </Summary> public class comparenetwork {public int comparetimes {Get; set;} private int _ n {Get; set;} private int _ k {Get; set ;} private list <pipeline> _ inputpipelines; private list <pipeline> _ outputpipelines; private list <comparator> _ comparators; private list <comparator> _ comparatormatirx; private pipeline [] _ outputs; // <summary> // compare the network constructor /// </Summary> /// <Param name = "K "> Compare the network scale base and the input scale N = 2 ^ k </param> Public comparenetwork (int K) {This. _ n = convert. toint32 (math. pow (2, K); this. _ k = K; _ inputpipelines = new list <pipeline> (); _ outputpipelines = new list <pipeline> (); _ comparatormatirx = new list <comparator> (); For (INT I = 0; I <this. _ n; I ++) {_ inputpipelines. add (new pipeline (null); _ outputpipelines. add (new pipeline (null);} _ comparators = new list <compara Tor> (); buildcomparenets () ;}/// <summary> // compare the network order. /// </Summary> /// <Param name = "values"> set of values to be sorted </param> /// <returns> sort the set of values in sequence </ returns> Public int [] docompare (INT [] values) {comparetimes = 0; // The number of input comparison sequences must be less than or equal to the capability of the comparison network. n if (values. length> This. _ n) {return NULL;} int thecount = 0; // input the value for (INT I = 1; I <= values. length; I ++) {_ inputpipelines [I-1]. transfervalue (Values [I-1]); thecount ++;} // if the number of input sequences is insufficient, fill the MPs queue with the maximum value. for (INT I = thecoun T + 1; I <= This. _ n; I ++) {_ inputpipelines [I-1]. transfervalue (Int. maxvalue);} // start the computation. The comparison is performed from the front to the back of the comparator. the comparator in the same depth can complete the computation in parallel under the same clock pulse. Of course, this is just a simulation. for (INT I = 0; I <_ comparatormatirx. count; I ++) {for (Int J = 0; j <_ comparatormatirx [J]. count; j ++) {_ comparatormatirx [I] [J]. docompare () ;}/// obtain the value from the output pipeline. List <int> theret = new list <int> (); For (INT I = 0; I <values. length; I ++) {if (I <_ outputs. length) {theret. add (_ outputs [I]. value) ;}} return theret. toarray () ;}/// <summary> // construct a comparison network /// </Summary> private void buildcomparenets () {_ comparatormatirx. clear (); pipeline [] theinputlines = _ inputpipelines. toarray (); For (INT I = 1; I <= This. _ k; I ++) {int thestartlevel = _ comparatormatirx. count; theinputlines = buildmergingnetwork (theinputlines, I, thestartlevel);} _ outputs = theinputlines ;} /// <summary> /// recursively construct the bitonic sequencer /// </Summary> /// <Param name = "inputlines"> input pipeline </param> // /<returns> network output pipeline set </returns> private list <pipeline> buildbitonicsorter (pipeline [] inputlines, int level) {pipeline [] outputlines = new pipeline [inputlines. length]; List <pipeline> theps = new list <pipeline> (); If (inputlines. length <= 1) {theps. addrange (inputlines); Return theps;} int thehalf = inputlines. length/2; for (Int J = 1; j <= thehalf; j ++) {comparator thecomparator = new comparator (this); int thecomindex1 = J; int thecomindex2 = thecomindex1 + thehalf; inputlines [thecomindex1-1]. nextpipe = thecomparator. inputA; inputlines [thecomindex2-1]. nextpipe = thecomparator. inputb; outputlines [thecomindex1-1] = thecomparator. outputa; outputlines [thecomindex2-1] = thecomparator. outputb; _ comparators. add (thecomparator); addcomparator (thecomparator, level);} List <pipeline> theps_1 = new list <pipeline> (); list <pipeline> theps_2 = new list <pipeline> (); For (Int J = 1; j <= thehalf; j ++) {theps_1.add (outputlines [J-1]); theps_2.add (outputlines [J + thehalf-1]);} var theret1 = buildbitonicsorter (theps_1.toarray (), level + 1 ); vaR theret2 = buildbitonicsorter (theps_2.toarray (), level + 1); theps. addrange (theret1); theps. addrange (theret2); Return theps;} private void addcomparator (comparator, int level) {If (level> = This. _ comparatormatirx. count) {This. _ comparatormatirx. add (new list <comparator> ();} This. _ comparatormatirx [level]. add (comparator );} /// <summary> /// construct the merged network /// </Summary> /// <Param name = "inputlines"> input media transcoding queue </param> /// <param name = "K"> phase k </param> /// <Param name = "level"> tree level of the comparator </param> /// <returns> Network set of output pipelines </returns> private pipeline [] buildmergingnetwork (pipeline [] inputlines, int K, int level) {int thenum = convert. toint32 (math. pow (2, K); int themergercount = This. _ n/thenum; int themergerwidth = thenum; pipeline [] theinputlines = inputlines; pipeline [] theoutputpipelines_temp = new pipeline [this. _ n]; for (INT I = 1; I <= themergercount; I ++) {int thestart = (I-1) * themergerwidth + 1; int theend = I * themergerwidth; int thehalfn = themergerwidth/2; for (Int J = 1; j <= thehalfn; j ++) {comparator thecomparator = new comparator (this); int thecomindex1 = thestart + J-1; int thecomindex2 = theend-J + 1; theinputlines [thecomindex1-1]. nextpipe = thecomparator. inputA; theinputlines [thecomindex2-1]. nextpipe = thecomparator. inputb; theoutputpipelines_temp [thecomindex1-1] = thecomparator. outputa; theoutputpipelines_temp [thecomindex2-1] = thecomparator. outputb; _ comparators. add (thecomparator); addcomparator (thecomparator, level);} // generate n/2 bitonicsorters // generate the semi-cleaner var theinputs_1 = new list <pipeline> (); vaR theinputs_2 = new list <pipeline> (); For (Int J = 1; j <= thehalfn; j ++) {theinputs_1.add (theoutputpipelines_temp [thestart + J-2]);} For (Int J = thehalfn + 1; j <= themergerwidth; j ++) {theinputs_2.add (parts [thestart + J-2]);} var theouts1 = partition (theinputs_1.toarray (), level + 1); var theouts2 = buildbitonicsorter (theinputs_2.toarray (), LEVEL + 1); For (Int J = 1; j <= thehalfn; j ++) {theoutputpipelines_temp [thestart + J-2] = theouts1 [J-1];} for (Int J = thehalfn + 1; j <= themergerwidth; j ++) {theoutputpipelines_temp [thestart + J-2] = theouts2 [J-1-thehalfn];} return theoutputpipelines_temp ;}}

PS: From the code above, we can see that using software to implement this sort network has no advantages, but it is very suitable for hardware implementation,
The following is the test code:
 

CompareNetwork theC = new CompareNetwork(3);            var theRet1 = theC.Docompare(new int[] { 1, 2, 3, 4, 4, 5, 6, 8 });            var theRet2 = theC.Docompare(new int[] { 2, 1, 3, 4 });            var theRet3 = theC.Docompare(new int[] { 3, 4, 2, 1 });            var theRet4 = theC.Docompare(new int[] { 3, 2, 4, 1 });

 

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.