Guest User

Mandel + Mandel custom FPU code

a guest
Nov 19th, 2016
164
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 5.10 KB | None | 0 0
  1. // test.cpp
  2. #include <stdio.h>
  3. #include <time.h>
  4.  
  5. int mandel(double x, double y, int max_iters)
  6. {
  7.     double  a, b, a2;
  8.     int     iter;
  9.  
  10.     a = 0.0;
  11.     b = 0.0;
  12.     for (iter = 0; iter < max_iters; iter++)
  13.     {
  14.         a2 = (a*a - b*b) + x;
  15.         b = 2.0*a*b + y;
  16.         a = a2;
  17.         if (a*a + b*b >= 4.0)
  18.         {
  19.             max_iters = iter;
  20.             break;
  21.         }
  22.     }
  23.     return max_iters;
  24. }
  25.  
  26. int mandel_custom(double x, double y, int max_iters)
  27. {
  28.     double  result;
  29.     int     iter, two;
  30.  
  31.  
  32.     two = 2;
  33.     _asm {
  34.         // Set computation to 64-bit
  35.         fldz                    // st0=a                                        // push a
  36.         fldz                    // st0=b, st1=a                                 // push b
  37.         fild    two             // st0=2, st1=b, st2=a                          // push 2
  38.         fld     x               // st0=x, st1=2, st2=b, st3=a                   // push x
  39.         fld     y               // st0=y, st1=x, st2=2, st3=b, st4=a            // push y
  40.  
  41.         // Compute initial a2 value (we know a and b are 0)
  42.         // a2 = (a*a - b*b) + x;
  43.         fld     st(1)           // st0=a2, st1=y, st2=x, st3=2, st4=b, st5=a
  44.     }
  45.  
  46.     for (iter = 0; iter < max_iters; iter++)
  47.     {
  48.         // Note:  Top-level entry of this loop:  st0=y, st1=x, st2=2, st3=b, st4=a
  49.         _asm {
  50.             // st0=a2
  51.  
  52.             // b = 2.0*a*b + y;
  53.             fld     st(5)           // st0=a, st1=a2,               st2=y, st3=x, st4=2, st5=b, st6=a
  54.             fmul    st(0),st(4)     // st0=2*a, st1=a2,             st2=y, st3=x, st4=2, st5=b, st6=a
  55.             fmul    st(0),st(5)     // st0=2*a*b, st1=a2,           st2=y, st3=x, st4=2, st5=b, st6=a
  56.             fadd    st(0),st(2)     // st0=(2*a*b)+y, st1=a2,       st2=y, st3=x, st4=2, st5=b, st6=a
  57.             fst     st(5)           // st0=b, st1=a2,               st2=y, st3=x, st4=2, st5=b, st6=a
  58.             // st0=b
  59.  
  60.             // b*b
  61.             fmul    st(0),st(0)     // st0=b*b, st1=a2,             st2=y, st3=x, st4=2, st5=b, st6=a
  62.             fld     st(0)           // st0=b*b, st1=b*b, st2=a2,    st3=y, st4=x, st5=2, st6=b, st7=a
  63.  
  64.             // a = a2
  65.             fxch    st(2)           // st0=a2, st1=b*b, st2=b*b,    st3=y, st4=x, st5=2, st6=b, st7=a
  66.             fst     st(7)
  67.             // st0=a
  68.  
  69.             // if (a*a + b*b >= 4.0)
  70.             // a*a
  71.             fmul    st(0),st(0)     // st0=a*a, st1=b*b, st2=b*b,           st3=y, st4=x, st5=2, st6=b, st7=a
  72.             fsubr   st(2),st(0)     // st0=a*a, st1=b*b, st2=(a*a - b*b),   st3=y, st4=x, st5=2, st6=b, st7=a
  73.             faddp   st(1),st(0)     // st0=(a*a + b*b), st1=(a*a - b*b),    st2=y, st3=x, st4=2, st5=b, st6=a
  74.             fstp    result          // st0=(a*a - b*b),                     st1=y, st2=x, st3=2, st4=b, st5=a
  75.  
  76.             // Pre-compute a2 for inner loop
  77.             // a2 = (a*a - b*b) + x;
  78.             fadd    st(0),st(2)     // st0=(a*a - b*b) + x,     st1=y, st2=x, st3=2, st4=b, st5=a
  79.             // st0=a2
  80.         }
  81.         if (result >= 4.0)
  82.         {
  83.             max_iters = iter;
  84.             break;
  85.         }
  86.     }
  87.  
  88.     // Clean the fpu stack
  89.     _asm {
  90.         // st0=a2 st1=y, st2=x, st3=2, st4=b, st5=a
  91.         // Reset FPU
  92.         fstp    st(0)       // stx=a2, st0=y, st1=x, st2=2, st3=b, st4=a        // pop a2
  93.         fstp    st(0)       // stx=a2, stx=y, st0=x, st1=2, st2=b, st3=a        // pop y
  94.         fstp    st(0)       // stx=a2, stx=y, stx=x, st0=2, st1=b, st2=a        // pop x
  95.         fstp    st(0)       // stx=a2, stx=y, stx=x, stx=2, st0=b, st1=a        // pop 2
  96.         fstp    st(0)       // stx=a2, stx=y, stx=x, stx=2, stx=b, st0=a        // pop b
  97.         fstp    st(0)       // stx=a2, stx=y, stx=x, stx=2, stx=b, stx=a        // pop a
  98.     }
  99.  
  100.     return max_iters;
  101. }
  102.  
  103. int main(int argc, char* argv[])
  104. {
  105.     int         lnI, max, max_custom;
  106.     double      x, y, step_x, step_y, x_min, x_max, y_min, y_max;
  107.     clock_t     start, end, start_custom, end_custom;
  108.  
  109.  
  110.     // Initialize
  111.     x_min   = -3.0;         x_max   = 2.0;
  112.     y_min   = -2.0;         y_max   = 2.0;
  113.     step_x  = +0.0005;      step_y  = +0.0005;
  114.  
  115.     // Iterate through the rectangle
  116.     start = clock();
  117.     for (lnI = 0; lnI < 5; lnI++)
  118.     {
  119.         max = 0;
  120.         for (x = x_min; x < x_max; x += step_x)
  121.             for (y = y_min; y < y_max; y += step_y)
  122.                 max += mandel(x, y, 40);
  123.  
  124.     }
  125.     end = clock();
  126.  
  127.     // Iterate through the rectangle
  128.     start_custom = clock();
  129.     for (lnI = 0; lnI < 5; lnI++)
  130.     {
  131.         max_custom = 0;
  132.         for (x = x_min; x < x_max; x += step_x)
  133.             for (y = y_min; y < y_max; y += step_y)
  134.                 max_custom += mandel_custom(x, y, 40);
  135.  
  136.     }
  137.     end_custom = clock();
  138.  
  139.     printf("Max       : %d, time: %lf\n", max, (double)(end - start) / (lnI * CLOCKS_PER_SEC));
  140.     printf("Max custom: %d, time: %lf\n", max_custom, (double)(end_custom - start_custom) / (lnI * CLOCKS_PER_SEC));
  141.  
  142.     _asm int 3;     // Injected to cause it to stop even in release mode
  143.     return 0;
  144. }
Advertisement
Add Comment
Please, Sign In to add comment