I'm desperatly trying for a week to add one float (at some place in memory) onto another float (at some other place), in an atomic way. Meaning, multiple threads should be able to add values to this memory location without interfering.
I don't wanna use mutex this they would slow down the process a lot.
I couldn't find any answer to this ! Any idea ?
(I just need to do an add, nothing else, no need for a full atomic float class if the problem is simplified this way)
that's precisely my problem: AFAIK, there's no such thing as "std::atomic<float>", only int types are supported, specially when it comes to add operation (unless I'm missing something ?). http://msdn.microsoft.com/en-us/library/hh874894.aspx
Have you enabled C++11 support? Because it does indeed work for me. Do you get a compile time error claiming that this specialization does not exist? Does it exist for integer specializations?
There is no specialization for std::atomic<float>.
We can instantiate the std::atomic<T> generalization with T as float, but it won't have the atomic arithmetic operations. (Specializations for integral types support arithmetic operations.)
Can't you use a simulated fixed point type for the floating point value?
Thanks for the tip JLBorges, unfortunately approximation like theses are not an option in my application. I guess I'll have to find another way to achieve what I want to do.
What does this print out on your implementation? std::cout << std::numeric_limits<float>::digits10 << '\n' ;
The standard 32-bit IEEE 754 floating-point type has a 24 bit fractional part (23 bits written, one implied), which may suggest that it can represent 7 digit decimals (24 * std::log10(2) is 7.22), but relative rounding errors are non-uniform and some floating-point values with 7 decimal digits do not survive conversion to 32-bit float and back: the smallest positive example is 8.589973e9, which becomes 8.589974e9 after the roundtrip. These rounding errors cannot exceed one bit in the representation, and digits10 is calculated as (24-1)*std::log10(2), which is 6.92. Rounding down results in the value 6.
- http://en.cppreference.com/w/cpp/types/numeric_limits/digits10
Sure float is an approximation, but just multiplying by 100000 won't handle cases where my float is a very large number, or a very small number - I deal with all kind of scale in my application.
> won't handle cases where my float is a very large number, or a very small number
Yes, the range is a serious problem.
> I just need to do an add, nothing else
If that is the case (the modified value is not read back till the end), you would be able to accumulate several adds into a local variable, and then do a single bulk add (with a mutex) periodically (say, at the end of an inner loop).