繁体   English   中英

x86轻松订购性能?

[英]x86 relaxed ordering performance?

由于intel提供了强大的硬件内存模型,在C ++ 11程序中使用“memory_order_relaxed”是否有任何优势? 或者只是保持默认的“顺序一致”,因为它没有区别?

像计算机科学中的大多数答案一样,答案就是“这取决于”。

首先,顺序一致排序永远不会带来任何惩罚的想法是不正确的。 根据您的代码(以及可能的编译器),它可以并且将带来惩罚。

其次,要对内存排序约束做出明智的决策,您需要考虑(并理解)您如何使用所涉及的数据。

memory_order_relaxed对于像独立计数器这样的东西很有用,它需要是原子的,但与其他东西没有直接关系,所以它不需要与任何“其他东西”保持一致。 典型示例是引用计数,例如在shared_ptrstd::string一些较旧实现中。 在这种情况下,我们只需要确保计数器以原子方式递增和递减,并且对它的修改对所有线程都是可见的。 但是,特别是,没有任何相关数据需要保持一致,因此我们不关心它对其他任何事物的排序。

顺序一致的排序几乎是相反的极端。 它可能是最容易应用的 - 你编写的代码就像单线程一样,并且实现确保它正常工作(这并不是说你根本不需要考虑线程,而是顺序一致的排序)通常需要最少的考虑,但通常也是最慢的模型)。

当您有两条或更多相关信息时,通常会使用获取/发布一致性,并且您需要确保只有一条信息在另一条信息之前/之后变得可见。 对于我最近处理的一个例子,让我们假设你正在构建一个大致类似于内存数据库的东西。 你有一些数据,并且你有一些元数据(并且你或多或少地分别存储)。

使用元数据(以及其他内容)来搜索数据库。 我们想确保如果有人发现某些特定数据,他们发现的数据实际上会存在于数据库中。

为了确保这一点,我们希望确保数据始终存在于元数据之前,并且至少与元数据一样长。 如果某人可以使用元数据搜索数据库,并且在该数据实际不存在时找到它想要使用的数据,则数据库将是不一致的。

所以在这种情况下,当我们添加记录时,我们需要确保首先添加数据,然后添加元数据 - 编译器不能重新排列这两个。 同样,当我们删除记录时,我们需要删除元数据(因此没有人会找到数据),然后删除数据本身。 对于数据本身,我们可能有一个引用计数来跟踪当前访问该数据的客户端数量,以确保在有人尝试使用它时我们不会删除它。

因此,在这种情况下,我们可以对元数据和数据使用获取/释放语义,并放宽引用计数的顺序。 或者,如果我们想让代码尽可能简单,我们可以在整个过程中使用顺序一致性 - 即使它可能(并且可能会)至少带来一些惩罚。

始终使用您所需的最低保证来使您的代码正确无误。

不多也不少。

这样,您可以避免对实现的任何不必要的依赖性,从而减少任何移植成本,并仍然可以获得最快的程序。

当然,如果您确定不会关心移植任何代码,那么在您知道平台无关紧要的情况下采取更有力的保证可能会使其更容易正确。
更难以滥用,更容易推理或更短是使用性能较低的结构的完全可接受的原因。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM