On
Monday, September 15, 2014 07:31 PM, Tim Odenthal wrote:
Dear experts,
essentially, I use this type of reinterpret_cast for doubles, and it __seems__ to work fine. I compile-time check that the sizeof(boost::atomic<T>) == sizeof( T ), but is that enough to ensure that this will always work? Should/could I check alignment issues
as well? Even if the "atomic_cast" function has a (small) run-time overhead, it would be very much worth it in my setting, where I actually want to safely add to a double at some location in memory. Obviously, I want to use boost::atomic to be system/compiler
agnostic, since it's supposed to eventually run with clang, gcc, (linux, OS X) as well as MS compilers, and so far we didn't see the need to move to C++11...
I'm
not sure I can figure out what problem you're trying to solve.
Well, essentially, I have an array of doubles that at exactly one point in the code needs to be added to where I cannot ensure that each thread only adds to its own part of the array, so I want to ensure that each addition there is executed atomically.
I
think the cast is probably "safe", but far less can be said of it when
it's
dereferenced. That would depend entirely on the type of var.
Is
*var actually a boost::atomic<T> in the first place? If it is, why
are
you erasing its type?
No, as I was saying, it’s a double *.
How
can you be sure there is nobody else aliasing var or *var and then
reading
or writing it?
That is actually a problem, but since I completely control that part of the code, I hope to not make that mistake ;-).
If
*var is not a boost::atomic<T>, reinterpret_cast isn't going to
magically
convert it, you have undefined behaviour. Of course, one
effect
of UB is that it __seems__ to work, until, presumably, it doesn’t.
But what, then, is the difference between an atomic<double>* and a normal double*, if the sizes (and possibly alignments) are the same?
Hmmm, I just read up on what a reinterpret_cast<> is supposed to be good for, which is very little indeed, so it seems that the behaviour is undefined - but then there is no way to solve that problem? (So far I only ever used it to print the address of
a pointer...)
Since openMP allows for a pragma atomic, somehow, it seems that there should be a way. Using a simple spin_lock is way too slow (tested), since it doesn’t lock a specific memory location, but essentially everything, and I suspect that more complicated
locking schemes will be also more expensive, just for different reasons.
Ben
Thanks for your insight!
Tim