2D array vs. structure (C++) - c++

If execution speed is important, should I use this,
struct myType {
float dim[3];
};
myType arr[size];
or to use a 2D array as arr[size][index]

It does not matter. The compiler will produce the exact same code regardless in almost all cases. The only difference would be if the struct induced some kind of padding, but given that you have floats that seems unlikely.

It depends on your use case. If you use the three dimensions typically together, the struct organization can be reasonable. Especially when using the dimension individually the array layout is most likely to give better performance: contemporary processors don't just load individual words but rather units of cache lines. If only parts of the data is used there are words loaded which aren't used.
The array layout is also more accessible to parallel processing e.g. using SIMD operations. This is unfortunate to some extend because the object layout is generally different. Actually, the arrays you are using are probably similar but if you change things to become float array[3][size] things become different.

No difference at all. Pick what is more readable to you.
Unless you're working on some weird platform, the memory layout of those two will be the same -- and for the compiler this is what counts most.

The only difference is when you pass something to a function.
When you use the array solution, you never copy the array contains but just pass the array address.
The structs will always be copied if you don't explicitly pass the struct address in case of the struct solution.

One other thing to keep in mind that another poster mentioned: If dim will always have a size of 3 in the struct, but the collection really represents something like "Red, Green, Blue" or "X, Y, Z" or "Car, Truck, Boat", from a maintenance standpoint you might be better off breaking them out. That is, use something like
typedef struct VEHICLES
{
float fCar;
float fTruck;
float fBoat;
} Vehicles;
That way when you come back in two years to debug it, or someone else has to look at it, they will not have to guess what dim[0], dim[1] and dim[2] refer to.

You might want to map out the 2d array to 1d. Might be more cache friendly

Related

Using a union in a struct that contains either pre-calculated or calculatable results

So I have a struct I need to create. Essentially its purpose is that an array of these structs will be returned from a variety of functions. All of these structs will be gathered (maybe a few hundred) and I will then need the normal for the least of them.
So to sort of summarise I have a situation where there will be many of these structs however the normal value will only be needed for one of them.
As such I was trying to create a struct that captures this idea. That way the one chosen struct can either contain its normal or a method to calculate it. As such I designed the following struct:
struct result {
float t;
bool calculated; // Tells whether to use result.normal.norm or result.norm.calculate()
union normal {
float2 norm;
float2 (*calculate)();
};
};
Is this the proper way to express this idea?
*For examples sake some of these normal calculations might involve some calculations like trig to figure out a normal on a complex curved surface. We would only want to calculate this if absolutely necessary.
(I don't believe you've provided enough context to fully answer your question, but I'll try based on what you've given me.)
Is this the proper way to express this idea?
Since you seem to be concerned with performance - probably not. Calling a function through a function pointer is (edit:) often expensive. What's more, that function doesn't even get the t field's value when you call it... so this will probably not even work.
What should you do, then?
First, figure out if this is even a pain point w.r.t. performance. Don't just optimize this because there's a potential for optimization.
Assuming this is useful to optimize - try avoiding this whole materialization-of-results. Instead, determine which float needs its norm, then be willing to spend some effort getting that norm; it won't be that bad since you'll only be doing work for one piece of data rather than all of them.
PS - No need to use unions these days, we have std::variant in C++17. The would save you the boolean, too.

Array for visited co-ordinates in c++

I am working on a game which has a map of 16000 X 9000 units, If I am at any point X,Y on map, I can see upto a radius of 2000 units. I wanted something from which I could manage whether I've visited a particular region or not. The main question is Should I take an array of bools? It will be too large bool visited[16000*9000]. So wanted advise, thanks. I am new to stackoverflow, sorry if I am not to the point.
If you need the discovered region to be circular (which your use of 'radius' implies) you have to use this huge arry, yes.
If it does not have to be a perfect circle, then you can simply downsample: say you use a roughness of 10 blocks - then you only need an array of 1600x90 size - a factor 100 reduction compared to the perfect circle.
It would indeed be inefficient to use an array of bool types. Mainly because the size of a bool in C++ can be luxuriously big. (On my platform, it's 8 bits long which means that 7 bits of it are not used.) The C++ standard does not specify the value of sizeof(bool).
Do consider using a std::vector<bool> instead: this is an explicit specialisation of std::vector and the C++ standard guarantees this is tightly packed: i.e. there is no wasted space. You might need a std::vector<std::vector<bool>> if you have difficultly acquiring one contiguous block of memory. This all said, some folk dislike the bool vector specialisation with a vengeance so do consider this carefully before diving in. (There is a movement to consider scheduling it for deprecation!)
Or you could lump areas of your graph together yourself into a set of integral types such as unsigned.

Three one dimension or one two dimensional

In my C and C++ programs, I have three arrays: one for an x coordinate, a y coordinate, and the location in the list. I was wondering if it would take less memory if I put all three in the same array. Any idea? Also, is there something about only having to define one dimension and having the other variable?
Thank you for the help.
It's unlikely to take less memory to put them together; depending on the structure packing and alignment, it might even take more. That's doubtful in this case though. The most likely outcome is that they'll be the same.
One thing that will be affected is cache coherency. If you usually access all of the values together at the same time, it will be slightly more efficient to have them close together. On the other hand if you typically zip through one array at a time, it will be more efficient to keep them separated.
P.S. If it wasn't obvious, I'm advocating putting the values in a structure rather than a 2D array. The memory layout would be similar but the syntax is different.
It will take exactly the same amount of memory; it will just be arranged differently.
It is (arguably, generally) better style to have 1 array of complex things, if those things go together. One reason is you can't accidentally have a different number of each component.
A multi dimenstional array is really just a one dimensional array. With this in mind you would want to use data localization principles (when you access a data point in memory it's easier to load datapoints nearby to it).
Take into consideration whether you'll be accessing your x's in one go then your y's then your locations, or whether you'll be accessing x y and location data all at once.
Look more into how multi -dimensional arrays are represented in memory to decide how you'd "group" your data.

Are there benefits to allocating large data contiguously?

In my program, I have the following arrays of double: a1, a2, ..., am; b1, b2, ..., bm; c1, c2, ..., cm; which are members of a class, all of length N, where m and N are known at run time. The reason I named them a, b, and, c is because they mean different things and that's how they are accessed outside the class. I wonder what's the best way to allocate memory for them. I was thinking:
1) Allocating everything in one big chunk. Something like.. double *ALL = new double[3*N*m] and then have a member function return a pointer to the requested part using pointer arithmetic.
2) Create 2D arrays A, B, and C of size m*N each.
3) Use std::vector? But since m is known at run time, then I need vector of vectors.
or does it not really matter what I use? I'm just wondering what's a good general practice.
If all three are linked in some way, if there is any relationship between a[i] and b[i], then they should all be stored together, ideally in a structure that names them with a meaningful and relevant name. This will be easier to understand for any future developer and ensures that the length of the array is always correct by default.
This is called design affordance, meaning that the structure of an object or interface lends itself to be used as intended by default. Just think how a programmer who had never seen the code before would interpret its purpose, the less ambiguity the better.
EDIT
Rereading I realize you might be asking about some kind of memory optimization (?) although it isn't clear. I'd still say use something like this, either an array of class pointers or structs depending on just how large N is.
This really depends significantly on how the data are used. If each array is used independently then the straightforward approach is either a number of named vectors of vectors.
If the arrays are used together where for example a[i] and b[i] are related and used together, separate arrays is not really a good approach because you'll keep accessing different areas of memory potentially causing a lot of cache misses. Instead you would want to aggregate the elements of a and b together into a struct or class and then have a single vector of those aggregates.
I don't see a big problem with allocating a big array and providing an appropriate interface to access the correct sets of elements. But please don't do this with new to manage your memory: Use vector even in this case: std::vector<double> all(3*N*m); However I'm not sure this buys you anything either so one of my other options may be more clear for the intention.
Use option 3, a vector of vectors. That will free you from worrying about memory management.
Then hide it behind an interface so you can change it if you feel the need.

Vector, Matrix, Algebra class Design

I am in the process of designing a maths library. I want to start with a simple vector 4 and a matrix 4x4 and I'll extend it with the needs. I am trying to pro and cons of several design I have seen so that I can choose. I find it frustrating I searched a lot, I found a lot but almost no answer were talking about efficiency of the design which is critical for a maths library.
What I am taking into consideration, compiler are amazing now a days I know I can't be smarter that the compiler, but I want to help him to the max. C++11 is bringing good stuff, like move semantics and other stuff like std::tuple....
From what I know the data should be stored in continuous memory.
Where I am a bit lost and need more info is:
A) Should the data be:
value_type[ Rows * Cols] (simple c array) or
value_type* (allocated on the heap of size Rows * Cols) or use something like
std::tuple
B) Also Inheritance or composition/aggregation
I could have a template base class for the data or I could do it with composition/aggregation
C) I saw 3 layout of the data
a struct and union (like in this article http://www.gamasutra.com/view/feature/4248/designing_fast_crossplatform_simd_.php)
a simple member variable
another one used static pointer to member instead of a union. (http://www.gamedev.net/topic/261920-a-slick-trick-in-c/)
D) Also in the gamasutra article (which seem to be old and compiler are better now) He say that the class should not have operator overload and that global function should be used instead. For example the crossProduct function to make it non-member instead of a member function.
I have all of those question, I know there is a lot. What are your take on those, especially on A and C.
Edit:
Thanks all for those answer for the point A, I must say that at the moment my biggest question is with point C, sorry I know it wasn't clear. Point c is really about the design of the classes. I saw 2 option (kind of three if you consider this static trick http://www.gamedev.net/topic/261920-a-slick-trick-in-c/) I could have for a Vector4 in example I could have members of x, y, z and w publicly available or I could also make a union with those members and an array, or I could have only an array and have functions X(), Y(), Z(), W() for accessor. And finally there is the static trick that I provided the link just above but I would prefer if the x,y,z and w would be static and the array would be the data member.
Refer to Blitz++. Also see its "About" page to get a gist about it. It is one of the popular industrial strength math library written in C++. Though you didn't ask for which library to refer to I am citing this mainly because you can learn from some of the design choices made in this library. You might find insights on the very questions you are pondering.
For a small 4x4 matrix, I would avoid dynamically allocating memory on the heap ... a simple one-dimensional array that you can index as a 2D array should suffice (i.e., the ordered pair (x,y) value would be matrix_array[COLUMNS * y + x]), especially considering that loading any single value in the array will also cause adjacent values to be stored on the processor's cache-line, speeding up access to any adjacent elements. The cache-loading can happen with heap-allocated memory as well, but the main reason to avoid heap allocation if possible for small matricies is that many sequential math operations will require you to return a temporary, and without r-value references, you're going to end up doing a lot of calls to new and delete inside the copy-constructors of those temporaries which will slow things down tremendously compared to quickly allocating memory on the stack.
Secondly, I would suggest you go with a templated approach, as this will let your define you matrix for not only plain-old-data-types like double, etc., but also for any secondary composite types you may decide to define later, or import from another library such as rationals, complex numbers, etc. Whether you decide to add operator overloads is really up to you ... some people do not like it because it "hides" the complexity of what may be happening underneath the hood (i.e, A * B for doubles will be far simpler than A * B for a 4x4 matrix<double>). On the other-hand, it can greatly simplify the amount of code you write for complex math operations.