ybu*_*ill 68 c++ multithreading memory-model c++11 carries-dependency
有人能用一种凡人理解的语言解释它吗?
Ant*_*ams 53
[[carries_dependency]]用于允许跨函数调用传递依赖项.这可能允许编译器在用于std::memory_order_consume在具有弱有序体系结构(例如IBM的POWER体系结构)的平台上的线程之间传输值时生成更好的代码.
特别是,如果读取的值memory_order_consume传入函数,然后没有[[carries_dependency]],则编译器可能必须发出内存栅栏指令以保证维持适当的内存排序语义.如果参数使用注释,[[carries_dependency]]则编译器可以假定函数体将正确地携带依赖性,并且可能不再需要此栅栏.
类似地,如果函数返回memory_order_consume从这样的值加载或从该值导出的值,则[[carries_dependency]]可能不需要编译器插入fence指令以保证维持适当的存储器排序语义.使用[[carries_dependency]]注释,可能不再需要此栅栏,因为调用者现在负责维护依赖关系树.
例如
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; // 1
if(local)
print(local); // 2
if(local)
print2(local); // 3
Run Code Online (Sandbox Code Playgroud)
在第(1)行中,依赖是显式的,因此编译器知道它local被解除引用,并且它必须确保保留依赖关系链以避免POWER上的栅栏.
在第(2)行中,定义print是不透明的(假设它没有内联),因此编译器必须发出一个fence,以确保读*p入print返回正确的值.
在第(3)行,编译器可以假设虽然print2也是不透明的,但是从参数到解除引用的值的依赖性保留在指令流中,并且在POWER上不需要栅栏.显然,定义print2必须实际保留这种依赖关系,因此该属性也会影响生成的代码print2.
| 归档时间: |
|
| 查看次数: |
8265 次 |
| 最近记录: |