gpt4 book ai didi

c++ - 为什么std::fetch_add返回旧值?

转载 作者:行者123 更新时间:2023-12-02 09:59:59 28 4
gpt4 key购买 nike

有哪些设计目的或技术限制使std::fetch_add的返回值变为更改前的值?

最佳答案

两种方法都没什么大不了的,您可以在另一种方面效仿。例如如果需要,可以使用val.add_fetch(1)实现1 + val.add_fetch(1)。但是,GNU C __atomic builtins provide both
ISO C / C++仅提供fetch_add而不是add_fetch的可能原因:在某些情况下,它使得在x86上实现成本更低; lock xadd [mem], reg 保留reg = mem的旧值,mem = sum。提供该原语而不是其他原语会鼓励人们围绕该构造块设计算法,从而可能避免需要额外的add指令。
大多数具有LL / SC原子的RISC ISA都有3个操作数指令,因此如果以后需要,它们可以add dst, src1, src2并将内存中的值保留在另一个寄存器中而不受干扰。 (LL / SC fetch_add(x)通常将实现为load-linked reg1, [mem] / add reg2, reg1, x / store-conditional reg3, reg2, [mem]。基于reg3中成功/失败结果的重试循环。如果未使用fetch_add返回值,则add可以覆盖reg1而不是使用新的reg。
因此,在大多数RISC上,这两种方法都可以,而且x86是关心效率更高的ISA之一。

对于某些用例,fetch_add也是您想要的。例如对于在基于数组的循环缓冲区无锁队列中抓取存储桶的线程(以std::atomic<unsigned> write_idx;开头为零初始化),您希望.fetch_add0开头。

  static std::atomic<unsigned> write_idx = 0;  // shared var

// in each thread:
unsigned my_buf = write_idx.fetch_add(1) & ((1<<size) - 1);
您将获得以 0而不是 1开头的值。对于许多用例,这似乎是一个合理的模式。

关于c++ - 为什么std::fetch_add返回旧值?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63108083/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com