i'm building a simple Neural Network, i have two main classess: NeuralNetwork And Level. I don't have neurons since it's a simple feedworward with all units in a level sharing the same activation function.
I've organized my levels in this way:
Class NeuralNetwork has a vector of levels (not pointers, values.), for fast access them and every object of class Level has a pointer to the prec and next level, some matrixes and stuff.
The question which is more general is:
What copy/move constructors/assignments operators for a class organized as a double linked list like Level should do?
Copy the entire structure following next and back pointers and returning the istance of the just copied object.
Copy the single level leaving the pointers next\prec to nullptr returning a singleton level with just the copies of the matrixes ecc..
Delete the copy constructor/assignment operator.
What your class does is up to you. With that said, people will generally expect generic containers such as linked lists to be copyable.
When designing such classes, more generally, ask yourself the following:
What does copying this class mean?
Does it make sense to copy this class?
Will user's be surprised if this class is copied?
If it's not clear what copying this class means, don't make it copyable. If it doesn't mean sense to copy this class, don't make it copyable. If people will be surprised to see the class getting copied (think unique_ptr), don't make it copyable without some serious thought. These aren't hard rules, these are just some thinking points to help you work out what's appropriate.
If you don't intend to make something copyable, it does indeed make sense to delete the associated operators (this acts as documentation if nothing else).
If you do make your class copyable, then it's up to you on how you implement it. You can make shared instances that copy on write, you can eagerly copy, you can do whatever you want; it all depends on what you your users (including you) will expect to happen, and what the trade-offs are for each.
"Class NeuralNetwork has a vector of levels (not pointers, values.), for fast access them and every object of class Level has a pointer to the prec and next level"
That's a bit pointless. The previous layer is *(this-1) and the next layer is *(this+1). That's because vector stores its elements contiguously. Of course, there's the minor challenge of knowing whether there is a previous or next layer, but that question doesn't tend to come up. The input layer is a special layer since you set its values directly. All the next layers can safely pull their input from the previous layer, so no layer needs to push its input to the next layer.
Training is a bit harder because there you have a backpropagation phase and need to walk in both directions. However, here you control both the inputs and the desired outputs, so you explicitly use layers.front() and layers.back(), never going past them.
Now, when you copy the whole vector, each layer is a copy and has a new this, but since the new vector is again contiguous the *(this-1) / *(this+1) rule for neigbours still holds.
Related
How would one go about creating a vector that includes both the base class as well as any derived classes?
For example, in a chess engine, I currently have a Move class which stores a particular move and a few functions to help it. In order to save memory, as millions of these objects are going to be created, I also have a derived class CaptureMove that extends the Move class storing a bit more information about what and where the piece was captured.
From what I can gather, pointers to Move objects should work, but I'm not quite sure on how to go about it.
The question is quite broad. Here some ideas:
Vectors of base pointers:
This works extremely well if your class is polymorphic (i.e. the relevant functions of the base class are virtual).
vector<Move*> mp;
mp.push_back (new Move); // attention, you have to delete it ofr memory will leak
mp.push_back (new CaptureMove);
It the simplest way to proceed. However you have to make sure that when you add an object, it's allocated properly (e.g. created with new), and that once you no longer need it, you delete it. This can be very cumbersome, especially if vector was copied and some of its pointers are still in use.
This approach can be practical for example if you create and delete the objects in a centralised manner, so that the vector only uses pointers which are properly managed somewhere else.
Vector of shared base pointers:
vector<shared_ptr<Move>> m;
m.push_back(make_shared<Move>());
m.push_back(make_shared<CaptureMove>());
m.push_back(make_shared<Move>());
Here an online demo.
It extends the pointer solution, using smart pointers to take care of the release of unused objects.
Honestly, it's a little overhead but it's really worth it, in order to have reliable code. This is the approach I would take personnally if I'd have to do it.
Vector of compound object
You could also prefer to store the object instead of a pointer to the object. While the idea seems simple, it's more difficult to do, because different derivates could have different size. And it has serious drawbacks, because you'd need to know all possible base and derived types you may store in the vector, which makes this approach less flexible.
You could certainly manage this with a complex union, but the easiers way would be to use boost::variant.
vector<boost::variant<Move, CaptureMove>> m;
This approach is only worth considering if the number of derived classes is very limited, but you have huge numbers of small objects (so that memory allocation would become a real overhead) of almost the same size.
I have been given some code to read which does some geometric operations on meshes.
A mesh data structure, by definition, should contain at least the information
regarding the coordinates of points, edge connectivity and face information.
So, the code given to me has classes to define vertex, edge and face data structure,
named respectively as Vertex, Edge and Face.
However the mesh class looks like this.
class basemesh
{
public:
/* Methods to operate on the protected data below.*/
protected:
/*! list of edges */
std::list<Edge*> m_edges;
/*! list of vertices */
std::list<Vertex*> m_verts;
/*! list of faces */
std::list<Face*> m_faces;
}
My question: Why does the mesh data structure store a list of pointers rather than a
list of the corresponding objects themselves.
e.g why not say directly std::list<Vertex>
I have seen this construct being used in a couple of other C++ codes
Does this have something to do with inheritance of classes? Or is it something to do
with performance with regards to iterating on the list?
This basemesh class is, as the name suggests, a base class from which
other specialized meshes are derived.
There is no performance reasons here. Its simply a case of ownership sharing. Remember this as a rule of thumb: Pointers in C++ are used to share/pass ownership of a resource, or to provide polymorphic behaviour through dynamic binding.
People is talking about performence because you avoid copying the things. Blah, blah, blah.
If you need to copy, you should copy. The only reason why its using pointers is because the author didn't want to copy the things when he/she copies the list of things, in other words, he/she wants to maintain the same things in two locations (lists): Ownership sharing, as I said before.
On the other hand, note that the class is called basemesh. So the real point of the pointers here could be to work with polymorphic vertices, edges, etc (Dynamic binding).
NOTE: If performance was the point here, I'm pretty sure the author would be using compact and aligned non-cache-miss-prone std::vector instead of std::list. In this case, the most presumable reason about the use of pointers is polymorphism, not performance. Anything related to pointers, dereferencing, and transversing linked lists will always have less performance than compact data, exactly what std::vector<Vertex> is, for example. Again, if the use of pointers is not for polymorphism, is for ownership related things, not performance.
Other note: Copying Yes, you are copying. But note what and how are copying. Vertices are, except of a very rare implementation, pairs of floats/ints. There is no gain at all about copying 64bits of floats vs 32/64bits of pointers.
Also note that, except you don't be so lucky, you are copying things stored at the same cache line, or almost at the cache.
A good rule about optimization nowadays is: Try to optimize memory accesses, not CPU cicles. I recommend this thread: What is "cache-friendly" code?, and this for a practical case: Why are elementwise additions much faster in separate loops than in a combined loop?. Finally, this thread contains good notes about optimizing using modern compilers.
My guess is that it's either made for a very unusual specific case, but more likely, it's written by a programmer who doesn't know how heap allocations or std::list actually work, and just blindly use pointers.
It seems very unlikely a std::list of pointers to single vertices was the best option performance- or designwise.
On a practical level if a method changes a point it does not need to reproduce the change in the other data structures. They will all point to the same thing.
But in terms of memory management it would be wise to use smart pointers,
At a guess I'd say it's so that these objects can have pointers to each other (e.g. an Edge can have pointers to two Vertices, each of which can have a pointer back to the Edge).
If all the Vertices lived in a std::list in basemesh, then pointers to them would not be reliable, although list::iterators might work well enough.
Using pointers is less efficient when retrieving inner data in general because you will have to dereference the value every time you access it.
But at the same time it will be more efficient when passing data around, since you are just passing pointers. I guess the solution chosen is related to the fact that data is shared between multiple objects by composition. Eg: multiple Edge instances could refer to same Vertex.
Now std::list guarantees that addresses to values contained are consistent until the element itself is removed so actually doing something like
Edge(const Vertex *v1, const Vertex *v2) { .. }
std::list<Vertex>::iterator it = std::advance(vertices.begin(), 3);
std::list<Vertex>::iterator it2 = std::advance(vertices.begin(), 5);
new Edge(&(*it), &(*it2));
Would work since addresses won't be invalidated so there is no real necessity to use pointers to store objects. Actually by using this solution you don't need to care about memory management of single objects since you won't need to delete them or wrap them into smart pointers.
It's using pointers for performance reasons and to reduce the chance of an error.
Imagine the alternative of not using pointers. Every insertion into class basemesh would cause a copy of the object to be created, and every time you access an object, if you aren't careful, you'll get a copy as well.
For example, imagine this statement:
Edge e = m_edges[0];
e.doSomethingThatModifiesState();
In this example, without pointers, you'll have a copy of the object, and any operations you perform on it will not affect the actual edge object stored in m_edges.
With pointers, you don't have this issue:
Edge* e = m_edges[0];
e->doSomethingThatModifiesState();
In this example, no copy of the object is made, and when you do something, you get the intended behavior.
As many others said the speed is the most obvious reason. Another reason is to get polymorphic behavior through pointers to the base class.
Of course I would like to know some magic fix to this but I am open to restructuring.
So I have a class DeviceDependent, with the following constructor
DeviceDependent(Device& device);
which stores a reference to the device. The device can change state, which will necessitate a change in all DeviceDependent instances dependent on that device. (You guessed it this is my paltry attempt to ride the directX beast)
To handle this I have the functions DeviceDependent::createDeviceResources(), DeviceDependent::onDeviceLost().
I planned to register each DeviceDependentinstance to the device specified in the DeviceDependent constructor. The Device would keep a std::vector<DeviceDependent*> of all DeviceDependent instances so registered. It would then iterate through that vector and called the above functions when appropriate.
This seemed simple enough, but what I especially liked about it was that I could have a std::vector<DeviceDependent (or child)> somewhere else in the code and iterate over them quickly. For instance I have a class Renderable which as the name suggest represents a renderable object, I need to iterate over this once a frame at least and because of this I did not want the objects to be scattered throughout memory.
Down to business, here is the problem:
When I create the solid objects I relied on move semantics. This was purely by instinct I did not consider copying large objects like these to add them to the std::vector<DeviceDependent (or child)> collection. (and still abhor the idea)
However, with move semantics (and I have tested this for those who don't believe it) the address of the object changes. What's more it changes after the default constructor is called. That means my code inside the constructor of DeviceDependant calling device.registerDeviceDependent(this) compiles and runs fine, but the device accumulates a list of pointers which are invalidated as soon as the object is moved into the vector.
I want to know if there is someway I can stick to this plan and make it work.
Things I thought of:
Making the 'real' vector a collection of shared pointers, no issue copying. The object presumably will not change address. I don't like this plan because I am afraid that leaving things out on the heap will harm iteration performance.
Calling register after the object has been moved, it's what I'm doing provisionally but I don't like it because I feel the constructor is the proper place to do this. There
should not exist an instance of DeviceDependent that is not on some device's manifest.
Writing my own move constructor or move assignment functions. This way I could remove the old address from the device and change it to the new one. I don't want to do this because I don't want to keep updating it as the class evolves.
This has nothing to do with move constructors. The issue is std::vector. When you add a new item to that vector, it may reallocate its memory, and that will cause all the DeviceDependant objects to be transferred to a new memory block internal to the vector. Then new versions of each item will be constructed, and the old ones deleted. Whether the construction is copy-construction or move-construction is irrelevant; the objects effectively change their address either way.
To make your code correct, DeviceDependant objects need to unregister themselves in their destructor, and register themselves in both copy- and move-constructors. You should do this regardless of what else you decide about storage, if you have not deleted those constructors. Otherwise those constructors, if called, will do the wrong thing.
One approach not on your list would be to prevent the vector reallocating by calling reserve() with the maximum number of items you will store. This is only practical if you know a reasonable upper-bound to the number of DeviceDependant objects. However, you may find that reserving an estimate, while not eliminating the vector reallocations entirely, makes it rare enough that the cost of un-registering and re-registering becomes insignificant.
It sounds like your goal is getting cache-coherency for the DeviceDependants. You might find that using a std::deque as main storage avoids the re-allocations while still giving enough cache-coherency. Or you could gain cache-coherency by writing a custom allocator or operator new().
As an aside, it sounds like your design is being driven by performance costs that you are only guessing at. If you actually measure it, you might find that using std::vector> is fine, and doesn't significantly the time it takes to iterate over them. (Note you don't need shared pointers here, since the vector is the only owner, so you can avoid the overheads of reference-counting.)
I'm trying to refactor some C++ code due to performance problems, and I'm wondering the best way to solve this. I have a class say DataGatherer, which a core component of a large system. This class is serialized and sent over data streams, copied and stored into tables, copied for the sake of concurrency (checking out a copy rather than having access to the original DataGatherer object). I list examples just to let you know it has copy and assignment operators that are both used.
The problem is that the DataGatherer objects can become extremely large because they contain essentially a large collection of gathered data as well as statistics and metadata about the data. In many cases, it's only the statistics and metadata that are required, and not the backend data collection.
Are there any design patterns that might be helpful here? Maybe the more general question is, what do you do when in most cases you only need part of an object, but the object is so tightly coupled internally that splitting it up is next to impossible?
Ideas I've had,
Split the class into a DataGatherer class and a pointer to a DataGathererBackend object. Return shallow copies in most cases to avoid all the overhead of copying DataGathererBackend around when it isn't used. I hate to do this because of all the hassle of dealing with when you want a shallow copy vs when you want a deep copy, and just general messyness form having to resort to DataGatherer objects that have NULL pointers for backend objects because it wasn't needed in those cases.
Split the class into DataStatistics and Data, and make a 3rd class that wraps and contains both.
Other ideas?
If just statistics are wanted, how about a struct of statistics you can return by value or const reference and change the retrieval from copy operators to calling a statistics getter function.
One option is that you can do Copy On Write, where copy constructor or assignment operator are overloaded to not copying the (backend?) data in the first place, ref count it, and copy it only when data is modified. You can do it internally to the DataGatherer so iterface is unchanged, as long as if you can overload the data modification members. But if you already exposed the pointer to data and used it everywhere, it'll be harder.
Can C++ objects be copied using bitwise copy? I mean using memcopy_s? Is there a scenario in which that can go wrong?
If they're Plain Old Data (POD) types, then this should work. Any class that has instances of other classes inside it will potentially fail, since you're copying them without invoking their copy constructors. The most likely way it will fail is one of their destructors will free some memory, but you've duplicated pointers that point to it, so you then try to use it from one of your copied objects and get a segfault. In short, don't do it unless it's a POD and you're sure it will always be a POD.
No, doing so can cause a lot of problems. You should always copy C++ types by using the assignment operator or copy constructor.
Using a bitwise copy breaks any kind of resource management because at the end of the day you are left with 2 objects for which 1 constructor has run and 2 destructors will run.
Consider as an example a ref counted pointer.
void foo() {
RefPointer<int> p1(new int());
RefPointer<int> p2;
memcpy(&p2,p1,sizeof(RefPointer<int>));
}
Now both p1 and p2 are holding onto the same data yet the internal ref counting mechanism has not been notified. Both destructors will run thinking they are the sole owner of the data potentially causing the value to be destructed twice.
It depends on the implementation of the C++ object you are trying to copy. In general the owner of the C++ object's memory is the object itself, so trying to "move" or "copy" it with something like memcopy_s is going behind its back which is going to get you in trouble more often than not.
Usually if a C++ object is intended to be copied or moved, there are APIs within the class itself that facilitate this.
If it is a single object, why not use assignment operator (I suppose the compiler-generated assignment operator could be implemented in terms of memcpy if that is so advantageous, and the compiler knows better whether your class is a POD.)
If you want to copy an array of objects, you can use std::copy. Depending on the implementation, this may end up using memmove (one more thing that you can mess up - the buffers may overlap; I don't know whether the nonstandard memcpy_s somehow checks for that) if the involved types allow that. Again, the decision is done by the compiler, which will get it right even if the types are modified.
In general if your structure contains pointers, you can't memcpy it because the structure would most likely allocate new memory spaces and point to those. A memcpy can't handle that.
If however your class only has primitive, non-pointer types, you should be able to.
In addition to the problem of unbalanced resource management calls in the two instance you end up with after a memcopy (as #JaredPar and #rmeador pointed), if the object supports a notion of an instance ID doing a memcopy will leave you with two instances with the same ID. This can lead to all sorts of "interesting" problems to hunt later on, especially if your objects are mapped to a database.