Overall codebase refactor

This commit is contained in:
Vitor Fernandes 2020-07-07 15:13:45 +01:00
parent eabc20a2e3
commit ba95c0fced
No known key found for this signature in database
GPG key ID: EBFB4EE09F348A26
33 changed files with 461 additions and 432 deletions

1
.gitignore vendored
View file

@ -1,6 +1,7 @@
bin/ bin/
*.dis *.dis
*.o *.o
*.dylib
.kdev4/ .kdev4/
.vscode/ .vscode/
CMakeFiles/ CMakeFiles/

View file

@ -6,23 +6,6 @@ set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin) set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)
add_subdirectory(src) add_subdirectory(src)
add_executable(cpplab main.cpp) #add_executable(c_time time.cpp)
add_executable( #install(TARGETS cpplab RUNTIME DESTINATION bin)
sse
src/core/cpu/sse.cpp
src/core/cpu/naive.cpp
src/core/cpu/avx2.cpp
src/core/bmath/complex.cpp
sse.cpp
)
add_executable(
complex
src/core/bmath/complex.cpp
complex.cpp
)
add_executable(c_time time.cpp)
install(TARGETS cpplab RUNTIME DESTINATION bin)

View file

@ -1,20 +0,0 @@
#include <iostream>
#include <string>
#include <iomanip>
#include <sys/time.h>
#include "src/core/bmath/complex.hpp"
using namespace Core::Bmath;
using namespace std;
int main(int argc, char** argcv){
Complex c1(1,1);
Complex c2(2,2);
Complex c3=c1*c2;
Complex c4=c1+c2;
cout << c1 << "*" << c2 << "=" << c3 << endl;
cout << c1 << "+" << c2 << "=" << c4 << endl;
}

View file

@ -1,43 +0,0 @@
#include <iostream>
#include "src/core/blist.hpp"
#include "src/core/cpu/avx2.hpp"
#include <string>
#include <iomanip>
using namespace Core::Cpu;
int main(int argc, char **argv) {
blist<int> list = blist<int>();
std::cout << "List size: " << list.getSize() <<std::endl;
list.add(1);
list.add(2);
std::cout << "List size: " << list.getSize() << std::endl;
std::cout << "Current value: " << list.current()->value << std::endl;
int *values = list.values();
for(int i=0;i<list.getSize();i++){
std::cout << "Value: " << values[i] << std::endl;
}
//node<int> n = node<int>(2);
//std::cout << "Hello node: " << ni->value << endl;
/*
std::cout << "Hello node: " << ni->value << endl;
std::cout << "Hello, world!" << std::endl;
std::cout << "Hello Blist: " << "Hello" << std::endl;
//Template structs
struct node<std::string> stringNode;
stringNode.value = std::string("Hello Master");
std::cout << stringNode.value << std::endl;
*/
return 0;
}

View file

@ -1,3 +1,5 @@
add_subdirectory(core) add_subdirectory(bmath)
add_subdirectory(cpu)
add_subdirectory(dtstruct)
add_subdirectory(opengl) add_subdirectory(opengl)
add_subdirectory(misc) add_subdirectory(misc)

10
src/bmath/CMakeLists.txt Normal file
View file

@ -0,0 +1,10 @@
add_library(
bmath SHARED
complex.cpp
)
add_executable(
complex
demos/complex.cpp
complex.cpp
)

48
src/bmath/complex.cpp Normal file
View file

@ -0,0 +1,48 @@
#include "complex.hpp"
/**
* Constructor implementation
*/
BMath::Complex::Complex(Double real, Double imaginary)
{
this->real = real;
this->imaginary = imaginary;
};
BMath::Complex::Complex(const Complex &other)
{
this->real = other.real;
this->imaginary = other.imaginary;
}
/**
* Add complex number
*/
BMath::Complex &BMath::Complex::operator+=(const Complex &rightOp)
{
this->real += rightOp.real;
this->imaginary += rightOp.imaginary;
return *this;
};
BMath::Complex BMath::Complex::operator-(const Complex &rightOp)
{
return Complex(
this->real-rightOp.real,
this->imaginary-rightOp.imaginary
);
};
BMath::Complex BMath::Complex::operator+(const Complex &rightOp)
{
return Complex(
this->real + rightOp.real,
this->imaginary + rightOp.imaginary);
};
BMath::Complex BMath::Complex::operator*(const Complex &rigthOp)
{
return Complex(
this->real * rigthOp.real - this->imaginary * rigthOp.imaginary,
this->imaginary * rigthOp.real + this->real * rigthOp.imaginary);
};

29
src/bmath/complex.hpp Normal file
View file

@ -0,0 +1,29 @@
#pragma once
#include "../cpu/types.hpp"
#include <iostream>
using namespace std;
namespace BMath
{
class Complex
{
private:
Double real;
Double imaginary;
public:
Complex(Double real, Double imaginary);
Complex(const Complex &other);
Complex &operator+=(const Complex &rightOp);
Complex operator+(const Complex &rightOp);
Complex operator-(const Complex &rigthOp);
Complex operator*(const Complex &rightOp);
//Overload to enable toString operations
friend std::ostream &operator<<(std::ostream &stream, BMath::Complex const &c)
{
return stream << "(" << c.real << "+" << c.imaginary << "i)";
}
};
}; // namespace Bmath

View file

@ -0,0 +1,12 @@
#include <iostream>
#include "../complex.hpp"
using BMath::Complex;
int main(void)
{
std::cout << "Complex numbers " << std::endl;
Complex c1(1,1);
Complex c2(2,2);
std::cout << c1 << c2 << c2-c1 << c2+c1 <<std::endl;
}

View file

@ -1,2 +0,0 @@
add_subdirectory(bmath)
add_subdirectory(cpu)

View file

@ -1,111 +0,0 @@
/*
* Copyright 2017 Vitor Fernandes <email>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
#ifndef BLIST_H
#define BLIST_H
#include <string>
#include <cstddef>
#include <iostream>
template <typename T>
class blist
{
public:
typedef struct node{
node(T v,node* p,node* n){
value = v;
next = n;
previous = p;
}
node(T v){
value=v;
next=NULL;
previous=NULL;
}
T value;
node* next;
node* previous;
} Node;
blist(){
this->rootNode = NULL;
this->currentNode=this->rootNode;
size = 0;
};
blist(T value){
this->rootNode=new Node(value,NULL,NULL);
this->currentNode=this->rootNode;
size = 1;
};
blist(const blist<T>& other){
this->rootNode = other.root();
};
void add(T value){
if(this->rootNode==NULL){
this->rootNode=new Node(value,NULL,NULL);
this->currentNode=rootNode;
}else{
Node* newNode = new Node(value,currentNode,NULL);
this->currentNode->next = newNode;
currentNode=newNode;
}
size++;
};
~blist(){
std::cout << "Destructing list" << std::endl;
Node *aux;
while(this->currentNode!=this->rootNode){
aux = this->currentNode;
this->currentNode = this->currentNode->previous;
delete aux;
}
delete this->rootNode;
};
blist<T>& operator=(const blist& other){
this->rootNode = other.root();
};
bool operator==(const blist& other){
this->rootNode==other.root();
};
Node * root() const {
return this->rootNode;
};
Node * current() const {
return this->currentNode;
};
T* values() {
T *aux = new T[size];
Node *naux = this->rootNode;
for(int i=0;i<size;i++){
aux[i]=naux->value;
naux=naux->next;
}
return aux;
};
int getSize(){
return size;
};
private:
Node * rootNode;
Node * currentNode;
int size;
};
#endif // BLIST_H

View file

@ -1,32 +0,0 @@
#include "complex.hpp"
/**
* Constructor implementation
*/
Core::Bmath::Complex::Complex(Double real,Double imaginary){
this->real=real;
this->imaginary=imaginary;
};
/**
* Add complex number
*/
Core::Bmath::Complex& Core::Bmath::Complex::operator+= (const Complex& rightOp){
this->real+=rightOp.real;
this->imaginary+=rightOp.imaginary;
return *this;
};
Core::Bmath::Complex Core::Bmath::Complex::operator+ (const Complex& rightOp){
return Complex(
this->real+rightOp.real,
this->imaginary+rightOp.imaginary
);
};
Core::Bmath::Complex Core::Bmath::Complex::operator* (const Complex& rigthOp){
return Complex(
this->real*rigthOp.real-this->imaginary*rigthOp.imaginary,
this->imaginary*rigthOp.real+this->real*rigthOp.imaginary
);
};

View file

@ -1,30 +0,0 @@
#ifndef CORE_BMATH_COMPLEX
#define CORE_BMATH_COMPLEX
#include "../cpu/types.hpp"
#include <iostream>
using namespace std;
namespace Core{
namespace Bmath{
class Complex{
private:
Double real;
Double imaginary;
public:
Complex(Double real,Double imaginary);
Complex& operator+=(const Complex& rightOp);
Complex operator+(const Complex &rightOp);
Complex operator*(const Complex &rightOp);
//Overload to enable toString operations
friend std::ostream& operator<<(std::ostream &stream, Core::Bmath::Complex const &c){
return stream << "(" << c.real << "+" << c.imaginary << "i)";
}
};
};
};
#endif

View file

@ -1,17 +0,0 @@
#include "avx2.hpp"
#include <iostream>
#include <string>
void Core::Cpu::avx2::avx_sum(int *a,int *b){
}
void Core::Cpu::avx2::printAVX2Num(int *num){
for(int i=0;i<avx2::AVX2_INT_SIZE;i++){
cout << i;
if(i<avx2::AVX2_INT_SIZE-1){
cout << ",";
}
}
}

View file

@ -1,18 +0,0 @@
#ifndef AVX2_H
#define AVX2_H
using namespace std;
/**
* This will define a set of functions
*/
namespace Core {
namespace Cpu {
class avx2 {
public:
static int const AVX2_INT_SIZE=16;
static void avx_sum(int* a, int* b);
static void printAVX2Num(int* num);
};
};
};
#endif

View file

@ -1,20 +0,0 @@
#ifndef CORE_CPU_NAIVE_H
#define CORE_CPU_NAIVE_H
#include "types.hpp"
using namespace std;
/**
* This will define a set of functions
*/
namespace Core {
namespace Cpu {
class Naive {
public:
//Methods
static void sum_128_long(UInt* a, UInt* b);
};
};
};
#endif

View file

@ -1,20 +0,0 @@
#ifndef CORE_CPU_SSE_H
#define CORE_CPU_SSE_H
#include "types.hpp"
using namespace std;
/**
* This will define a set of functions
*/
namespace Core {
namespace Cpu {
class SSE {
public:
static void paddw(UInt *a,UInt *b);
static void paddd(ULong *a,ULong *b);
};
};
};
#endif

View file

@ -1,25 +0,0 @@
#ifndef CORE_CPU_TYPES_H
#define CORE_CPU_TYPES_H
/*
* Types for x86 architectures
*/
#if defined(__x86_64__)
//Signed type alias
typedef int Int;
typedef int Int;
typedef long Long;
typedef char Char;
typedef short Short;
//IEEE floating point alias
typedef float Float;
typedef double Double;
//Unsigned type alias
typedef unsigned char UChar;
typedef unsigned short UShort;
typedef unsigned int UInt;
typedef unsigned long ULong;
#endif
#endif

View file

@ -1,71 +0,0 @@
#ifndef CORE_CPU_UTILS_H
#define CORE_CPU_UTILS_H
#include <iostream>
#include "types.hpp"
namespace Core {
namespace Cpu {
class Utils {
public:
//Lengths
static const UChar INT_LEN_64 = 2;
static const UChar INT_LEN_128 = 4;
static const UChar INT_LEN_256 = 8;
static const UChar INT_LEN_512 = 16;
static const UChar LONG_LEN_64 = 1;
static const UChar LONG_LEN_128 = 2;
static const UChar LONG_LEN_256 = 4;
static const UChar LONG_LEN_512 = 8;
//Masks
static const UInt MASK_32=0xFFFFFFFF;
static const UInt MASK_16=0xFFFF;
static const UInt MASK_8=0xFF;
//Shifts
static const UChar SHIFT_32 = 32;
static const UChar SHIFT_16 = 16;
static const UChar SHIFT_8 = 8;
/**
* Template function (generics) to enable the printing of several datatypes
*/
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;
};
/**
* Utility method to convert a packaged 128bit int to 128bit long
*/
static void int128BitToLong(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 packed 128bit long into a 128 int
*/
static void long128BitToInt(ULong *packedULong, UInt *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;
};
};
};
};
#endif

7
src/cpu/CMakeLists.txt Normal file
View file

@ -0,0 +1,7 @@
add_executable(
sse
demos/sse.cpp
sse.cpp
naive.cpp
avx2.cpp
)

19
src/cpu/avx2.cpp Normal file
View file

@ -0,0 +1,19 @@
#include "avx2.hpp"
#include <iostream>
#include <string>
void Cpu::avx2::avx_sum(int *a, int *b)
{
}
void Cpu::avx2::printAVX2Num(int *num)
{
for (int i = 0; i < avx2::AVX2_INT_SIZE; i++)
{
cout << i;
if (i < avx2::AVX2_INT_SIZE - 1)
{
cout << ",";
}
}
}

13
src/cpu/avx2.hpp Normal file
View file

@ -0,0 +1,13 @@
#pragma once
using namespace std;
namespace Cpu
{
class avx2
{
public:
static int const AVX2_INT_SIZE = 16;
static void avx_sum(int *a, int *b);
static void printAVX2Num(int *num);
};
};

63
src/cpu/demos/sse.cpp Normal file
View file

@ -0,0 +1,63 @@
#include <iostream>
#include "../utils.hpp"
#include "../sse.hpp"
#include "../naive.hpp"
#include <sys/time.h>
using namespace Cpu;
using namespace std;
long int gettime(){
struct timeval tp;
gettimeofday(&tp, NULL);
long int ms = tp.tv_sec * 1000 + tp.tv_usec / 1000;
return ms;
};
#define MAX_ITER 1000*1000*100
int main(int argc, char** argcv){
UInt v1_128[INT_LEN_128] = { 0x1, 0x2,0x3,0x4 };
UInt v2_128[INT_LEN_128] = { 0x1, 0x2,0x3,0x4 };
ULong v1_128_l[LONG_LEN_128];
ULong v2_128_l[LONG_LEN_128];
Utils::int128BitToLong(v1_128,v1_128_l);
Utils::int128BitToLong(v2_128,v2_128_l);
SSE::paddw(v1_128,v2_128);
long int start,end;
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);
start = gettime();
for(int i=0;i<MAX_ITER;i++){
Naive::sum_128_long(v1_128,v2_128);
}
end = gettime();
cout << "Naive Approach: " << end-start << endl;
start = gettime();
for(int i=0;i<MAX_ITER;i++){
SSE::paddw(v1_128,v2_128);
}
end = gettime();
cout << "SSE Approach paddw: " << end-start << endl;
start = gettime();
for(int i=0;i<MAX_ITER;i++){
SSE::paddd(v1_128_l,v2_128_l);
}
end = gettime();
cout << "SSE Approach paddd: " << end-start << endl;
Utils::printHex(v1_128,INT_LEN_128);
Utils::printHex(v1_128_l,LONG_LEN_128);
}

View file

@ -2,7 +2,7 @@
#include "types.hpp" #include "types.hpp"
#include <iostream> #include <iostream>
void Core::Cpu::Naive::sum_128_long(UInt *a,UInt *b){ void Cpu::Naive::sum_128_long(UInt *a,UInt *b){
ULong a1 = ((ULong)a[0] << 32) | a[1]; ULong a1 = ((ULong)a[0] << 32) | a[1];
ULong a2 = ((ULong)a[2] << 32) | a[3]; ULong a2 = ((ULong)a[2] << 32) | a[3];
ULong b1 = ((ULong)b[0] << 32) | b[1]; ULong b1 = ((ULong)b[0] << 32) | b[1];

17
src/cpu/naive.hpp Normal file
View file

@ -0,0 +1,17 @@
#pragma once
#include "types.hpp"
using namespace std;
/**
* This will define a set of functions
*/
namespace Cpu
{
class Naive
{
public:
//Methods
static void sum_128_long(UInt *a, UInt *b);
};
};

View file

@ -2,7 +2,7 @@
#include <iostream> #include <iostream>
//X86 Assembly to add two 128 bit numbers in the form of packed integers 32bit //X86 Assembly to add two 128 bit numbers in the form of packed integers 32bit
void Core::Cpu::SSE::paddw(UInt *a,UInt *b) { void Cpu::SSE::paddw(UInt *a,UInt *b) {
asm( asm(
"movdqa %0, %%xmm1\n" "movdqa %0, %%xmm1\n"
"paddw %1, %%xmm1\n" "paddw %1, %%xmm1\n"
@ -14,7 +14,7 @@ void Core::Cpu::SSE::paddw(UInt *a,UInt *b) {
//X86 Assembly to add two 128 bit numbers in the form of packed long 64bit //X86 Assembly to add two 128 bit numbers in the form of packed long 64bit
void Core::Cpu::SSE::paddd(ULong *a,ULong *b) { void Cpu::SSE::paddd(ULong *a,ULong *b) {
asm( asm(
"movdqa %0, %%xmm1\n" "movdqa %0, %%xmm1\n"
"paddd %1, %%xmm1\n" "paddd %1, %%xmm1\n"

16
src/cpu/sse.hpp Normal file
View file

@ -0,0 +1,16 @@
#pragma once
#include "types.hpp"
using namespace std;
namespace Cpu
{
class SSE
{
public:
static void paddw(UInt *a, UInt *b);
static void paddd(ULong *a, ULong *b);
};
};

42
src/cpu/types.hpp Normal file
View file

@ -0,0 +1,42 @@
#pragma once
/*
* Types for x86 architectures
*/
#if defined(__x86_64__)
//Signed type alias
typedef int Int;
typedef long Long;
typedef char Char;
typedef short Short;
//IEEE floating point alias
typedef float Float;
typedef double Double;
//Unsigned type alias
typedef unsigned char UChar;
typedef unsigned short UShort;
typedef unsigned int UInt;
typedef unsigned long ULong;
//SSE DataTypes
#define INT_LEN_64 2
#define INT_LEN_128 4
#define INT_LEN_256 8
#define INT_LEN_512 16
#define LONG_LEN_64 1
#define LONG_LEN_128 2
#define LONG_LEN_256 4
#define LONG_LEN_512 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

50
src/cpu/utils.hpp Normal file
View file

@ -0,0 +1,50 @@
#pragma once
#include <iostream>
#include "types.hpp"
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;
};
/**
* Utility method to convert a packaged 128bit int to 128bit long
*/
static void int128BitToLong(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 packed 128bit long into a 128 int
*/
static void long128BitToInt(ULong *packedULong, UInt *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;
};
};
}; // namespace Cpu

126
src/dtstruct/blist.hpp Normal file
View file

@ -0,0 +1,126 @@
/*
* Copyright 2017 Vitor Fernandes <email>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
#pragma once
#include <string>
#include <cstddef>
#include <iostream>
template <typename T>
class blist
{
public:
typedef struct node
{
node(T v, node *p, node *n)
{
value = v;
next = n;
previous = p;
}
node(T v)
{
value = v;
next = NULL;
previous = NULL;
}
T value;
node *next;
node *previous;
} Node;
blist()
{
this->rootNode = NULL;
this->currentNode = this->rootNode;
size = 0;
};
blist(T value)
{
this->rootNode = new Node(value, NULL, NULL);
this->currentNode = this->rootNode;
size = 1;
};
blist(const blist<T> &other)
{
this->rootNode = other.root();
};
void add(T value)
{
if (this->rootNode == NULL)
{
this->rootNode = new Node(value, NULL, NULL);
this->currentNode = rootNode;
}
else
{
Node *newNode = new Node(value, currentNode, NULL);
this->currentNode->next = newNode;
currentNode = newNode;
}
size++;
};
~blist()
{
std::cout << "Destructing list" << std::endl;
Node *aux;
while (this->currentNode != this->rootNode)
{
aux = this->currentNode;
this->currentNode = this->currentNode->previous;
delete aux;
}
delete this->rootNode;
};
blist<T> &operator=(const blist &other)
{
this->rootNode = other.root();
};
bool operator==(const blist &other)
{
this->rootNode == other.root();
};
Node *root() const
{
return this->rootNode;
};
Node *current() const
{
return this->currentNode;
};
T *values()
{
T *aux = new T[size];
Node *naux = this->rootNode;
for (int i = 0; i < size; i++)
{
aux[i] = naux->value;
naux = naux->next;
}
return aux;
};
int getSize()
{
return size;
};
private:
Node *rootNode;
Node *currentNode;
int size;
};