相关疑难解决方法(0)

`std :: kill_dependency`做了什么,为什么我要使用它?

我一直在阅读有关新C++ 11内存模型的内容,并且我已经开始使用该std::kill_dependency功能(§29.3/ 14-15).我很难理解为什么我会想要使用它.

我在N2664提案中找到了一个例子,但它并没有多大帮助.

它首先显示代码而不是std::kill_dependency.这里,第一行将依赖性携带到第二行中,第二行将依赖性携带到索引操作中,然后将依赖性携带到do_something_with函数中.

r1 = x.load(memory_order_consume);
r2 = r1->index;
do_something_with(a[r2]);
Run Code Online (Sandbox Code Playgroud)

还有一个例子std::kill_dependency用于打破第二行和索引之间的依赖关系.

r1 = x.load(memory_order_consume);
r2 = r1->index;
do_something_with(a[std::kill_dependency(r2)]);
Run Code Online (Sandbox Code Playgroud)

据我所知,这意味着索引和调用do_something_with不是在第二行之前排序的依赖项.根据N2664:

这允许编译器将调用重新排序do_something_with,例如,通过执行预测值的推测优化a[r2].

为了使得需要调用do_something_with该值a[r2].假设编译器"知道"数组填充了零,它可以根据需要优化该调用do_something_with(0);并相对于其他两个指令重新排序此调用.它可以产生以下任何一种:

// 1
r1 = x.load(memory_order_consume);
r2 = r1->index;
do_something_with(0);
// 2
r1 = x.load(memory_order_consume);
do_something_with(0);
r2 = r1->index;
// 3
do_something_with(0);
r1 = x.load(memory_order_consume);
r2 = r1->index;
Run Code Online (Sandbox Code Playgroud)

我的理解是否正确?

如果do_something_with通过其他方式与另一个线程同步,这对于x.load调用的顺序和另一个线程意味着什么?

假设我的描述是正确的,那还有一件事让我感到困惑:当我编写代码时,是什么原因导致我选择杀死依赖?

c++ multithreading memory-model c++11

57
推荐指数
2
解决办法
3296
查看次数

C++ 11标准是否正式定义了获取,发布和使用操作?

在C++ 11标准,部分1.10/5提到,但不正式定义的术语acquire operation,release operationconsume operation.然后在第29节继续使用这些术语来描述某些内存排序,原子操作和内存栅栏的操作.例如,关于"顺序和一致性"的29.3/1表示:

memory_order_release,memory_order_acq_relmemory_order_seq_cst:存储操作在受影响的内存位置上执行释放操作 [强调添加].

这种类型的语言在第29节中重复出现,但令我烦恼的是,memory_order枚举的所有含义都基于操作类型,这些类型本身似乎没有被标准正式化,但必须对它们有一些共同的意义.作为定义有效.

换句话说,如果我说"一个酒吧是一个翻转的foo",barfoo的具体含义是模棱两可的,因为这两个术语都没有正式定义.只定义了它们的相对性质.

请问C++的11个标准,或其他一些C++ 11标准委员会文件正式准确定义的是什么acquire operation,release operation等等是,或者是这些简单的通常理解的术语?如果是后者,是否有一个很好的参考被认为是这些操作含义的行业标准?我特别要求,因为硬件内存一致性模型不是相同的,因此我认为必须有一些共同商定的引用,允许那些实现编译器等的人正确地将这些操作的语义转换为本机程序集命令.

c++ standards c++11

21
推荐指数
1
解决办法
1088
查看次数

标签 统计

c++ ×2

c++11 ×2

memory-model ×1

multithreading ×1

standards ×1