Giving an instance of a class a pointer to a struct - c++

I am trying to get SSE functionality in my vector class (I've rewritten it three times so far. :\) and I'm doing the following:
#ifndef _POINT_FINAL_H_
#define _POINT_FINAL_H_
#include "math.h"
namespace Vector3D
{
#define SSE_VERSION 3
#if SSE_VERSION >= 2
#include <emmintrin.h> // SSE2
#if SSE_VERSION >= 3
#include <pmmintrin.h> // SSE3
#endif
#else
#include <stdlib.h>
#endif
#if SSE_VERSION >= 2
typedef union { __m128 vector; float numbers[4]; } VectorData;
//typedef union { __m128 vector; struct { float x, y, z, w; }; } VectorData;
#else
typedef struct { float x, y, z, w; } VectorData;
#endif
class Point3D
{
public:
Point3D();
Point3D(float a_X, float a_Y, float a_Z);
Point3D(VectorData* a_Data);
~Point3D();
// a lot of not-so-interesting functions
private:
VectorData* _NewData();
}; // class Point3D
}; // namespace Vector3D
#endif
It works! Hurray! But it's slower than my previous attempt. Boo.
I've determined that my bottle neck is the malloc I'm using to get a pointer to a struct.
VectorData* Point3D::_NewData()
{
#if SSE_VERSION >= 2
return ((VectorData*) _aligned_malloc(sizeof(VectorData), 16));
#else
return ((VectorData*) malloc(sizeof(VectorData)));
#endif
}
One of the main problems with using SSE in a class is that it has to be aligned in memory for it to work, which means overloading the new and delete operators, resulting in code like this:
BadVector* test1 = new BadVector(1, 2, 3);
BadVector* test2 = new BadVector(4, 5, 6);
*test1 *= test2;
You can no longer use the default constructor and you have to avoid new like the plague.
My new approach is basically to have the data external from the class so the class doesn't have to be aligned.
My question is: is there a better way to get a pointer to an (aligned on memory) instance of a struct or is my approach really dumb and there's a much cleaner way?

How about:
__declspec( align( 16 ) ) VectorData vd;
?
You can also create your own version of operator new as follows
void* operator new( size_t size, size_t alignment )
{
return __aligned_malloc( size, alignment );
}
which can then make allocationas follows
AlignedData* pData = new( 16 ) AlignedData;
to align at a 16 byte boundary.
If thats no help then i may be misunderstanding what you are asking for ...

You should probably not expect to get improved performance for single-use vectors. Parallel processing shines brightest when you can combine the parallel processing with some volume, i.e. when processing many vectors in sequence.

I fixed it. :O
It was really rather easy. All I had to do was turn
VectorData* m_Point;
into
VectorData m_Point;
and my problems are gone, with no need for malloc or aligning.
But I appreciate everyone's help! :D

Related

Why can I continue to use the overridden structure even if I redefine the structure as typedef and annotate the typedef line?

Why can I continue to use the overridden structure even if I redefine the structure as typedef and annotate the typedef line?
#include <iostream>
#define MAZE_SIZE 21
#define MENU_H_SIZE 30
#define MENU_V_SIZE 120
using namespace std;
char strMaze[MAZE_SIZE][MAZE_SIZE] = {};
struct _tagPlayerPos
{
int x;
int y;
};
//typedef _tagPlayerPos POINT; <- here
//typedef _tagPlayerPos* PPOINT; <- here
POINT tPlayerPos;
POINT tStartPos;
POINT tEndPos;
int main()
{
setMaze(strMaze, &tPlayerPos, &tStartPos, &tEndPos
}
void setMaze(char Maze[MAZE_SIZE][MAZE_SIZE], PPOINT pPlayerPos, PPOINT pStartPos,
PPOINT pEndPos)
{
pStartPos->x = 1;
pStartPos->y = 0;
pEndPos->x = 18;
pEndPos->y = 19;
*pPlayerPos = *pStartPos;
strcpy_s(Maze[0], "02000000000000000000");
strcpy_s(Maze[1], "01111110001100000000");
strcpy_s(Maze[2], "00000011111000110000");
strcpy_s(Maze[3], "00000010010100100000");
strcpy_s(Maze[4], "00000110011111100000");
strcpy_s(Maze[5], "00000100000100000000");
strcpy_s(Maze[6], "00000100000111000000");
strcpy_s(Maze[7], "00011111000001000000");
strcpy_s(Maze[8], "00010001111100000000");
strcpy_s(Maze[9], "00010000001000000000");
strcpy_s(Maze[10], "01111000001111000000");
strcpy_s(Maze[11], "00001000000100000000");
strcpy_s(Maze[12], "00011000000111111100");
strcpy_s(Maze[13], "00010000001100000100");
strcpy_s(Maze[14], "00011111000000001100");
strcpy_s(Maze[15], "00000001000000001000");
strcpy_s(Maze[16], "00011101000111111000");
strcpy_s(Maze[17], "00000101000000000000");
strcpy_s(Maze[18], "00000111111111111110");
strcpy_s(Maze[19], "00000000000000000030");
}
Why can I continue to use the overridden structure even if I redefine the structure as typedef and annotate the typedef line?
You can't, the compiler doesn't know those names, you must be missing something, maybe you have these typedefs in other files included in main, it's hard to say, the only thing that is certain, is that the code you show alone will never compile as you can confirm in this online compiler.
In any case, in C++ you don't need to use typedef for the structure, you can just declare the structure like so:
struct POINT
{
int x;
int y;
};
And use it, no struct keyword is needed to declare a variable o type POINT.
POINT tPlayerPos;
POINT tStartPos;
POINT tEndPos;
Another thing to note is that "overridden" is probably not what you meant, the override keyword has a different meaning.
I also don't see any redefinition of the struct it in your code.

Counting the number of copy and move of a std::vector

I have a program written in C++11 and I would like to count the number of move and copy (construction and assignment) of std::vector<double> objects. Is there a way to do that?
Best regards
No. The implementation of std::vector<> provides no way for that. Neither does any compiler I know of.
As mentioned in the comments, you could create your own counting replacement and use that instead. I.e.
struct counting_vector_double
: std::vector<double>
{
static size_t count_copy_ctor;
static size_t count_move_ctor;
counting_vector_double(counting_vector_double const&other)
: std::vector<double>(other)
{ count_copy_ctor++; }
// etc
};
// in .cc file:
size_t counting_vector_double::count_copy_ctor = 0;
size_t counting_vector_double::count_move_ctor = 0;
(in a multi-threaded situation use atomic counters.) To implement this, you may use a typedef or using directive, like
#ifdef CountingMoveCopy
using vector_double = counting_vector_double;
#else
using vector_double = std::vector<double>;
#endif
and use vector_double in your code.
This answer consider that the OP needs to count the how many times the items of the vector are copied, moved, constructed.. etc) not the vector itself.
Although it is not a direct answer to your question, you may be interested in this answer.
Make a small wrapper class around double:
struct double_wrapper{
double_wrapper()=delete;
double_wrapper(const double value):value_(value){
++constructions_count;
}
double_wrapper(const double_wrapper& other){
value_=other.value_;
++copies_count;
}
double_wrapper(double_wrapper&& other){
value_=other.value_;
//invalidate it in someway.. maybe set it to 0 (not important anyway)
++moves_count;
}
operator double() const {
return value_;
}
double value_;
static unsigned int copies_count;
static unsigned int constructions_count;
static unsigned int moves_count;
}
// in .cpp
unsigned int double_wrapper::copies_count=0;
unsigned int double_wrapper::constructions_count=0;
unsigned int double_wrapper::moves_count=0;
Finally, you have to edit the vector type (you may short it to Debug Mode with some #ifdef):
std::vector<double_wrapper> v1;
Note: not tested.
A possible way to circumvent the restriction could be by making a class Vector inheriting an std::vector and then overload the move and copy operators to increment internal counters.

Copy huge structure of arrays to GPU

I need to transform an existing Code about SPH (=Smoothed Particle Hydrodynamics) into a code that can be run on a GPU.
Unfortunately, it has a lot of data structure that I need to copy from the CPU to the GPU. I already looked up in the web and I thought, that I did the right thing for my copying-code, but unfortunately, I get an error (something with unhandled exception).
When I opened the Debugger, I saw that there is no information passed to my variables that should be copied to the GPU. It's just saying "The memory could not be read".
So here is an example of one data structure that needs to be copied to the GPU:
__device__ struct d_particle_data
{
float Pos[3]; /*!< particle position at its current time */
float PosMap[3]; /*!< initial boundary particle postions */
float Mass; /*!< particle mass */
float Vel[3]; /*!< particle velocity at its current time */
float GravAccel[3]; /*!< particle acceleration due to gravity */
}*d_P;
and I pass it on the GPU with the following:
cudaMalloc((void**)&d_P, N*sizeof(sph_particle_data));
cudaMemcpy(d_P, P, N*sizeof(d_sph_particle_data), cudaMemcpyHostToDevice);
The data structure P looks the same as the data structure d_P. Does anybody can help me?
EDIT
So, here's a pretty small part of that code:
First, the headers I have to use in the code:
Allvars.h: Variables that I need on the host
struct particle_data
{
float a;
float b;
}
*P;
proto.h: Header with all the functions
extern void main_GPU(int N, int Ntask);
Allvars_gpu.h: all the variables that have to be on the GPU
__device__ struct d_particle_data
{
float a;
float b;
}
*d_P;
So, now I call from the .cpp-File the -.cu-File:
hydra.cpp:
#include <stdio.h>
#include <cuda_runtime.h>
extern "C" {
#include "proto.h"
}
int main(void) {
int N_gas = 100; // Number of particles
int NTask = 1; // Number of CPUs (Code has MPI-stuff included)
main_GPU(N_gas,NTask);
return 0;
}
Now, the action takes place in the .cu-File:
hydro_gpu.cu:
#include <cuda_runtime.h>
#include <stdio.h>
extern "C" {
#include "Allvars_gpu.h"
#include "allvars.h"
#include "proto.h"
}
__device__ void hydro_evaluate(int target, int mode, struct d_particle_data *P) {
int c = 5;
float a,b;
a = P[target].a;
b = P[target].b;
P[target].a = a+c;
P[target].b = b+c;
}
__global__ void hydro_particle(struct d_particle_data *P) {
int i = threadIdx.x + blockIdx.x*blockDim.x;
hydro_evaluate(i,0,P);
}
void main_GPU(int N, int Ntask) {
int Blocks;
cudaMalloc((void**)&d_P, N*sizeof(d_particle_data));
cudaMemcpy(d_P, P, N*sizeof(d_particle_data), cudaMemcpyHostToDevice);
Blocks = (N+N-1)/N;
hydro_particle<<<Blocks,N>>>(d_P);
cudaMemcpy(P, d_P, N*sizeof(d_particle_data), cudaMemcpyDeviceToHost);
cudaFree(d_P);
}
The really short answer is probably not to declare *d_P as a static __device__ symbol. Those cannot be passed as device pointer arguments to cudaMalloc, cudaMemcpy, or kernel launches and your use of __device__ is both unecessary and incorrect in this example.
If you make that change, your code might start working. Note that I lost interest in trying to actually compile your MCVE code some time ago, and there might well be other problems, but I'm too bored with this question to look for them. This answer has mostly been added to get this question off the unanswered queue for the CUDA tag.

Having trouble dynamically allocating an array with a created class in C++

I've actually managed to successfully do a dynamically allocated array with a normal data type, but it was a while ago (like, six chapters!) And I can't figure out why I can't set the array dynamically here - I know it's giving me an int error, but I can't use the class type because the class type doesn't deal with numbers like that. At this point I'm pretty confused. Here's my code including headers:
#include <iostream>
#include "milTime.h"
#include "Time.h"
using namespace std;
int main()
{
milTime *theta;
bool amOrPm;
int milHr, milSc,milM,times;
cout<<"How many times would you like to convert?";
cin>>times;
theta = new milTime;
*theta = times;
And here's my error:
Error 1 error C2440: '=' : cannot convert from 'int' to 'milTime
*' c:\users\heather\documents\visual studio 2012\projects\military time\military time\source.cpp 17 1 Military Time
Any help would be greatly appreciated, as I'm completely done except for that. Me and my bright ideas to let it be dynamically allocated!
Here's the milTime class that was requested:
#ifndef MILTIME
#define MILTIME
#include <iostream>
#include "Time.h"
class milTime : public Time
{
protected:
int milHours;
int milMins;
int milSeconds;
public:
void setTime(int h)
{
milHours = h;
}
void setMin(int m)
{
milMins=m;
}
void setSec(int s)
{
milSeconds=s;
}
int getmilHours()
{return milHours;}
int getmilMins()
{return milMins;}
int getmilSeconds()
{return milSeconds;}
bool timeConverter(int mTime, int mMins, int mSecs)
{
bool aOrPm;
min = mMins;
if(mTime<12)
{
hour = mTime;
aOrPm = false;
//AM will be false.
}
else if (mTime>12 && mTime<=24)
{
hour = mTime%12+1;
aOrPm = true;
}
sec = mSecs;
return aOrPm;
}
};
#endif
there are already answers why your code doesn't work
just in case you wanted to allocate an array of milTime, you will need to do it like this:
theta = new milTime[times];
this will create times of milTime objects
anyway, you should be using std::vector instead of dynamic allocations, this is much safer
What is the definition of milTime?
You are trying to assign an int, which is an inbuilt integer type, into your own type milTime. Which won't work unless your type has an assignment operator which takes an int.
Does your type have a constructor that takes an int? as in that case you would want something more like:
theta = new milTime(times);
theta is a pointer to miltime but times is an int hence *theta = times; fails.
Here's your problem:
*theta = times;
theta is a class of milTime, times is an int.
You'll probably need to create a setter method in milTime, like this:
theta.setTime( times )
I can't see your milTime class though, can you post it as well?
Well it seems that in this line:
*theta = times;
You try to assign an int to a milTime.
you can fix this by either doing a static cast:
*theta = static_cast<milTime>(times);
Or oldschool cast:
*theta = (milTime) times;
But prefarbly you can add a constructor to milTime (in miltime.h):
milTime(int i) : someInnerDataWhichIsAnInt(i) {}
The last one is preferable as casts are a sign of a bad structure.
To use the last one do this:
theta = new milTime(times);
Or is it because you need an array? Prefaably use:
std::vector<milTimes> theta() // You need to remove prior definition of `theta`.

I am trying to create an array of objects inside a header file which is failing (Starting C++ Programmer)

EDITED BELOW FOR UPDATES!!!
Thank you for the help, please by all means point out ALL mistakes , I don't care if it sounds rude or mean or whatever, emo junk. Just give it to me straight so I can understand what is going wrong.
Hi everyone!
I am a rookie C++ programmer trying to learn and gain some IRL exp for C++.
I am attempting the following inside my VC++ (vs2008) compiler:
typedef unsigned short USHORT;
class Grid
{
...
public:
Grid()
{
Tile[36]* tileList_ptr;
}
...
};
In essence, I want to put 36 tiles , slam them into an array nice and tidy on the heap for a 8x8 playfield that never changes in size. Like a chessboard. Refer to them with a pointer, and fiddle with them in the related cpp file if needed.
If you aren't laughing by now at this attempt then I probably made a syntax error instead of major design flaw :P
Any help would be much appreciated!
Thanks in advance
EDIT 24/08/2010 13:49 (Time of start)
My code is now as following example:
The Grid Header file Grid.h:
#include "Tile.h"
class Grid
{
//no more typedef used
public:
Tile grid[8][8];
private:
unsigned short selectedItemIndexValue;
public:
Grid()
{
Initialize();
}
~Grid(){}
void Update();
void FinalizeMove(unsigned short index);
void Draw();
private:
void Initialize(); //Initializes members
};
The Grid.cpp file:
#include "stdafx.h"
#include "Grid.h"
//Not tile , that used to give me a class redefinition error
unsigned short selectedItemIndexValue;
//No more typedef used
void Grid::Update()
{
//Respond to controller commands
}
void Grid::FinalizeMove(unsigned short index)
{
}
void Grid::Draw()
{
}
void Grid::Initialize()
{
for(int i = 0; i < 4; i++)
{
Grid::grid[i] = new Tile::Tile(10,10); // ATTEMPT AT FILLING ARRAY
}
}
Tile.h file
class Tile
{
public:
private:
enum TileOccupation
{
EmptyTile = 0,
WhiteSphere = 1,
BlackSphere = 2
};
unsigned short horizontalDimensions;
unsigned short verticalDimensions;
public:
Tile(){}
~Tile(){}
void Update();
void Draw();
};
Tile.cpp file:
#include "stdafx.h"
#include "Tile.h"
void Tile::Update()
{
}
void Tile::Draw()
{
}
The attempt at filling the array in Grid.cpp is returning via the compiler the following error message: "Error 1 error C2061: syntax error : identifier '{ctor}'"
MSDN helped me giving me this:
"Compiler Error C2061. The compiler found an identifier where it wasn't expected. Make sure that identifier is declared before you use it."
I have failed at analysing it's meaning. What exactly have I done wrong here ? And what other problems are there to be found in my project? All help and comments will be much appreciated. Just assume I know 0% of C++
#user428435. Three things:
8x8 is 64, not 36
What kind of problems are you having? If a compilation error, what is the error? Often careful reading of the errors can help you solve your problems. If the code compiles and runs, what does it do that you don't expect it to do?
You probably meant
Tile* tileList_ptr[36];
If you want to allocate memory on the Heap, you have to use an allocation operator like "malloc" or "new"
Your example would, if written correctly only increase the Constructors stack size.
Correct Version of the Stack Memory:
Tile tileList_ptr[36];
Correct Version of the Heap Memory:
Tile* tileList_ptr = new Tile[36];
However, if you use "new" or "malloc" you have to remember to use "delete" or "free" when you don't need the allocated memory anymore...
typedef unsigned short Tile; // <= assuming typo
class Grid
{
...
public:
Grid()
{
}
...
private:
Tile tileList[64]; // <= 8x8=64
};
If the number of tiles is fixed at compile-time, why not store an array of tiles, instead of an array of pointers to tiles?
I am laughing. Your code, it's kind of full of fail :P
First tip: If you can avoid heap allocating, do. If your playfield is always 8x8, don't waste time with the heap (allocating the actual game class on the heap is another matter).
Second tip: Don't do that crappy typedef unsigned short USHORT thing. It's an unsigned short. Just use the type directly. USHORT is not going to change to not be an unsigned short. Plus, ALLCAPS names are reserved for macros. You probably picked this up from the Windows headers, they also use this. Really, it's a TERRIBLE idea.
Thirdly, 8x8 = 64, not 36, and you can just directly say 8x8.
What you want is something like this:
class Grid {
Tile grid[8][8];
public:
Grid() {
}
Tile* operator[](int index) {
return grid[index];
}
const Tile* operator[](int index) const {
return grid[index];
}
...
};
Possibly you mean this:
Tile tileList_ptr[36];
or this:
Tile* tileList_ptr[36];