
Hello Helge, What would it take to get this code to work? std::vector<boost::atomic<Something> > v; v.resize(100); best regards -- Janek Kozicki http://janek.kozicki.pl/ |

Janek Kozicki said: (by the date of Fri, 30 Apr 2010 17:04:53 +0200)
What would it take to get this code to work?
std::vector<boost::atomic<Something> > v; v.resize(100);
Just for the question to be complete, that's my Something class: class Something { private: int val; public: Something(){}; Something(int i):val(i){}; void set_val(int i) {val=i;}; int get_val() {return val;}; }; But that 'int' is just a placeholder. This class is intended to be a bit more complex... best regards -- Janek Kozicki http://janek.kozicki.pl/ |

On Fri, 30 Apr 2010 17:04:53 +0200, Janek Kozicki <janek_listy@wp.pl> wrote:
What would it take to get this code to work?
std::vector<boost::atomic<Something> > v; v.resize(100);
Hi Janek, I'd like to know what's your goal when you declare a vector of "atomic" variables. What is the result you are looking for? Regards. -Edouard

edouard@fausse.info said: (by the date of Fri, 30 Apr 2010 17:12:50 +0200)
On Fri, 30 Apr 2010 17:04:53 +0200, Janek Kozicki <janek_listy@wp.pl> wrote:
What would it take to get this code to work?
std::vector<boost::atomic<Something> > v; v.resize(100);
Hi Janek,
I'd like to know what's your goal when you declare a vector of "atomic" variables. What is the result you are looking for?
This is for YADE, our software for discrete modelling. Imagine a std::vector of 125000 spheres: https://yade-dem.org/wiki/Screenshots_and_videos#Ball_Mill_-_125_000_spheres it is currently parallelized with OPEN MP, but there are some global locks in few places. Saying that each sphere is atomic (instead of locking whole container) would solve the problem. best regards -- Janek Kozicki http://janek.kozicki.pl/ |

This is for YADE, our software for discrete modelling.
Imagine a std::vector of 125000 spheres:
https://yade-dem.org/wiki/Screenshots_and_videos#Ball_Mill_-_125_000_sphere s
it is currently parallelized with OPEN MP, but there are some global locks in few places. Saying that each sphere is atomic (instead of locking whole container) would solve the problem.
Actually you will only add problems if you do that. You need to use a concurrent container, not a classical containers with atomics variables. First, atomic is more expensive than you think, to convince yourself of this, benchmark the two following codes: int i = 0; while(i < 10 * 1000 * 1000) ++i; and atomic<int> i = 0; while(i < 10 * 1000 * 1000) ++i; Second, you will lock nevertheless because your memory entries will belong to the same cache line. You need to use a special allocator that makes sure that each entry doesn't overlap so that reading and writing to a slot will not result in false sharing. Third, wrapping a variable in atomic doesn't magically make your variable immune to the reader/writer problem (or other synchronization problems). You probably want access to your object to be atomic, in which case a container that guarantees that affectation to an entry is atomic is enough for you. Making your business logic reader/writer proof is generally more complex than a simple atomic<> wrapping. All in all, I think that what you need is a concurrent_vector<T> not a vector<atomic<T>>. Regards. -Edouard __________ Information from ESET NOD32 Antivirus, version of virus signature database 5075 (20100430) __________ The message was checked by ESET NOD32 Antivirus. http://www.eset.com

Edouard A. wrote:
Actually you will only add problems if you do that. You need to use a concurrent container, not a classical containers with atomics variables.
If you do nothing but mutate the stored objects, then it should be fine without a concurrent container.
First, atomic is more expensive than you think, to convince yourself of this, benchmark the two following codes:
int i = 0; while(i < 10 * 1000 * 1000) ++i;
Will probably be optimized to nothing, so it's not really a good example.

Edouard A. said: (by the date of Fri, 30 Apr 2010 18:36:13 +0200)
This is for YADE, our software for discrete modelling.
Imagine a std::vector of 125000 spheres:
https://yade-dem.org/wiki/Screenshots_and_videos#Ball_Mill_-_125_000_sphere s
it is currently parallelized with OPEN MP, but there are some global locks in few places. Saying that each sphere is atomic (instead of locking whole container) would solve the problem.
Actually you will only add problems if you do that. You need to use a concurrent container, not a classical containers with atomics variables.
First, atomic is more expensive than you think, to convince yourself of this, benchmark the two following codes:
int i = 0; while(i < 10 * 1000 * 1000) ++i;
and
atomic<int> i = 0; while(i < 10 * 1000 * 1000) ++i;
Second, you will lock nevertheless because your memory entries will belong to the same cache line. You need to use a special allocator that makes sure that each entry doesn't overlap so that reading and writing to a slot will not result in false sharing.
yes, the cache line issue seems to be our problem right now.
Third, wrapping a variable in atomic doesn't magically make your variable immune to the reader/writer problem (or other synchronization problems). You probably want access to your object to be atomic, in which case a container that guarantees that affectation to an entry is atomic is enough for you. Making your business logic reader/writer proof is generally more complex than a simple atomic<> wrapping.
All in all, I think that what you need is a concurrent_vector<T> not a vector<atomic<T>>.
The one from intel thread building blocks? Or another one? I don't see it in boost, unfortunately (or I'm blind?). I would prefer to avoid adding another large library to our dependencies. We will consider it, though. thank you for longer explanation. I am investigating the possibilities. best regards -- Janek Kozicki http://janek.kozicki.pl/ |

The one from intel thread building blocks? Or another one? I don't see it in boost, unfortunately (or I'm blind?). I would prefer to avoid adding another large library to our dependencies. We will consider it, though.
Yes, I was referring to tbb::concurrent_vector, there are probably a lot of things inside TBB that will help you. -- EA __________ Information from ESET NOD32 Antivirus, version of virus signature database 5075 (20100430) __________ The message was checked by ESET NOD32 Antivirus. http://www.eset.com

Janek Kozicki wrote:
Hello Helge,
What would it take to get this code to work?
std::vector<boost::atomic<Something> > v; v.resize(100);
Hi, just to understand better your concern. What kind of problems do you expect to have? have you already tried it? What do you expect from the atomic library? Best, Vicente -- View this message in context: http://old.nabble.com/boost-atomic-question-tp28413326p28413638.html Sent from the Boost - Dev mailing list archive at Nabble.com.

Vicente Botet Escriba said: (by the date of Fri, 30 Apr 2010 08:33:04 -0700 (PDT))
What would it take to get this code to work? std::vector<boost::atomic<Something> > v; v.resize(100);
Hi, just to understand better your concern.
What kind of problems do you expect to have?
A dynamic simulation of thousands / millions of elements.
have you already tried it?
It is already implemented, with OPEN MP and several global locks. We have a speed-up of x5 times on 8 cores. https://yade-dem.org/wiki/Screenshots_and_videos#Ball_Mill_-_125_000_spheres
What do you expect from the atomic library?
I would like to simplify our current code, shorten it by replacing mutexes with boost::atomic in places where I could do that. Mainly I am hoping to remove global container locks. The fact is that when calculating the dynamic equations for thousands of elements, there is no conflict about the order in which they are processed, it can be done simultaneously (so we divide whole container into equal parts and process them in parallel). But also, while being calculated the elements are drawn on a screen by separate thread (a read-only). And also they can be accessed (read-write) from python shell, in realtime, during the calculation. An example of accessing the data in realtime, during calculation is shown on this video: http://geo.hmg.inpg.fr/~janek/yade-videos/buldozer.mpg http://geo.hmg.inpg.fr/~janek/yade-videos/longer-yade-builtin-help.mpg (there are other videos too in that directory). You can read about our software here: https://yade-dem.org/ https://www.yade-dem.org/sphinx/index.html https://www.yade-dem.org/epydoc/ https://www.yade-dem.org/doxygen/ best regards -- Janek Kozicki http://janek.kozicki.pl/ |

Janek Kozicki wrote:
Vicente Botet Escriba said: (by the date of Fri, 30 Apr 2010 08:33:04 -0700 (PDT))
have you already tried it?
It is already implemented, with OPEN MP and several global locks. We have a speed-up of x5 times on 8 cores.
What Vicente asked is whether you tried the bit of code you showed.

Mathias Gaunard said: (by the date of Fri, 30 Apr 2010 17:34:21 +0100)
Janek Kozicki wrote:
Vicente Botet Escriba said: (by the date of Fri, 30 Apr 2010 08:33:04 -0700 (PDT))
have you already tried it?
It is already implemented, with OPEN MP and several global locks. We have a speed-up of x5 times on 8 cores.
What Vicente asked is whether you tried the bit of code you showed.
ah, yes. If you comment out the 'Something' part, the attached code will work. (after you download the boost atomic library) -- Janek Kozicki http://janek.kozicki.pl/ |

On Fri, Apr 30, 2010 at 5:04 PM, Janek Kozicki <janek_listy@wp.pl> wrote:
Hello Helge,
What would it take to get this code to work?
std::vector<boost::atomic<Something> > v; v.resize(100);
It'll never work: atomic<T> has a deleted copy constructor, and standard containers only work with copyable types. For atomic<T> to work, T must be trivially copyable (basically it must be a POD). Unless T is small (<= 64 bits) i'd expect atomic<T> to be implemented with a (per-object) mutex, but: 'atomic<T>' only supports a few operations (it does not reexport T's interface), so you'd have to reimplement your methods in terms of that limited set operations. If you are not familiar with lock-free coding you might be better off explicitly adding a mutex to 'Something', and implementing your methods the traditional way. br, andras
participants (6)
-
Andras Erdei
-
Edouard A.
-
edouard@fausse.info
-
Janek Kozicki
-
Mathias Gaunard
-
Vicente Botet Escriba