TS-4800 FPU Usage

From Technologic Systems Manuals

The ARM Cortex-A8 Neon floating point unit can produce significant performance increases when properly implemented. The example below should be compiled thus:
g++ fpudemo.cpp -o mandel -march=armv7-a -mtune=cortex-a8 -mfpu=neon -ftree-vectorize -mfloat-abi=softfp -ffast-math

// TS-4800 Math demo
// Written by Michael D. Peters for Technologic Systems, Inc.
//
// The goal of this exercise is to demonstrate use of
// floating point math on the TS-4800.  We will do this by
// generating a mandelbrot set.
//
// can output a csv in the format x,y,value.
// 
// Since the libraries included with the TS-4800 are all compiled
// for soft-float, all mathematics in this project will be
// done without the aid of library functions.

#include <iostream>
using std::cout;

#define XGRIDMAX 1024
#define YGRIDMAX 1024
float scalarX(int, int);
float scalarY(int, int);

// Software entry point.
int main()
{
  float grid[XGRIDMAX][YGRIDMAX] = {0};
  int a,b,i = 0;
  float x0, y0, t, x, y;

  // for each cell do:
  for(a=0; a < XGRIDMAX; a++){
    for(b=0; b < YGRIDMAX; b++){
      // setup iteration
      x = y = i = 0; 
      x0 = scalarX(a, XGRIDMAX);
      y0 = scalarY(b, YGRIDMAX);
 
      while((x*x + y*y < 4) && i < 1000){
        t = x*x - y*y + x0;
        y = 2 * x * y + y0;
        x = t;
        i = i + 1;
      }
      grid[a][b]=i;
    //  This will provide a comma delimited list of results
    //  in case producing a graphic output is desired.
    //  format:  x,y,val,x,y,val,x,y,val,...
    //  cout << a << ',' << b << ',' << i << ',';
    }
  }
  return 0;
}

// The X position must be a scalar between -2.5 and +1.
// x is the literal pixel position
// maxX is the value to scale against.
float scalarX(int x, int maxX)
{
  float x0;
  // Error check.
  if(maxX == 0) return 0;

  // First, the total distance from -2.5 and 1 is 3.5 units.
  // We must find the size of the divisions between 0 and 3.5
  // for the number of units represented by maxX.
  x0 = 3.5/(float)maxX;

  // Next, scale x down to the approprate unit.
  x0 = (float)x * x0;

  // Finally, offset the return value into the expected range.
  x0 = x0 - 2.5;

  return x0;
}

// The Y position must be a scalar between -1 and 1.
// y is the literal pixel position
// maxY is the value to scale against.
float scalarY(int y, int maxY)
{
  float y0;
  // Error check.
  if(maxY == 0) return 0;

  // First, how many units are there between 0 and 2?
  y0 = (float) 2/maxY;
  
  // Next, scale y down to y0 size.
  y0 = (float) y * y0;

  // Finally, shift y0 into range.
  y0 = y0 - 1;

  return y0;
}