Volatile not useful for Atomic class


#1

I just checked the juce atomic operations and can see the templated class still uses the keyword volatile. Can anyone give me a good reason why this is used? 

line 153 of juce_Atomic.h in the latest tip dated 16 May 2014:

    volatile Type value;

https://software.intel.com/en-us/blogs/2007/11/30/volatile-almost-useless-for-multi-threaded-programming

This will just cause everything to slow down and it won't help with any multi-threading issues. If the memory inside is always swapped / incremented with memory barrier than that is all that is needed, and will give optimal performance.


#2

I vaguely remember it was because some of the OS functions for atomic ops took parameters which were marked as volatile, so this was to keep the compiler happy.

TBH an item on my to-do-list that I must get round to is to make the Atomic class use the new C++11 atomics now that compilers support it, and to leave the current implementation as a legacy fallback.


#3

I see the confusion. The underlying data doesn't have to be volatile, you just cast it to be volatile for the function call alone, that is all you need otherwise you take a performance hit for nothing.


#4

I found the JUCE Atomic classes were slow in my processors… I was wondering if/when you plan to make it use the std atomics (and can LinearSmoothedValue be updated to use them)?

Cheers,

Rail


#5

We certainly will wrap the std::atomic classes, but I’d like to know more about the idea that our atomics are slow! They really don’t do anything beyond wrapping the same OS/intrinsic functions that the std library must also be using - I’d be really surprised if the std classes didn’t produce almost exactly the same assembly code. If you could share some benchmark code, we’d take a look…


#6

I’ll try and make time this weekend to make a benchmark app.

Thanks,

Rail


#7

interesting topic, of course compareAndSet somehow needs to synchronize/interrupt access to the cache, otherwise it wouldn’t work.


#8

Hi Rail,

Try removing the “volatile” keyword on line 155 of juce_Atomic.h, ie

change:

volatile Type value;

to:

Type value;

As already I already pointed out and cited a reference to, making the class member volatile is useless and just slows things down, but this fix still hasn’t been added to the Juce source code.


#9

Hi Andrew - sorry, we didn’t know you’d already suggested that - we’ll try it now and see if everything still works.

IIRC the volatile was there because some atomic intrinsic functions (on Windows, I think…) actually took a volatile* as their argument. It’s surprising to think that the compiler would produce suboptimal code with the keyword there, since having the memory fences around should mean that it has to re-read it anyway, but if this is an easy optimisation, great!


#10

Hi Andrew,

I was able to improve my plugin which has a lot of processors by a significant amount by removing the use of JUCE Atomic… and then found this thread… I suspected the volatile variable was the issue… but hadn’t tested it yet.

Thanks,

Rail


#11

I thought I was being pretty clear, so sorry for not being more explicit about what needed to be done for the fix. I figured if you read the link in my first post all would be clear. I strongly recommend you read it now, here it is again:

https://software.intel.com/en-us/blogs/2007/11/30/volatile-almost-useless-for-multi-threaded-programming


#12

Oh, you were totally clear! I think it just slipped under the radar - thanks for giving us a nudge again!