Refactor basic alias types

This commit is contained in:
Balhau 2023-06-19 10:54:22 +01:00
parent 259496e8ea
commit dce40559d6
20 changed files with 538 additions and 482 deletions

View file

@ -1,3 +1,4 @@
#include "../src/engine/math/matrix3d.hpp"
#include "../src/engine/math/vector3d.hpp"
#include <iostream>
@ -11,10 +12,18 @@ int main() {
cout << v1 << endl;
cout << v2 << endl;
cout << v1 - v2 << endl;
cout << (v1 - v2) + v3 << endl;
cout << -v1 << endl;
cout << vector3d::Magnitude(v1) << endl;
cout << vector3d::Normalize(v1) << endl;
cout << vector3d::Magnitude(v3) << endl;
cout << vector3d::Normalize(v3) << endl;
engine::math::matrix3d m = engine::math::matrix3d();
engine::math::matrix3d id = matrix3d::Identity();
cout << m << endl;
cout << m[0][0] << endl;
cout << id << endl;
cout << id[0][0] << id[1][1] << id[2][2] << endl;
cout << id(0, 0) << id(0, 1) << id(0, 2) << endl;
}

View file

@ -1,9 +1,9 @@
#include <iostream>
#include <unistd.h>
#include "../src/cpu/utils.hpp"
#include "../src/cpu/x86/sse.hpp"
#include "../src/cpu/naive.hpp"
#include "../src/cpu/utils.hpp"
#include "../src/platform/timer.hpp"
#include <iostream>
#include <unistd.h>
using namespace cpu;
using namespace platform;
@ -11,128 +11,115 @@ using namespace std;
#define MAX_ITER 1000 * 1000 * 100
void naive128(UInt *v1_128, UInt *v2_128)
{
Timer t=Timer("Naive 128: ");
for (int i = 0; i < MAX_ITER; i++)
{
Naive::add_128(v1_128, v2_128);
}
void naive128(uint32 *v1_128, uint32 *v2_128) {
Timer t = Timer("Naive 128: ");
for (int i = 0; i < MAX_ITER; i++) {
Naive::add_128(v1_128, v2_128);
}
}
void int128(SSE *sse, UInt *v1_128, UInt *v2_128)
{
Timer t=Timer("SIMD(Byte) 256: ");
for (int i = 0; i < MAX_ITER; i++)
{
sse->add_128(v1_128, v2_128);
}
void int128(SSE *sse, uint32 *v1_128, uint32 *v2_128) {
Timer t = Timer("SIMD(Byte) 256: ");
for (int i = 0; i < MAX_ITER; i++) {
sse->add_128(v1_128, v2_128);
}
}
void long128(SSE *sse, ULong *v1_128_l, ULong *v2_128_l)
{
Timer t=Timer("SIMD(Byte) 256: ");
for (int i = 0; i < MAX_ITER; i++)
{
sse->add_128(v1_128_l, v2_128_l);
}
void long128(SSE *sse, uint64 *v1_128_l, uint64 *v2_128_l) {
Timer t = Timer("SIMD(Byte) 256: ");
for (int i = 0; i < MAX_ITER; i++) {
sse->add_128(v1_128_l, v2_128_l);
}
}
void byte128(SSE *sse, UChar *c1_128, UChar *c2_128)
{
Timer t=Timer("SIMD(Byte) 256: ");
for (int i = 0; i < MAX_ITER; i++)
{
sse->add_128(c1_128, c2_128);
}
void byte128(SSE *sse, uint8 *c1_128, uint8 *c2_128) {
Timer t = Timer("SIMD(Byte) 256: ");
for (int i = 0; i < MAX_ITER; i++) {
sse->add_128(c1_128, c2_128);
}
}
void naive256(UInt *v1_256, UInt *v2_256)
{
Timer t=Timer("Naive 256: ");
for (int i = 0; i < MAX_ITER; i++)
{
Naive::add_256(v1_256, v2_256);
}
void naive256(uint32 *v1_256, uint32 *v2_256) {
Timer t = Timer("Naive 256: ");
for (int i = 0; i < MAX_ITER; i++) {
Naive::add_256(v1_256, v2_256);
}
}
void int256(SSE *sse, UInt *v1_256, UInt *v2_256)
{
Timer t=Timer("SIMD(Byte) 256: ");
for (int i = 0; i < MAX_ITER; i++)
{
sse->add_256(v1_256, v2_256);
}
void int256(SSE *sse, uint32 *v1_256, uint32 *v2_256) {
Timer t = Timer("SIMD(Byte) 256: ");
for (int i = 0; i < MAX_ITER; i++) {
sse->add_256(v1_256, v2_256);
}
}
void long256(SSE *sse, ULong *v1_256, ULong *v2_256)
{
Timer t=Timer("SIMD(Byte) 256: ");
for (int i = 0; i < MAX_ITER; i++)
{
sse->add_256(v1_256, v2_256);
}
void long256(SSE *sse, uint64 *v1_256, uint64 *v2_256) {
Timer t = Timer("SIMD(Byte) 256: ");
for (int i = 0; i < MAX_ITER; i++) {
sse->add_256(v1_256, v2_256);
}
}
void byte256(SSE *sse, UChar *v1_256, UChar *v2_256)
{
Timer t=Timer("SIMD(Byte) 256: ");
for (int i = 0; i < MAX_ITER; i++)
{
sse->add_256(v1_256, v2_256);
}
void byte256(SSE *sse, uint8 *v1_256, uint8 *v2_256) {
Timer t = Timer("SIMD(Byte) 256: ");
for (int i = 0; i < MAX_ITER; i++) {
sse->add_256(v1_256, v2_256);
}
}
int main(int argc, char **argcv)
{
SSE sse = SSE();
int main(int argc, char **argcv) {
SSE sse = SSE();
UChar c1_128[CHAR_LEN_128] = {0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xA, 0xB, 0xC, 0xD, 0xE, 0xF, 0x10};
UChar c2_128[CHAR_LEN_128] = {0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xA, 0xB, 0xC, 0xD, 0xE, 0xF, 0x10};
uint8 c1_128[CHAR_LEN_128] = {0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8,
0x9, 0xA, 0xB, 0xC, 0xD, 0xE, 0xF, 0x10};
uint8 c2_128[CHAR_LEN_128] = {0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8,
0x9, 0xA, 0xB, 0xC, 0xD, 0xE, 0xF, 0x10};
UInt v1_128[INT_LEN_128] = {0x1, 0x2, 0x3, 0x4};
UInt v2_128[INT_LEN_128] = {0x1, 0x2, 0x3, 0x4};
uint32 v1_128[INT_LEN_128] = {0x1, 0x2, 0x3, 0x4};
uint32 v2_128[INT_LEN_128] = {0x1, 0x2, 0x3, 0x4};
ULong v1_128_l[LONG_LEN_128];
ULong v2_128_l[LONG_LEN_128];
uint64 v1_128_l[LONG_LEN_128];
uint64 v2_128_l[LONG_LEN_128];
UChar c1_256[CHAR_LEN_256] = {
0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xA, 0xB, 0xC, 0xD, 0xE, 0xF, 0x10,
0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xA, 0xB, 0xC, 0xD, 0xE, 0xF, 0x10};
uint8 c1_256[CHAR_LEN_256] = {0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8,
0x9, 0xA, 0xB, 0xC, 0xD, 0xE, 0xF, 0x10,
0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8,
0x9, 0xA, 0xB, 0xC, 0xD, 0xE, 0xF, 0x10};
UChar c2_256[CHAR_LEN_256] = {
0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xA, 0xB, 0xC, 0xD, 0xE, 0xF, 0x10,
0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xA, 0xB, 0xC, 0xD, 0xE, 0xF, 0x10};
uint8 c2_256[CHAR_LEN_256] = {0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8,
0x9, 0xA, 0xB, 0xC, 0xD, 0xE, 0xF, 0x10,
0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8,
0x9, 0xA, 0xB, 0xC, 0xD, 0xE, 0xF, 0x10};
UInt v1_256[INT_LEN_256] = {0x1, 0x2, 0x3, 0x4, 0x1, 0x2, 0x3, 0x4};
UInt v2_256[INT_LEN_256] = {0x1, 0x2, 0x3, 0x4, 0x1, 0x2, 0x3, 0x4};
uint32 v1_256[INT_LEN_256] = {0x1, 0x2, 0x3, 0x4, 0x1, 0x2, 0x3, 0x4};
uint32 v2_256[INT_LEN_256] = {0x1, 0x2, 0x3, 0x4, 0x1, 0x2, 0x3, 0x4};
ULong v1_256_l[LONG_LEN_256];
ULong v2_256_l[LONG_LEN_256];
uint64 v1_256_l[LONG_LEN_256];
uint64 v2_256_l[LONG_LEN_256];
Utils::int128ToLong(v1_128, v1_128_l);
Utils::int128ToLong(v2_128, v2_128_l);
Utils::int128ToLong(v1_128, v1_128_l);
Utils::int128ToLong(v2_128, v2_128_l);
Utils::int256ToLong(v1_256, v1_256_l);
Utils::int256ToLong(v2_256, v2_256_l);
Utils::int256ToLong(v1_256, v1_256_l);
Utils::int256ToLong(v2_256, v2_256_l);
sse.add_128(v1_128, v2_128);
sse.add_128(v1_128, v2_128);
long int start, end;
long int start, end;
Utils::printHex(v1_128, INT_LEN_128);
Utils::printHex(v2_128, INT_LEN_128);
Utils::printHex(v1_128, INT_LEN_128);
Utils::printHex(v2_128, INT_LEN_128);
Utils::printHex(v1_128_l, LONG_LEN_128);
Utils::printHex(v2_128_l, LONG_LEN_128);
Utils::printHex(v1_128_l, LONG_LEN_128);
Utils::printHex(v2_128_l, LONG_LEN_128);
naive128(v1_128, v2_128);
int128(&sse, v1_128, v2_128);
long128(&sse, v1_128_l, v2_128_l);
byte128(&sse, c1_128, c2_128);
naive128(v1_128, v2_128);
int128(&sse, v1_128, v2_128);
long128(&sse, v1_128_l, v2_128_l);
byte128(&sse, c1_128, c2_128);
naive256(v1_256, v2_256);
byte256(&sse, c1_256, c2_256);
int256(&sse, v1_256, v2_256);
long256(&sse, v1_256_l, v2_256_l);
}
naive256(v1_256, v2_256);
byte256(&sse, c1_256, c2_256);
int256(&sse, v1_256, v2_256);
long256(&sse, v1_256_l, v2_256_l);
}

View file

@ -3,7 +3,7 @@
/**
* Constructor implementation
*/
BMath::Complex::Complex(Double real, Double imaginary) {
BMath::Complex::Complex(int64 real, int64 imaginary) {
this->real = real;
this->imaginary = imaginary;
};
@ -37,7 +37,7 @@ BMath::Complex BMath::Complex::operator+(const Complex &rightOp) {
this->imaginary + rightOp.imaginary);
};
Int BMath::Complex::answer() { return this->real; }
int32 BMath::Complex::answer() { return this->real; }
BMath::Complex BMath::Complex::operator*(const Complex &rightOp) {
return Complex(

View file

@ -7,18 +7,18 @@ using namespace std;
namespace BMath {
class Complex {
private:
Double real;
Double imaginary;
int64 real;
int64 imaginary;
public:
Complex(Double real, Double imaginary);
Complex(int64 real, int64 imaginary);
Complex(const Complex &other);
Complex();
Complex &operator+=(const Complex &rightOp);
Complex operator+(const Complex &rightOp);
Complex operator-(const Complex &rigthOp);
Complex operator*(const Complex &rightOp);
Int answer();
int32 answer();
// Overload to enable toString operations
friend std::ostream &operator<<(std::ostream &stream,

View file

@ -1,74 +1,53 @@
#include "math.hpp"
//http://graphics.stanford.edu/~seander/bithacks.html
//https://hbfs.wordpress.com/2008/08/05/branchless-equivalents-of-simple-functions/
//access CHAR_BIT --> const with number of bits in a byte (usually 8)
#include <limits.h>
// http://graphics.stanford.edu/~seander/bithacks.html
// https://hbfs.wordpress.com/2008/08/05/branchless-equivalents-of-simple-functions/
// access CHAR_BIT --> const with number of bits in a byte (usually 8)
#include <iostream>
#include <limits.h>
#define C_API extern "C"
/**
* This will get the most significant bit of the Int value. If the most significant bit is 1 then the number is
* 0x11111111 --> equals to -1 integer
* This will get the most significant bit of the int32 value. If the most
* significant bit is 1 then the number is 0x11111111 --> equals to -1 integer
*/
Int msb(Int value)
{
return value >> (CHAR_BIT * sizeof(Int) - 1);
};
int32 msb(int32 value) { return value >> (CHAR_BIT * sizeof(int32) - 1); };
/**
* This version of msb2 avoids the use of bitwise operators by destructuring the datastructure
* with the help of union and struct trickery.
* We basically define a new Union datatype named SInt we use the structure int_with_msb as a way to de-structure
* the Int sint information.
* More on unions
* This version of msb2 avoids the use of bitwise operators by destructuring the
* datastructure with the help of union and struct trickery. We basically define
* a new Union datatype named Sint32 we use the structure int_with_msb as a way
* to de-structure the int32 sint information. More on unions
* https://www.geeksforgeeks.org/union-c/
*/
Int msb2(Int value)
{
SignedInt sint = {.signed_int = value};
int32 msb2(int32 value) {
s_int32 sint = {.signed_int = value};
return sint.int_with_msb.signal;
};
/**
*
*
*/
template <>
Int BMath::Math<Int>::abs(Int value)
{
template <> int32 BMath::Math<int32>::abs(int32 value) {
return (value ^ msb2(value)) - msb2(value);
};
template <>
Float BMath::Math<Float>::abs(Float value)
{
template <> float32 BMath::Math<float32>::abs(float32 value) {
return value > 0 ? value : -value;
};
template <>
Int BMath::Math<Int>::min(Int a, Int b)
{
template <> int32 BMath::Math<int32>::min(int32 a, int32 b) {
return b + ((a - b) & msb2(a - b));
}
template <>
Int BMath::Math<Int>::max(Int a, Int b)
{
template <> int32 BMath::Math<int32>::max(int32 a, int32 b) {
return a + ((b - a) & ~msb2(b - a));
}
/**
* Export as C API
*/
C_API Int c_msb(Int value)
{
return msb(value);
};
C_API int32 c_msb(int32 value) { return msb(value); };
C_API Int c_msb2(Int value)
{
return msb2(value);
}
C_API int32 c_msb2(int32 value) { return msb2(value); }

View file

@ -13,7 +13,7 @@ namespace cpu {
*/
class Clock {
public:
virtual ULong getTimestamp() = 0;
virtual uint64 getTimestamp() = 0;
virtual ~Clock() = default;
}; // namespace cpu
}; // namespace cpu

View file

@ -1,45 +1,43 @@
#include "naive.hpp"
#include <iostream>
void cpu::Naive::add_128(UInt *a, UInt *b)
{
ULong a1 = ((ULong)a[0] << 32) | a[1];
ULong a2 = ((ULong)a[2] << 32) | a[3];
ULong b1 = ((ULong)b[0] << 32) | b[1];
ULong b2 = ((ULong)b[2] << 32) | b[3];
void cpu::Naive::add_128(uint32 *a, uint32 *b) {
uint64 a1 = ((uint64)a[0] << 32) | a[1];
uint64 a2 = ((uint64)a[2] << 32) | a[3];
uint64 b1 = ((uint64)b[0] << 32) | b[1];
uint64 b2 = ((uint64)b[2] << 32) | b[3];
a1 = a1 + b1;
a2 = a2 + b2;
a1 = a1 + b1;
a2 = a2 + b2;
a[0] = (UInt)a1;
a[1] = (UInt)(a1 >> 32);
a[2] = (UInt)a2;
a[3] = (UInt)(a2 >> 32);
a[0] = (uint32)a1;
a[1] = (uint32)(a1 >> 32);
a[2] = (uint32)a2;
a[3] = (uint32)(a2 >> 32);
};
void cpu::Naive::add_256(UInt *a, UInt *b)
{
ULong a1 = ((ULong)a[0] << 32) | a[1];
ULong a2 = ((ULong)a[2] << 32) | a[3];
ULong a3 = ((ULong)a[4] << 32) | a[5];
ULong a4 = ((ULong)a[6] << 32) | a[7];
void cpu::Naive::add_256(uint32 *a, uint32 *b) {
uint64 a1 = ((uint64)a[0] << 32) | a[1];
uint64 a2 = ((uint64)a[2] << 32) | a[3];
uint64 a3 = ((uint64)a[4] << 32) | a[5];
uint64 a4 = ((uint64)a[6] << 32) | a[7];
ULong b1 = ((ULong)b[0] << 32) | b[1];
ULong b2 = ((ULong)b[2] << 32) | b[3];
ULong b3 = ((ULong)b[4] << 32) | b[5];
ULong b4 = ((ULong)b[6] << 32) | b[7];
uint64 b1 = ((uint64)b[0] << 32) | b[1];
uint64 b2 = ((uint64)b[2] << 32) | b[3];
uint64 b3 = ((uint64)b[4] << 32) | b[5];
uint64 b4 = ((uint64)b[6] << 32) | b[7];
a1 = a1 + b1;
a2 = a2 + b2;
a3 = a3 + b3;
a4 = a4 + b4;
a1 = a1 + b1;
a2 = a2 + b2;
a3 = a3 + b3;
a4 = a4 + b4;
a[0] = (UInt)a1;
a[1] = (UInt)(a1 >> 32);
a[2] = (UInt)a2;
a[3] = (UInt)(a2 >> 32);
a[4] = (UInt)a3;
a[5] = (UInt)(a3 >> 32);
a[6] = (UInt)a4;
a[7] = (UInt)(a4 >> 32);
a[0] = (uint32)a1;
a[1] = (uint32)(a1 >> 32);
a[2] = (uint32)a2;
a[3] = (uint32)(a2 >> 32);
a[4] = (uint32)a3;
a[5] = (uint32)(a3 >> 32);
a[6] = (uint32)a4;
a[7] = (uint32)(a4 >> 32);
};

View file

@ -1,13 +1,11 @@
#pragma once
#include "../platform/types.hpp"
namespace cpu
{
class Naive
{
public:
// Methods
static void add_128(UInt *a, UInt *b);
static void add_256(UInt *a, UInt *b);
};
};
namespace cpu {
class Naive {
public:
// Methods
static void add_128(uint32 *a, uint32 *b);
static void add_256(uint32 *a, uint32 *b);
};
}; // namespace cpu

View file

@ -2,46 +2,44 @@
#include "../platform/types.hpp"
namespace cpu
{
class SIMD
{
public:
/**
* @brief Add two packed 128 bits number (16 byte array)
* @param a 16 byte vector
* @param b 16 byte vector
*/
virtual void add_128(UChar *a, UChar *b) = 0;
/**
* @brief Add two packed 128 bits number (4 int array)
* @param a 4 int vector
* @param b 4 int vector
*/
virtual void add_128(UInt *a, UInt *b) = 0;
/**
* @brief Add two packed 128 bits number (2 long array)
* @param a 2 long vector
* @param b 2 long vector
*/
virtual void add_128(ULong *a, ULong *b) = 0;
/**
* @brief Add two packed 256 bits number (32 byte array)
* @param a 32 byte vector
* @param b 32 byte vector
*/
virtual void add_256(UChar *a, UChar *b) = 0;
/**
* @brief Add two packed 256 bits number (8 int array)
* @param a 8 int vector
* @param b 8 int vector
*/
virtual void add_256(UInt *a, UInt *b) = 0;
/**
* @brief Add two packed 256 bits number (4 long array)
* @param a 4 long vector
* @param b 4 long vector
*/
virtual void add_256(ULong *a, ULong *b) = 0;
};
};
namespace cpu {
class SIMD {
public:
/**
* @brief Add two packed 128 bits number (16 byte array)
* @param a 16 byte vector
* @param b 16 byte vector
*/
virtual void add_128(uint8 *a, uint8 *b) = 0;
/**
* @brief Add two packed 128 bits number (4 int array)
* @param a 4 int vector
* @param b 4 int vector
*/
virtual void add_128(uint32 *a, uint32 *b) = 0;
/**
* @brief Add two packed 128 bits number (2 long array)
* @param a 2 long vector
* @param b 2 long vector
*/
virtual void add_128(uint64 *a, uint64 *b) = 0;
/**
* @brief Add two packed 256 bits number (32 byte array)
* @param a 32 byte vector
* @param b 32 byte vector
*/
virtual void add_256(uint8 *a, uint8 *b) = 0;
/**
* @brief Add two packed 256 bits number (8 int array)
* @param a 8 int vector
* @param b 8 int vector
*/
virtual void add_256(uint32 *a, uint32 *b) = 0;
/**
* @brief Add two packed 256 bits number (4 long array)
* @param a 4 long vector
* @param b 4 long vector
*/
virtual void add_256(uint64 *a, uint64 *b) = 0;
};
}; // namespace cpu

View file

@ -1,70 +1,58 @@
#pragma once
#include <iostream>
#include "../platform/types.hpp"
#include <iostream>
using namespace std;
namespace cpu
{
class Utils
{
public:
template <typename Number>
static void printHex(Number *num, Int len)
{
for (int i = 0; i < len; i++)
{
cout << hex << num[i];
if (i < len - 1)
{
cout << ",";
}
}
cout << std::dec << endl;
};
static void printHex(UChar *num, Int len)
{
for (int i = 0; i < len; i++)
{
cout << hex << int(num[i]);
if (i < len - 1)
{
cout << ",";
}
}
cout << std::dec << endl;
}
namespace cpu {
class Utils {
public:
template <typename Number> static void printHex(Number *num, int32 len) {
for (int i = 0; i < len; i++) {
cout << hex << num[i];
if (i < len - 1) {
cout << ",";
}
}
cout << std::dec << endl;
};
static void printHex(uint8 *num, int32 len) {
for (int i = 0; i < len; i++) {
cout << hex << int(num[i]);
if (i < len - 1) {
cout << ",";
}
}
cout << std::dec << endl;
}
/**
* Utility method to convert a packaged 128bit int to 128bit long
*/
static void int128ToLong(UInt *packedUInteger, ULong *packedULong)
{
packedULong[0] = (ULong)packedUInteger[1] << 32 | packedUInteger[0];
packedULong[1] = (ULong)packedUInteger[3] << 32 | packedUInteger[2];
};
/**
* Utility method to convert a packaged 128bit int to 128bit long
*/
static void int128ToLong(uint32 *packedUInteger, uint64 *packedULong) {
packedULong[0] = (uint64)packedUInteger[1] << 32 | packedUInteger[0];
packedULong[1] = (uint64)packedUInteger[3] << 32 | packedUInteger[2];
};
static void int256ToLong(UInt *packedUInteger, ULong *packedULong)
{
packedULong[0] = (ULong)packedUInteger[1] << 32 | packedUInteger[0];
packedULong[1] = (ULong)packedUInteger[3] << 32 | packedUInteger[2];
packedULong[2] = (ULong)packedUInteger[5] << 32 | packedUInteger[4];
packedULong[3] = (ULong)packedUInteger[7] << 32 | packedUInteger[6];
}
static void int256ToLong(uint32 *packedUInteger, uint64 *packedULong) {
packedULong[0] = (uint64)packedUInteger[1] << 32 | packedUInteger[0];
packedULong[1] = (uint64)packedUInteger[3] << 32 | packedUInteger[2];
packedULong[2] = (uint64)packedUInteger[5] << 32 | packedUInteger[4];
packedULong[3] = (uint64)packedUInteger[7] << 32 | packedUInteger[6];
}
/**
* Utility method to convert a packed 128bit long into a 128 int
*/
static void long128ToInt(ULong *packedULong, UInt *packedUInteger)
{
// Unpack first long
packedUInteger[0] = packedULong[0] & MASK_32;
packedUInteger[1] = packedULong[0] >> SHIFT_32;
/**
* Utility method to convert a packed 128bit long into a 128 int
*/
static void long128ToInt(uint64 *packedULong, uint32 *packedUInteger) {
// Unpack first long
packedUInteger[0] = packedULong[0] & MASK_32;
packedUInteger[1] = packedULong[0] >> SHIFT_32;
// Unpack second long
packedUInteger[2] = packedULong[1] & MASK_32;
packedUInteger[3] = packedULong[1] >> SHIFT_32;
};
};
};
// Unpack second long
packedUInteger[2] = packedULong[1] & MASK_32;
packedUInteger[3] = packedULong[1] >> SHIFT_32;
};
};
}; // namespace cpu

View file

@ -16,8 +16,8 @@ cpu::X86Clock::~X86Clock() { print("Destructructor from X86Clock"); }
*
* @return ULong
*/
ULong cpu::X86Clock::getTimestamp() {
UInt hi, lo;
uint64 cpu::X86Clock::getTimestamp() {
uint32 hi, lo;
asmv("rdtsc" : "=a"(lo), "=d"(hi));
return ((unsigned long)lo) | ((unsigned long)hi << 32);
}

View file

@ -2,12 +2,11 @@
#include "../clock.hpp"
namespace cpu
{
class X86Clock: public Clock{
public:
X86Clock();
~X86Clock();
ULong getTimestamp();
};
};
namespace cpu {
class X86Clock : public Clock {
public:
X86Clock();
~X86Clock();
uint64 getTimestamp();
};
}; // namespace cpu

View file

@ -1,76 +1,62 @@
#include "sse.hpp"
#ifdef ARCH_X86
#include <iostream>
#include <iostream>
void cpu::SSE::add_128(UChar *a,UChar *b){
asmv(
"movdqa %0,%%xmm1\n"
"paddb %1,%%xmm1\n"
"movdqa %%xmm1,%0"
:"=m"(*a)
:"m"(*b)
);
}
void cpu::SSE::add_128(uint8 *a, uint8 *b) {
asmv("movdqa %0,%%xmm1\n"
"paddb %1,%%xmm1\n"
"movdqa %%xmm1,%0"
: "=m"(*a)
: "m"(*b));
}
//X86 Assembly to add two 128 bit numbers in the form of packed integers 32bit
void cpu::SSE::add_128(UInt *a,UInt *b) {
asmv(
"movdqa %0,%%xmm1\n"
"paddw %1,%%xmm1\n"
"movdqa %%xmm1, %0"
: "=m"(*a)
: "m"(*b)
);
};
// X86 Assembly to add two 128 bit numbers in the form of packed integers 32bit
void cpu::SSE::add_128(uint32 *a, uint32 *b) {
asmv("movdqa %0,%%xmm1\n"
"paddw %1,%%xmm1\n"
"movdqa %%xmm1, %0"
: "=m"(*a)
: "m"(*b));
};
// X86 Assembly to add two 128 bit numbers in the form of packed long 64bit
void cpu::SSE::add_128(uint64 *a, uint64 *b) {
asmv("movdqa %0,%%xmm1\n"
"paddd %1,%%xmm1\n"
"movdqa %%xmm1, %0"
: "=m"(*a)
: "m"(*b));
};
//X86 Assembly to add two 128 bit numbers in the form of packed long 64bit
void cpu::SSE::add_128(ULong *a,ULong *b) {
asmv(
"movdqa %0,%%xmm1\n"
"paddd %1,%%xmm1\n"
"movdqa %%xmm1, %0"
: "=m"(*a)
: "m"(*b)
);
};
// X86 Assembly to add two 256 bit numbers in the form of packed byte vector
void cpu::SSE::add_256(uint8 *a, uint8 *b) {
asmv("vmovdqu %0,%%ymm1\n"
"vmovdqu %1,%%ymm2\n"
"vpaddb %%ymm3,%%ymm2,%%ymm1\n"
"vmovdqu %%ymm1,%0"
: "=m"(*a)
: "m"(*b));
};
//X86 Assembly to add two 256 bit numbers in the form of packed byte vector
void cpu::SSE::add_256(UChar *a,UChar *b) {
asmv(
"vmovdqu %0,%%ymm1\n"
"vmovdqu %1,%%ymm2\n"
"vpaddb %%ymm3,%%ymm2,%%ymm1\n"
"vmovdqu %%ymm1,%0"
: "=m"(*a)
: "m"(*b)
);
};
// X86 Assembly to add two 256 bit numbers in the form of packed int 32bit
void cpu::SSE::add_256(uint32 *a, uint32 *b) {
asmv("vmovdqu %0,%%ymm1\n"
"vmovdqu %1,%%ymm2\n"
"vpaddw %%ymm1, %%ymm2, %%ymm1\n"
"vmovdqu %%ymm1,%0"
: "=m"(*a)
: "m"(*b));
};
//X86 Assembly to add two 256 bit numbers in the form of packed int 32bit
void cpu::SSE::add_256(UInt *a,UInt *b) {
asmv(
"vmovdqu %0,%%ymm1\n"
"vmovdqu %1,%%ymm2\n"
"vpaddw %%ymm1, %%ymm2, %%ymm1\n"
"vmovdqu %%ymm1,%0"
: "=m"(*a)
: "m"(*b)
);
};
//X86 Assembly to add two 256 bit numbers in the form of packed long 64bit
//Here we are using vmovdqu instead of vmovdqa because memory is not aligned.
void cpu::SSE::add_256(ULong *a,ULong *b) {
asmv(
"vmovdqu %0, %%ymm1\n"
"vmovdqu %1, %%ymm2\n"
"vpaddd %%ymm1,%%ymm2,%%ymm1\n"
"vmovdqu %%ymm1, %0"
: "=m"(*a)
: "m"(*b)
);
};
#endif
// X86 Assembly to add two 256 bit numbers in the form of packed long 64bit
// Here we are using vmovdqu instead of vmovdqa because memory is not aligned.
void cpu::SSE::add_256(uint64 *a, uint64 *b) {
asmv("vmovdqu %0, %%ymm1\n"
"vmovdqu %1, %%ymm2\n"
"vpaddd %%ymm1,%%ymm2,%%ymm1\n"
"vmovdqu %%ymm1, %0"
: "=m"(*a)
: "m"(*b));
};
#endif

View file

@ -3,19 +3,17 @@
#include "../../platform/platform.hpp"
#ifdef ARCH_X86
#include "../../platform/types.hpp"
#include "../simd.hpp"
namespace cpu
{
class SSE: public SIMD
{
public:
void add_128(UChar *a,UChar *b);
void add_128(UInt *a, UInt *b);
void add_128(ULong *a, ULong *b);
void add_256(UChar *a,UChar *b);
void add_256(UInt *a, UInt *b);
void add_256(ULong *a, ULong *b);
};
};
#endif
#include "../../platform/types.hpp"
#include "../simd.hpp"
namespace cpu {
class SSE : public SIMD {
public:
void add_128(uint8 *a, uint8 *b);
void add_128(uint32 *a, uint32 *b);
void add_128(uint64 *a, uint64 *b);
void add_256(uint8 *a, uint8 *b);
void add_256(uint32 *a, uint32 *b);
void add_256(uint64 *a, uint64 *b);
};
}; // namespace cpu
#endif

View file

@ -0,0 +1,80 @@
#include "matrix3d.hpp"
namespace engine::math {
void matrix3d::setFloatArray(const float32 m[3][3]) {
this->_m[0][0] = m[0][0];
this->_m[0][1] = m[0][1];
this->_m[0][2] = m[0][2];
this->_m[1][0] = m[1][0];
this->_m[1][1] = m[1][1];
this->_m[1][2] = m[1][2];
this->_m[2][0] = m[2][0];
this->_m[2][1] = m[2][1];
this->_m[2][2] = m[2][2];
};
void matrix3d::setAll(float32 v) {
this->_m[0][0] = v;
this->_m[0][1] = v;
this->_m[0][2] = v;
this->_m[1][0] = v;
this->_m[1][1] = v;
this->_m[1][2] = v;
this->_m[2][0] = v;
this->_m[2][1] = v;
this->_m[2][2] = v;
};
vector3d matrix3d::operator[](int i) {
float32 *row = this->_m[i];
return vector3d(*row, *(row + 1), *(row + 2));
};
float32 matrix3d::operator()(int row, int column) {
return this->_m[row][column];
};
matrix3d::matrix3d() { this->setAll(0); };
matrix3d::~matrix3d(){};
matrix3d::matrix3d(const matrix3d &m){};
matrix3d::matrix3d(const float32 m[3][3]) { this->setFloatArray(m); };
matrix3d::matrix3d(const vector3d r1, const vector3d r2, const vector3d r3) {
this->_m[0][0] = r1[0];
this->_m[0][1] = r1[1];
this->_m[0][2] = r1[2];
this->_m[1][0] = r2[0];
this->_m[1][1] = r2[1];
this->_m[1][2] = r2[2];
this->_m[2][0] = r3[0];
this->_m[2][1] = r3[1];
this->_m[2][2] = r3[2];
};
std::ostream &operator<<(std::ostream &stream, matrix3d const &m) {
stream << "matrix3d(" << std::endl;
stream << m._m[0][0] << "," << m._m[0][1] << "," << m._m[0][2] << std::endl;
stream << m._m[1][0] << "," << m._m[1][1] << "," << m._m[1][2] << std::endl;
stream << m._m[2][0] << "," << m._m[2][1] << "," << m._m[2][2] << std::endl;
stream << ")";
return stream;
};
matrix3d matrix3d::Identity() {
float32 id[3][3] = {{1, 0, 0}, {0, 1, 0}, {0, 0, 1}};
return matrix3d(id);
};
matrix3d operator+(const matrix3d &left, const matrix3d &right) {
MATRIX(m_temp);
m_temp[0][0];
return NULL;
};
} // namespace engine::math

View file

@ -0,0 +1,35 @@
#pragma once
#include "../../platform/base.hpp"
#include "vector3d.hpp"
#define MATRIX(n) float32 n[3][3]
namespace engine::math {
class matrix3d {
private:
MATRIX(_m);
void setFloatArray(const float32[3][3]);
void setAll(float32 v);
public:
// Default empty constructor
matrix3d();
~matrix3d();
static matrix3d Identity();
matrix3d(const float32[3][3]);
matrix3d(const vector3d r1, const vector3d r2, const vector3d r3);
// Constructor with matrix3d object
matrix3d(const matrix3d &m);
vector3d operator[](int i);
float32 operator()(int r, int c);
friend std::ostream &operator<<(std::ostream &stream,
engine::math::matrix3d const &m);
};
// Non instance operator overloading
matrix3d operator+(const matrix3d &left, const matrix3d &right);
matrix3d operator-(const matrix3d &left, const matrix3d &right);
}; // namespace engine::math

View file

@ -1,56 +1,57 @@
#include "vector3d.hpp"
#include <ostream>
using namespace engine::math;
using namespace std;
namespace engine::math {
vector3d::vector3d() = default;
vector3d::~vector3d() = default;
vector3d vector3d::operator+=(const vector3d &other) {
vector3d &vector3d::operator+=(const vector3d &other) {
this->x += other.x;
this->y += other.y;
this->z += other.z;
return (*this);
};
vector3d vector3d::operator-=(const vector3d &other) {
vector3d &vector3d::operator-=(const vector3d &other) {
this->x -= other.x;
this->y -= other.y;
this->z -= other.z;
return (*this);
};
vector3d vector3d::operator+(const vector3d &other) {
return vector3d(this->x + other.x, this->y + other.y, this->z + other.z);
}
vector3d vector3d::operator-(const vector3d &other) {
return vector3d(this->x - other.x, this->y - other.y, this->z - other.z);
};
}
vector3d vector3d::operator-() {
return vector3d(-this->x, -this->y, -this->z);
};
vector3d vector3d::operator/(const Float scalar) {
Float inv = 1 / scalar;
vector3d vector3d::operator/(const float32 scalar) {
float32 inv = 1 / scalar;
return vector3d(this->x * inv, this->y * inv, this->z * inv);
};
vector3d::vector3d(Float _x, Float _y, Float _z) {
vector3d::vector3d(float32 _x, float32 _y, float32 _z) {
this->x = _x;
this->y = _y;
this->z = _z;
};
Float vector3d::Magnitude(const vector3d &v) {
float32 vector3d::Magnitude(const vector3d &v) {
return sqrt((v.x * v.x + v.y * v.y + v.z * v.z));
};
vector3d vector3d::Normalize(vector3d &v) { return v / vector3d::Magnitude(v); }
Float &vector3d::operator[](int i) { return (&this->x)[i]; };
const Float &engine::math::vector3d::operator[](int i) const {
float32 &vector3d::operator[](int i) { return (&this->x)[i]; };
const float32 &engine::math::vector3d::operator[](int i) const {
return (&this->x)[i];
};

View file

@ -1,8 +1,7 @@
#pragma once
#include "../../platform/types.hpp"
#include "../../platform/base.hpp"
#include <cmath>
#include <iostream>
using namespace std;
@ -12,7 +11,7 @@ namespace engine::math {
*/
class vector3d {
private:
Float x, y, z;
float32 x, y, z;
public:
// Default constructor;
@ -22,7 +21,7 @@ public:
* Constructor with (x,y,z) passed as parameters
*
* */
vector3d(Float _x, Float _y, Float _z);
vector3d(float32 _x, float32 _y, float32 _z);
friend std::ostream &operator<<(std::ostream &stream,
engine::math::vector3d const &v);
@ -32,17 +31,18 @@ public:
* This enable to access x,y,z in a index form like v[0], v[1], v[2]
* respectively
*/
Float &operator[](int i);
float32 &operator[](int i);
const Float &operator[](int i) const;
const float32 &operator[](int i) const;
vector3d operator+=(const vector3d &other);
vector3d operator-=(const vector3d &other);
vector3d operator/(const Float scalar);
vector3d &operator+=(const vector3d &other);
vector3d &operator-=(const vector3d &other);
vector3d operator+(const vector3d &other);
vector3d operator-(const vector3d &other);
vector3d operator/(const float32 scalar);
vector3d operator-();
static Float Magnitude(const vector3d &v);
static float32 Magnitude(const vector3d &v);
static vector3d Normalize(vector3d &v);
~vector3d();
};

5
src/platform/base.hpp Normal file
View file

@ -0,0 +1,5 @@
#pragma once
#include "platform.hpp"
#include "types.hpp"
#include <ostream>

View file

@ -5,90 +5,85 @@
* Types for x86 architectures
*/
#ifdef ARCH_X86_64
// Signed type alias
typedef int Int;
typedef long Long;
typedef char Char;
typedef short Short;
// Signed type alias
typedef int int32;
typedef long int64;
typedef char int8;
typedef short int16;
typedef union
{
struct
{
Int value : 31;
Int signal : 1;
} int_with_msb;
Int signed_int;
} SignedInt;
typedef union {
struct {
int32 value : 31;
int32 signal : 1;
} int_with_msb;
typedef union
{
struct
{
Long value : 63;
Int signal : 1;
} long_with_msb;
} SignedLong;
int32 signed_int;
} s_int32;
// IEEE floating point alias
typedef float Float;
typedef double Double;
typedef union {
struct {
int64 value : 63;
int32 signal : 1;
} long_with_msb;
} s_int64;
// Unsigned type alias
typedef unsigned char UChar;
typedef unsigned short UShort;
typedef unsigned int UInt;
typedef unsigned long int ULong;
// IEEE floating point alias
typedef float float32;
typedef double float64;
// SSE DataTypes
#define CHAR_LEN_128 16
#define CHAR_LEN_256 32
// Unsigned type alias
typedef unsigned char uint8;
typedef unsigned short uint16;
typedef unsigned int uint32;
typedef unsigned long int uint64;
#define INT_LEN_64 2
#define INT_LEN_128 4
#define INT_LEN_256 8
#define INT_LEN_512 16
// SSE DataTypes
#define CHAR_LEN_128 16
#define CHAR_LEN_256 32
#define LONG_LEN_64 1
#define LONG_LEN_128 2
#define LONG_LEN_256 4
#define LONG_LEN_512 8
#define INT_LEN_64 2
#define INT_LEN_128 4
#define INT_LEN_256 8
#define INT_LEN_512 16
// Masks
#define MASK_32 0xFFFFFFFF
#define MASK_16 0xFFFF
#define MASK_8 0xFF
#define LONG_LEN_64 1
#define LONG_LEN_128 2
#define LONG_LEN_256 4
#define LONG_LEN_512 8
// Shifts
#define SHIFT_32 32
#define SHIFT_16 16
#define SHIFT_8 8
// Masks
#define MASK_32 0xFFFFFFFF
#define MASK_16 0xFFFF
#define MASK_8 0xFF
// Shifts
#define SHIFT_32 32
#define SHIFT_16 16
#define SHIFT_8 8
#endif
#ifdef ARCH_X86_32
typedef int Int;
typedef char Char;
typedef short Short;
typedef int Int;
typedef char Char;
typedef short Short;
//64bit Long do not exist at cpu level
//emulate this via struct
typedef struct Long
{
Int high;
Int lo;
} Long;
// 64bit Long do not exist at cpu level
// emulate this via struct
typedef struct Long {
Int high;
Int lo;
} Long;
// Unsigned type alias
typedef unsigned char UChar;
typedef unsigned short UShort;
typedef unsigned int UInt;
//64bit unsigned long do not exist at cpu level
//emulate this via struct
typedef struct ULong {
UInt high;
UInt low;
} ULong;
// Unsigned type alias
typedef unsigned char UChar;
typedef unsigned short UShort;
typedef unsigned int UInt;
// 64bit unsigned long do not exist at cpu level
// emulate this via struct
typedef struct ULong {
UInt high;
UInt low;
} ULong;
#endif