[C++] using openMP 'parallel for' directive with std::list - possible?

Started by
16 comments, last by ApochPiQ 14 years, 11 months ago
Quote:Original post by loufoqueAnd by the way, a container of pointers is *always* wrong, period.



Pardon me, but I doubt that. I can see that containers of objects are usually preferable, but there are definitely special cases where you'll need containers of pointers (in this context, 'pointers' refers to smart pointers ... I obviously wouldn't recommend using raw pointers for that).

Advertisement
Quote:Original post by loufoque
And by the way, a container of pointers is *always* wrong, period.


Bullshit. It's such a useful construct that boost provides several containers exactly designed to handle pointers.

Wielder of the Sacred Wands
[Work - ArenaNet] [Epoch Language] [Scribblings]

Quote:Original post by Damocles

But if I used list<Particle> then every time I added a particle to the list, it would be copying the entire contents of the particle class each time. The whole reason I used list in the first place is for fast insertion/removal. By using Particle* I am adding another layer of indirection, but I'm removing the copy time for insertion/deletion.


A list is intended just for that - it does not relocate elements, and removal/addition do not relocate anything. It is a linked list. A std::list is not what List interface is in Java or C#. It is (doubly) linked list.

A std::list of pointers is rarely if ever needed, unless list itself is merely a proxy to elements stored elsewhere, so that it is merely a temporary structure. But a std::list that owns the elements, should be holding values. Usual exceptions for polymorphic types apply.

A vector of pointers is more useful, but for particles in particular it many not be needed.

Quote:I'm not sure that swapping the vector positions so the particle is at the end then popping back would be faster than simply removing a node in an std::list. That is of course when the list is just pointers - it would be plenty faster if it was allocating all the data in the particle.


Due to purely hardware reasons (memory cache), this operation will outperform non-continous memory in many cases, even when particles are big (< 96 bytes). This is not a C++ issue, but a consequence of current CPU/memory designs.

Memcpy (which is what is often the case with particles) can copy 1-4 bytes per cycle (depends a lot) when memory is continuous. Dereferencing a pointer however can cause various cache misses and branch stalls (again, depends a lot), which can cost several hundred CPU cycles (yet again, depends).

So in extreme theoretical case, it may be cheaper to copy several hundred bytes than to move pointers. In practice, the difference will be smaller. For reasonably-size particles, in practice, it will be about factor of 2 for typical use of such structures.

Quote:And by the way, a container of pointers is *always* wrong, period.


Unless container needs to hold polymorphic classes, in which way it cannot reasonably be implemented in any other way.
The problem with containers of pointers is exception-safety.

Quote:Bullshit. It's such a useful construct that boost provides several containers exactly designed to handle pointers.

You're missing the point.

Quote:Unless container needs to hold polymorphic classes, in which way it cannot reasonably be implemented in any other way.

Sure it can. Make it contain a value type that exhibits polymorphic behaviour.
So called smart pointers, for example.
Quote:Original post by loufoque
The problem with containers of pointers is exception-safety.

Quote:Bullshit. It's such a useful construct that boost provides several containers exactly designed to handle pointers.

You're missing the point.

Quote:Unless container needs to hold polymorphic classes, in which way it cannot reasonably be implemented in any other way.

Sure it can. Make it contain a value type that exhibits polymorphic behaviour.
So called smart pointers, for example.
What if you've got a list of function pointers for a callback system? They don't need to be cleaned up and you can't put them in a smart pointer object.
[size=2][ I was ninja'd 71 times before I stopped counting a long time ago ] [ f.k.a. MikeTacular ] [ My Blog ] [ SWFer: Gaplessly looped MP3s in your Flash games ]
Quote:Original post by loufoque
The problem with containers of pointers is exception-safety.


boost's pointer containers are safe. You can also trivially make your own wrapper for a pointer container which clears the pointers when the wrapper is destructed. Also, you can use a container of boost::shared_ptr or any of a half-dozen other smart pointer classes.

Quote:You're missing the point.


No, you're missing the point. You made a blanket "always" assertion, which are almost always false in the first place, but you've also been given examples to counteract your opinion.

Quote:Sure it can. Make it contain a value type that exhibits polymorphic behaviour.
So called smart pointers, for example.


Value types do not support dynamic dispatch in C++ because of the slicing problem. At the base, you have to have either a reference type or a pointer type to use polymorphism. If you investigate those smart pointers you mentioned, you'll find that - gasp! - they wrap pointers internally, which is why they can appear to be polymorphic value types.

Wielder of the Sacred Wands
[Work - ArenaNet] [Epoch Language] [Scribblings]

Quote:Original post by ApochPiQ
Quote:Original post by loufoque
And by the way, a container of pointers is *always* wrong, period.


Bullshit. It's such a useful construct that boost provides several containers exactly designed to handle pointers.


FFS, guys. He means a container of raw pointers.
You know, you're right. I was far more forceful (not to mention rude) than I should have been.

My apologies to loufoque.

Wielder of the Sacred Wands
[Work - ArenaNet] [Epoch Language] [Scribblings]

This topic is closed to new replies.

Advertisement