thread safe vst

DSP, Plugin and Host development discussion.
RELATED
PRODUCTS

Post

matt42 wrote:OK so if I specify a volatile float then I can expect single load/stores to be atomic.
Volatile has nothing to do with reads/writes being atomic AFAIK.

For atomic reads and writes the variables just need to be naturally aligned, which they will be for 4 byte size variables unless you actually messed with the default alignment settings.

The 'volatile' keyword does 2 things...

1. It stops a variable from being held in a register so that whenever it is referenced it is always read from memory. Basically it tells the compiler "this variable can be modified by multiple threads so to make sure you always have the latest value you must access it from memory"

2. It prevents the compiler from reordering it with respect to code around it, so things are always done in the order you have written.

Post

nollock wrote:The 'volatile' keyword does 2 things...

1. It stops a variable from being held in a register so that whenever it is referenced it is always read from memory. Basically it tells the compiler "this variable can be modified by multiple threads so to make sure you always have the latest value you must access it from memory"

2. It prevents the compiler from reordering it with respect to code around it, so things are always done in the order you have written.
How about dynamically allocated arrays? Can an array be declared volatile? Should it? when it's values are accessed from different threads even if the access is well synchronized. How about other than primitive types? Are members of a volatile class variable also implicitly declared volatile?

Post

nollock wrote: 2. It prevents the compiler from reordering it with respect to code around it, so things are always done in the order you have written.
Strictly speaking, the language spec only requires that operations on volatile variables not be reordered with respect to other "volatile" loads/stores; the keyword was designed for MMIO rather than inter-thread synchronization.

In practice I believe (though don't take this for truth) that only ICC is aggressive enough to require explicit compiler fences (for which it provides it's own intrinsics though).

Post

mfa wrote:
nollock wrote:The 'volatile' keyword does 2 things...

1. It stops a variable from being held in a register so that whenever it is referenced it is always read from memory. Basically it tells the compiler "this variable can be modified by multiple threads so to make sure you always have the latest value you must access it from memory"

2. It prevents the compiler from reordering it with respect to code around it, so things are always done in the order you have written.
How about dynamically allocated arrays? Can an array be declared volatile? Should it? when it's values are accessed from different threads even if the access is well synchronized. How about other than primitive types? Are members of a volatile class variable also implicitly declared volatile?
This is only an issue if you design your own synchronization primitives, since any properly designed synchronization primitives will cause a compiler fence.

Post

mystran wrote:
mfa wrote:
nollock wrote:The 'volatile' keyword does 2 things...

1. It stops a variable from being held in a register so that whenever it is referenced it is always read from memory. Basically it tells the compiler "this variable can be modified by multiple threads so to make sure you always have the latest value you must access it from memory"

2. It prevents the compiler from reordering it with respect to code around it, so things are always done in the order you have written.
How about dynamically allocated arrays? Can an array be declared volatile? Should it? when it's values are accessed from different threads even if the access is well synchronized. How about other than primitive types? Are members of a volatile class variable also implicitly declared volatile?
This is only an issue if you design your own synchronization primitives, since any properly designed synchronization primitives will cause a compiler fence.
Ok, that's a relief. I take it that windows' critical sections are properly designed regarding this. Thanks!

Post

mfa wrote:How about dynamically allocated arrays? Can an array be declared volatile? Should it? when it's values are accessed from different threads even if the access is well synchronized. How about other than primitive types? Are members of a volatile class variable also implicitly declared volatile?
I dont suppose it would work on anything that wasnt a primitive type. I definately dont see how it could work on an aggregate type.

edit: after a bit of reading it seems you can use volatile on user defined types, it works similarly to const, you can only access volatile methods on a variable that has been delcared volatile. Im thinking about how that would all work and what purpose it could serve. Cant remember ever actualy encountering it tbh.
Last edited by nollock on Wed Jul 06, 2011 6:15 pm, edited 1 time in total.

Post

mystran wrote:Strictly speaking, the language spec only requires that operations on volatile variables not be reordered with respect to other "volatile" loads/stores; the keyword was designed for MMIO rather than inter-thread synchronization.
I didnt know that, but it does make sense.

In practice I believe (though don't take this for truth) that only ICC is aggressive enough to require explicit compiler fences (for which it provides it's own intrinsics though).
I didnt think fences were needed on X86 as it has strong ordering anyway. I mean as long as the actual generated code is in the right order there's nothing else to worry about AFAIK.

Post

nollock wrote:
In practice I believe (though don't take this for truth) that only ICC is aggressive enough to require explicit compiler fences (for which it provides it's own intrinsics though).
I didnt think fences were needed on X86 as it has strong ordering anyway. I mean as long as the actual generated code is in the right order there's nothing else to worry about AFAIK.
Wait, you need to make a difference between "CPU memory fences" and "compiler memory fences." You don't need a CPU fence on x86 because of the strong ordering (ie the ISA mandates that CPUs do not allow reordering to be observable).

Compiler fences are different: they prevent the compilers optimizer from moving loads/stores around. Usually things like function calls (to unknown functions anyway) and access to "volatile" variables (or "volatile asm" blocks) result in implicit compiler fences, and for some things like InterlockedFoobar() there are even variants with different types of fences. On x86 none of this has nothing to do with the CPU. It's just so the compiler's optimizer doesn't do the wrong thing with aggressive reordering.

Now, I remember reading some Intel article about ICC being more aggressive than most compilers and sometimes needing some explicit fences, hence the mention. Unfortunately I can't give the dirty details 'cos I can't seem to find the relevant articles right now. It could be I'm not searching with the right keywords, or it could be it's no longer relevant to latest versions, I don't know.

But just like volatile, as far as CPU goes, on x86 there is absolutely nothing special that needs to be done (except aligned variables, but unaligned variables are stupid for so many other reasons anyway), other than to convince the compiler to generate the correct code (which might mean some form of a compiler fence, unless you use standard synchronization primitives which would have the necessary fences already). :)

Post

mystran wrote: Compiler fences are different: they prevent the compilers optimizer from moving loads/stores around. Usually things like function calls (to unknown functions anyway) and access to "volatile" variables (or "volatile asm" blocks) result in implicit compiler fences, and for some things like InterlockedFoobar() there are even variants with different types of fences.
Its obvious now you point it out. I knew how volatile and such like worked in respect to the compiler reordering stuff, but hadnt spotted the obvious analogy to cpu memory fences.

Cheers :)

Edit: Some googling has turned up this..

http://en.wikipedia.org/wiki/Memory_ord ... ry_barrier

I didnt know about this, so you can avoid volatile altogether and just force the ordering in the places where it is required.

Loverly!

Post

Can anyone comment on how the gui -> process and process -> gui communication works in JUCE? i.e what approach does it use?

thanks,

oli

Post Reply

Return to “DSP and Plugin Development”