[[carries_dependency]] used to allow dependencies to be carried through function calls. This potentially allows the compiler to generate better code when used with std::memory_order_consume to pass values ββbetween threads on platforms with poorly ordered architectures such as the IBM POWER architecture.
In particular, if a value read using memory_order_consume is passed to a function, then without [[carries_dependency]] , the compiler may have to issue a memory save command to ensure that the appropriate semantics of memory ordering are maintained. If the parameter is annotated using [[carries_dependency]] , then the compiler may assume that the function body will correctly transport the dependency, and this fence will no longer be needed.
Similarly, if a function returns a value loaded with memory_order_consume or obtained from that value, then without [[carries_dependency]] compiler may need to insert a guard command to ensure that the appropriate semantics of memory ordering are maintained. With the annotation [[carries_dependency]] this fence may not be needed, since the caller is responsible for maintaining the dependency tree.
eg.
void print(int * val) { std::cout<<*p<<std::endl; } void print2(int * [[carries_dependency]] val) { std::cout<<*p<<std::endl; } std::atomic<int*> p; int* local=p.load(std::memory_order_consume); if(local) std::cout<<*local<<std::endl;
In line (1), the dependency is explicit, so the compiler knows that local dereferenced and that it must ensure that the dependency chain is preserved in order to avoid being protected from POWER.
On line (2), the definition of print opaque (unless specified), so the compiler must throw a fence to make sure that reading *p in print returns the correct value.
On line (3), the compiler can assume that although print2 also opaque, then the dependency on the parameter to the dereferenced value is stored in the command stream, and no fence is required in POWER. Obviously, the definition of print2 should actually preserve this dependency, so the attribute will also affect the generated code for print2 .
Anthony Williams Jun 20 '11 at 13:14 2011-06-20 13:14
source share