Features
What's New
Download
Support
 

    Using Exentia

    Include the unit Exentia.pas in your project, then create instances of the TFVector class using 

    class function BuildVector(const ALength : integer) : TFVector;

    Never create instances using constructors (i.e. MyVector := TSSEVector.Create(MySize);) as it would force the usage of a specific instruction set!
    You can clone an existing vector by using:

    class function CopyVector(const V : TFVector) : TFVector;

    You can read and write single data elements using the Data property (being the default property, you can also use the simpler MyDataValue := MyVector[index] syntax).
    Each vector allocates the memory required to hold ALength 32-bit floating point values on 16-bytes boundaries so that memory access is optimal.
    Please note that ALength must be a multiple of 4, otherwise it will be rounded up during vector construction.
    Here is the definition of the TFVector class:

    type
      TFVector = class(TObject)
      private
        AlignedArray : PSingleArray;
        AllocatedArray : pointer;
        NumElements : integer;
        function GetDataElement(index : integer) : single;
        procedure SetDataElement(index : integer; const value : single);
      public
        property DataArray : PSingleArray read AlignedArray;
        property Data[index : integer] : single read GetDataElement write SetDataElement; default;
        constructor Create(const ALength : integer);
        constructor Copy(const V : TFVector); // Self = V
        destructor Destroy;override;
        class function BuildVector(const ALength : integer) : TFVector;
        class function CopyVector(const V : TFVector) : TFVector;
        class function isSSE : boolean;
        class function is3DNow : boolean;
        procedure SetLength(const ALength : integer);
        procedure ImportArray(const Source : PSingleArray; const Length : integer = 0);
        procedure ExportArray(Destination : PSingleArray; const Length : integer = 0);
        procedure ClearArray; // Self = 0
        procedure SetArray(value : single);  // Self[i] = value
        // basic operations
        procedure Add(V : TFVector); virtual; abstract;  // Self = Self + V
        procedure Sub(V : TFVector); virtual; abstract;  // Self = Self - V
        procedure Mul(V : TFVector); virtual; abstract;  // Self = Self * V
        procedure Divide(V : TFVector); virtual; abstract;  // Self = Self / V
        procedure Sqrt(V : TFVector); virtual; abstract;  // Self = Sqrt(V)
        procedure Reciprocal(V : TFVector); virtual; abstract;  // Self = 1 / V
        procedure RecSqrt(V : TFVector); virtual; abstract;  // Self = 1 / Sqrt(V)
        procedure Max(V : TFVector); virtual; abstract;  // Self = Max(Self, V)
        procedure Min(V : TFVector); virtual; abstract;  // Self = Min(Self, V)
        procedure LogicalAnd(V : TFVector); virtual; abstract;  // Self = Self and V
        procedure LogicalOr(V : TFVector); virtual; abstract;   // Self = Self or V
        procedure LogicalXor(V : TFVector); virtual; abstract;  // Self = Self xor V
        procedure CmpGreater(V : TFVector); virtual; abstract;       // Self = Self > V
        procedure CmpLower(V : TFVector); virtual; abstract;         // Self = Self < V
        procedure CmpEqual(V : TFVector); virtual; abstract;         // Self = Self == V
        procedure CmpGreaterEqual(V : TFVector); virtual; abstract;  // Self = Self >= V
        procedure CmpLowerEqual(V : TFVector); virtual; abstract;    // Self = Self <= V
        // complex operations
        procedure AddSquare(V : TFVector); virtual; abstract;   // Self = Self + V^2
        function InnerSum : single; virtual; abstract;  // result = Sum(Self[i])
        function InnerSumAbs : single; virtual; abstract;  // result = Sum(abs(Self[i]))
        function DotProduct(V : TFVector) : single; virtual; abstract;  // result = Sum(Self[i] * V[i])
        function MaxValue : single; virtual; abstract;  // result = Max(Self[i])
        function MaxAbsValue : single; virtual; abstract;  // result = Max(abs(Self[i]))
        function IndexMaxValue : integer; virtual; abstract;  // result = index of Max(Self)
        function MinValue : single; virtual; abstract;  // result = Min(Self[i])
        function MinAbsValue : single; virtual; abstract;  // result = Min(abs(Self[i]))
        function IndexMinValue : integer; virtual; abstract;  // result = index of Min(Self)
        function Mean : single; virtual; abstract;  // result = Sum(Self[i]) / NumElements
        procedure Scale(value : single); virtual; abstract;  // Self = value * Self 
      end;

    TFVector defines an abstract interface which is implemented in the derived classes: TX87Vector, TSSEVector and T3DNowVector. When creating a vector, the BuildVector class function checks the instruction sets supported by the current CPU and creates the top-performing instance, i.e.

    • TSSEVector on Intel Pentium III and Celeron II processors
    • T3DNowVector on AMD K6-2, K6-III, Athlon and Duron processors
    • TX87Vector on older processors
    The derived classes implement all abstract methods.

    Update! The new Exentia64 extensions lets you use both x87 and Intel SSE2 instructions to process 64-bit floating point data vectors. Just include the Exentia64 unit, and use the TFVector64 object as base class, and you're ready to reap the benefits of the Pentium 4 processor! Many thanks to Tom Womack and Chris Rorden for coding and testing these extensions!

    Update! The new SIMD extensions lets you use Exentia SSE code with previously unsupported Delphi release (5 and below)! Click here to download the SIMD DLL and the import class. Many thanks to Uwe Rossek for designing and coding it!


    Click here for the current status of this library.
     
     

Copyright Stefano Tommesani 2000/03 - All trademarks belong to their respective holders