[英]Why does std::barrier allocate?
Why does std::barrier
allocate memory on the heap while std::latch
doesn't?为什么std::barrier
在堆上分配内存而std::latch
没有?
The main difference between them is that std::barrier
can be reused while std::latch
can't, but I can't find an explanation on why this would make the former allocate memory.它们之间的主要区别在于std::barrier
可以重用,而std::latch
不能,但我找不到解释为什么这会使前者分配内存。
While it is true that a naive barrier could be implemented with a constant amount of storage as part of the std::barrier
object, real-world barrier implementations use structures that have > O(1) storage, but better concurrency properties.虽然可以使用作为std::barrier
对象的一部分的恒定存储量来实现一个简单的屏障,但现实世界的屏障实现使用具有 > O(1) 存储但更好的并发属性的结构。 The naive, constant-storage barrier can suffer from a large number of threads contending on the same counter .天真的、恒定存储屏障可能会受到大量线程在同一个计数器上竞争的影响。 Such contention can lead to O(N) runtime to release threads from the barrier.这种争用可能导致 O(N) 运行时从屏障中释放线程。
As an example of a "better" implementation, the gcc libstdc++ implementation uses a tree barrier .作为“更好”实现的示例, gcc libstdc++ 实现使用树屏障。 This avoids the contention on a single counter/mutex shared among all threads, and a tree barrier can propagate the "barrier done, time to release" signal in logarithmic time, at the expense of needing linear space to represent the thread tree.这避免了在所有线程之间共享的单个计数器/互斥锁上的争用,并且树屏障可以在对数时间内传播“屏障完成,释放时间”信号,代价是需要线性空间来表示线程树。
It's not too difficult to imagine enhanced tree-style barrier implementations that are aware of cache/socket/memory bus hierarchy, and group threads in the tree based on their physical location to minimize cross-core, cross-die, and cross-socket polling to the minimum required.不难想象增强的树型屏障实现知道缓存/套接字/内存总线层次结构,并根据它们的物理位置对树中的线程进行分组,以最大限度地减少跨核、跨芯片和跨套接字轮询到最低要求。
On the other hand, a latch is a much more lightweight synchronization tool.另一方面,闩锁是一种更轻量级的同步工具。 However, I'm not quite sure why a latch would be forbidden to allocate - cppreference states,但是,我不太确定为什么会禁止分配锁存器 - cppreference状态,
The latch class is a downward counter of type
std::ptrdiff_t
锁存器类是std::ptrdiff_t
类型的向下计数器
which would indicate that it should not allocate (ie it's just a counter and has no space to hold a pointer to an allocated object).这表明它不应该分配(即它只是一个计数器并且没有空间来保存指向已分配对象的指针)。 On other hand, [thread.latch] in the standard says nothing more than "A latch maintains an internal counter that is initialized when the latch is created" without forbidding it from allocating.另一方面,标准中的[thread.latch]只不过是“一个锁存器维护一个在创建锁存器时初始化的内部计数器”,而不禁止它分配。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.