【问题标题】:How many clock cycles to modify C++11 atomic bool?修改 C++11 atomic bool 需要多少个时钟周期?
【发布时间】:2013-09-16 18:59:19
【问题描述】:

我想知道假设它使用最严格的内存模型设置,修改 std::atomic(或 atomic_flag)需要多少时钟周期?

【问题讨论】:

  • 你遗漏了很多关键信息:什么处理器(架构、型号、类型),你修改它时的数据在哪里(缓存、主内存、另一个处理器的缓存),系统中还有多少其他处理器,这些处理器中有多少拥有原子变量的副本?
  • 说 Linux Ubuntu 12.04、2.5 GHz 和 Intel 64 位架构。我想我关心的场景是该值已经在 L1 缓存中。然后还有另外两种情况:1)没有其他线程在运行,2)多个线程访问该变量,但为简单起见,假设只有一个生产者和消费者(绑定在不同的内核上)。
  • 几十到几千之间...这不是一个足够好的答案吗?
  • 这是一个有点傻的问题,答案是:0.5 到 1,000,000 个周期,取决于 a) 实现是否无锁 b) 是否存在拥塞,以及 c) 是否存在数据依赖。如果它是在没有拥塞和数据依赖的情况下的无锁实现,它以 CPU 可以启动新整数指令的速度运行(通常每个时钟 2-4 条)。对于数据依赖性,大约需要 20 个周期(或者在 NUMA 系统的不同内核上多 3-5 倍)。否则,由于拥塞或锁定,它需要......任何......数量的周期。
  • 好吧,我想原子变量是无锁的,应该在活动线程到达它时立即执行。

标签: c++ performance c++11 concurrency atomic


【解决方案1】:

很难确定它实际需要多少个时钟周期。相反,我将尝试解释实际发生的情况,如果我们假设它是 x86 处理器(如评论中所述),并且运行时库使用“锁定”指令实现 atomic - 如果这些假设中的任何一个是错误的,那么就像俗话说的“所有赌注都关闭”:

当执行atomic 操作时,CPU 将首先确保它对(潜在的)缓存值具有“独占”访问权。这意味着向所有其他 CPU 发送一条消息,说“我是 it 这个变量”。然后每个其他 CPU 必须刷新其副本(如果已修改)并将值标记为“无效”,然后回复“我完成了”。

一旦所有处理器都说“我完成了”,主处理器就可以继续。这个过程,尤其是在具有大量 CPU(内核)的大型系统中,可能需要相当长的时间(数百或数千个周期)。

当然,CPU 可以通过知道没有其他 CPU 读取该值,或者没有其他 CPU 对该值发出写操作来优化这一点,在这种情况下,它可以非常快。

您也许可以通过编写一些代码来了解[在特定机器上]这有多糟糕,您可以在两个线程中循环循环例如 1 秒,尝试更新和读取相同的原子变量,看看它有多好/坏。然后尝试两个“更新”循环(这样你就可以在两个线程之间进行更新)。

【讨论】:

    【解决方案2】:

    这与访问未缓存的主内存大致相同。大约 100-1000 ns,或大约 100 个时钟周期。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-10-27
      • 2015-10-08
      • 2021-05-09
      • 1970-01-01
      • 1970-01-01
      • 2017-11-24
      • 1970-01-01
      相关资源
      最近更新 更多