You define: std::vector<double*> ne(nx*ny) which makes "ne", bad name, a variable to a vector of "double" pointers.
In the line: ne[j + ny*i] = ne0[j + ny*i] + ne1[j + ny*i];. Since "ne" is a vector of "double*"s the rhs of = needs to return an address not a value. So if "ne0" is not an array of "double" pointers. you have a problem.
// double *ne;
// ne = (double*) fftw_malloc(nx*ny*sizeof(double));
// memset(ne, 42, nx*nyk* sizeof(double)); // 42 here was something large enough
// create a vector containing nx*ny double values initialised to something large enough
// DBL_MAX is defined in <cfloat> https://en.cppreference.com/w/cpp/header/cfloat
std::vector<double> ne( nx*ny, DBL_MAX ) ;
You're going to have to change all the function definitions - and probably also their usage.
I thought I can convert between malloc and std:vector easily and use it for speed.
Yes if malloc is just used for a 1-d array that isn't passed as a function param and if the memory pointer is used as an array. I doubt that using std::vector will give any extra speed.
Hello @Handy Andy
Sure, I have my full code that I could provide to you. Unfortunately, is HUGE and I guess you'll see why I am trying to change every malloc and fttw_malloc to std::vector.
Here's my code:
Yes if malloc is just used for a 1-d array that isn't passed as a function param and if the memory pointer is used as an array. I doubt that using std::vector will give any extra speed.
oh! I see, mm then I probably should go about this some other way.
you absolutely can. vectors are ensured to be sequential, so if the thing in the vector is a type that can tolerate these, you can use them, eg a vector of bytes. You probably should not do it, but you "can". If you are seeking a faster data copy / move you can write an assembly loop to move the data via the 128 bit register if you have one, copying 16 bytes per operation if supported... remember to check the boundary or pad the space eg if you have 257 bytes there is 1 left over
vectors are plenty fast if used correctly. I had a lot of trouble with them when they first came out, but they have been tweaked and work fine if you understand what things they do that can hurt performance and avoid them as much as possible. There are a few places valarray can do something a vector can't do easily, making those faster in some jobs. Plain arrays, plain pointers, etc can cut a tiny bit of overhead but its an exceptional program where those matter.
> You're going to have to change all the function definitions - and probably also their usage.
Not really; vectors are compatible with C's memory model.
The pointer returned by std::vector<double>::data() (along with the vector's size) can be passed to a C-function. C-code can both read from and write to the elements in the vector.
> If you are seeking a faster data copy / move you can write an assembly loop to move the data
> via the 128 bit register if you have one, copying 16 bytes per operation if supported...
An optimiser should do this automatically for TriviallyCopyable types.
I agree, it should. I ran out of energy trying to run down how the AVX stuff works and whether it has 512 bit registers or not and whether anything makes much use of it yet if it does. It would be really cool if it could shuffle 512 / clock, but I suspect bus bandwidth or something has it locked at 64 in critical areas.
Anyway, some minor testing shows it doing 64 bits at at time as you said. I have been unable to catch anything I have access to in the act of more than this, though.
I didn't say you couldn't. I said you don't. Yes, you can get the data starting memory address using .data() and use this as a memory pointer for memset, memcpy etc. But unless you are really into high-performance and understand memory/cpu organisation etc you normally don't. The member functions (and those from <algorithm> ) are already highly optimised for copying etc.
As I said, if you are currently using malloc() and memory manipulation, you probably won't get any performance improvement using std::vector per se.
Not really; vectors are compatible with C's memory model.
The pointer returned by std::vector<double>::data() (along with the vector's size) can be passed to a C-function. C-code can both read from and write to the elements in the vector.
Yes you can but IMO don't. Pass the vector by ref/const ref and use as a vector - not as a block of memory. Unless there are good reasons, don't mix C++ containers et al with using raw memory.
@JamieAL, Can you provide some sample input and output?
The ability to execute the code and compare its output would be a major help because it lets us
- use the debugger to test assumptions
- make sure that our transformations don't blow up the program
- use a profiler to guide our optimizations
and so on.