Advertisement
Guest User

Batcher Odd-Even #2

a guest
Oct 9th, 2013
86
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
D 3.81 KB | None | 0 0
  1. module main;
  2.  
  3. import std.stdio;
  4. import std.algorithm;
  5. import std.conv;
  6.  
  7. struct cas_args {
  8.     int arg0 = -1;
  9.     int arg1 = -1;
  10. };
  11.  
  12. void print_network( const ref cas_args[][] cas_net )
  13. {
  14.     for( int i=0; i<cas_net.length; ++i ) {
  15.         for( int j=0; j<cas_net[i].length; ++j ) {
  16.             if( cas_net[i][j] != cas_args(-1,-1) ) {
  17.                 write( "cas(", cas_net[i][j].arg0, ", ", cas_net[i][j].arg1, ")" );
  18.             }
  19.         }
  20.         write("\n");
  21.     }
  22. }
  23.  
  24. // Ich bin mir nicht sicher, oder log2 garantiert, dass der nächste
  25. // ganze Wert entsteht, wenn man 2^N als Argument verwendet, oder
  26. // ob da auch einmal etwas echt kleineres als die ganze Zahl herauskommt
  27. // und dann abgerundet wird...
  28. int power2log( int N )
  29. {
  30.     int log=0;
  31.     while( N > 1 ) { N/=2; ++log; }
  32.     return log;
  33. }
  34.  
  35. int CalculateDepth( int N )
  36. {
  37.     int x = power2log(N);
  38.     return (x*(x+1))/2;
  39. }
  40.  
  41. // leider funktioniert "reserve" nicht zur compile-zeit
  42. // daher müssen die Elemente alle mit einem Spezial-Wert
  43. // gefüllt werden und immer nach dem ersten freien
  44. // gesucht werden (alternativ müsste man im ersten Element
  45. // die größe speichern, aber dann müssten alle Algorithmen
  46. // immer +1 ausschreiben...
  47. int FirstFree( const ref cas_args[] cas_list )
  48. {
  49.     for( int i=0; i<cas_list.length; ++i ) {
  50.         if( cas_list[i] != cas_args(-1,-1) ) return i;
  51.     }
  52.     return 0;
  53. }
  54.  
  55. void GenerateMerge( ref cas_args[][] cas_net, int base, int N, int stride=1, int offset=0)
  56. {
  57.     int index = FirstFree(cas_net[base]);
  58.     if( N > 2 ) {
  59.         GenerateMerge( cas_net, base-1, N/2, stride*2, offset );
  60.         GenerateMerge( cas_net, base-1, N/2, stride*2, offset+stride );
  61.         for( int i = 1; i <= N-3; i += 2 ) {
  62.             cas_net[base][index++] = cas_args(i*stride+offset,(i+1)*stride+offset);
  63.         }
  64.     } else  {
  65.         cas_net[base][index] = cas_args(offset,stride+offset);
  66.     }  
  67. }
  68.  
  69. void GenerateSort( ref cas_args[][] cas_net, int base, int N )
  70. {
  71.     if( N > 1 ) {
  72.         int thismerge = power2log(N);
  73.         // Oberen vorhergehenden Sort generieren
  74.         GenerateSort( cas_net, base-thismerge, N/2 );
  75.         // Unteren aus oberem erzeugen
  76.         for( int j=0; j<=base-thismerge; ++j ) {
  77.             for( int k=N/2; k<N; ++k ) {
  78.                 cas_net[j][k] = cas_net[j][k-N/2];
  79.                 if(cas_net[j][k]==cas_args(-1,-1)) continue;
  80.                 cas_net[j][k].arg0 += N/2;
  81.                 cas_net[j][k].arg1 += N/2;
  82.             }
  83.         }
  84.         // Merge-Netzwerk
  85.         GenerateMerge( cas_net, base, N );
  86.     }
  87. }
  88.  
  89. cas_args[][] GenerateNetwork(int N)
  90. {
  91.     int depth = CalculateDepth(N);
  92.     cas_args[][] result;
  93.     result.length = depth;
  94.     for( int i=0; i<depth; ++i ) {
  95.         result[i].length = N;
  96.     }
  97.  
  98.     GenerateSort( result, depth-1, N );
  99.     return result;
  100. }
  101.  
  102. string GenerateNetworkMixin( string arr, string op, int size )
  103. {
  104.     cas_args[][] network = GenerateNetwork( size );
  105.  
  106.     string result;
  107.  
  108.     string arg0;
  109.     string arg1;
  110.  
  111.     int pos = 0;
  112.  
  113.     // Diese Schleife zwingt den Compiler schnell in die Knie, offenbar
  114.     // bricht er lieber ab, bevor er swappen müsste, weil auf unterschiedlichen
  115.     // Rechner mit selbem Speicherausbau unterschiedliche Grenzen bestehen.
  116.     // Wenn man mehr will, sollte man irgendwie
  117.     // klug die Größe vorbestimmen (aber achtung, reserve funktioniert
  118.     // ja nicht) und dann nur noch mit dem Feld arbeiten. to!string
  119.     // müsste dann wahrscheinlich durch irgendein in-place-Algo
  120.     // ersetzt werden...
  121.     for( int i=0; i<network.length; ++i ) {
  122.         for( int j=0; j<network[i].length; ++j ) {
  123.             if( network[i][j] == cas_args(-1,-1) ) continue;
  124.             arg0 = arr~"["~to!string(network[i][j].arg0)~"]";
  125.             arg1 = arr~"["~to!string(network[i][j].arg1)~"]";
  126.             result ~= "if("~arg0~op~arg1~") swap("~arg0~","~arg1~");\n";
  127.             arg0.clear();
  128.             arg1.clear();
  129.         }
  130.     }
  131.  
  132.     return result;
  133. }
  134.  
  135. int main(string[] argv)
  136. {
  137.     int arr[512];
  138.     mixin(GenerateNetworkMixin("arr", ">", arr.length));
  139.     static cas_args[][] net = GenerateNetwork(4096); // -> 3 mb Netzwerkdatan plus minus
  140.     print_network( net );
  141.  
  142.     return 0;
  143. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement