Advertisement
Guest User

Untitled

a guest
Dec 4th, 2016
90
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 2.01 KB | None | 0 0
  1. #include <xmmintrin.h>
  2. #include "mandelbrot.h"
  3.  
  4. // mandelbrot() takes a set of SIZE (x,y) coordinates - these are actually
  5. // complex numbers (x + yi), but we can also view them as points on a plane.
  6. // It then runs 200 iterations of f, using the (x,y) point, and checks
  7. // the magnitude of the result.  If the magnitude is over 2.0, it assumes
  8. // that the function will diverge to infinity.
  9.  
  10. // vectorize the below code using SIMD intrinsics
  11. int *
  12. mandelbrot_vector(float x[SIZE], float y[SIZE]) {
  13.    static int ret[SIZE];
  14.    __m128 x1, y1, x2, y2, X1SQUARED, Y1SQUARED, otherX1SQUARED, otherY1SQUARED, comparison, xati, yati, subval, addsquares, xmuly;
  15.  
  16.    comparison = _mm_set1_ps(M_MAG *M_MAG);
  17.  
  18.    for (int i = 0 ; i < SIZE ; i +=4) {
  19.       x1 = _mm_set1_ps(0.0);
  20.       y1 = _mm_set1_ps(0.0);
  21.       xati = _mm_loadu_ps(&x[i]);
  22.       yati = _mm_loadu_ps(&y[i]);
  23.       // Run M_ITER iterations
  24.       for (int j = 0 ; j < M_ITER ; j ++) {
  25.          // Calculate the real part of (x1 + y1 * i)^2 + (x + y * i)
  26.          X1SQUARED = _mm_mul_ps(x1, x1);
  27.          Y1SQUARED = _mm_mul_ps(y1, y1);
  28.          subval = _mm_sub_ps(X1SQUARED, Y1SQUARED);
  29.          x2 = _mm_add_ps(xati, subval);
  30.  
  31.          //x2 = (x1 * x1) - (y1 * y1) + x[i];
  32.  
  33.          // Calculate the imaginary part of (x1 + y1 * i)^2 + (x + y * i)
  34.  
  35.          xmuly = _mm_mul_ps(x1, y1);
  36.          y2 = _mm_add_ps(yati, _mm_add_ps(xmuly, xmuly));
  37.          
  38.          //y2 = 2 * (x1 * y1) + y[i];
  39.  
  40.          // Use the new complex number as input for the next iteration
  41.          x1 = x2;
  42.          y1 = y2;
  43.       }
  44.  
  45.       otherX1SQUARED = _mm_mul_ps(x2, x2);
  46.       otherY1SQUARED = _mm_mul_ps(y2, y2);
  47.       addsquares = _mm_add_ps(otherX1SQUARED, otherY1SQUARED);
  48.       _mm_storeu_ps((float *)&ret[i], _mm_cmplt_ps(addsquares, comparison));
  49.       // caculate the magnitude of the result
  50.       // We could take the square root, but instead we just
  51.       // compare squares
  52.       //ret[i] = ((x2 * x2) + (y2 * y2)) < (M_MAG * M_MAG);
  53.    }
  54.  
  55.    return ret;
  56. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement