简体   繁体   English

为什么 std::barrier 分配?

[英]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.

相关问题 为什么std :: latch如果有std :: barrier? - Why std::latch if there is std::barrier? 为什么std :: deque在默认构造函数中为其元素分配内存? - Why does std::deque allocate memory for its elements in the default constructor? std :: atomic访问是否充当内存屏障? - Does std::atomic access serve as a memory barrier? 为什么 C++ 引入了单独的 std::latch 和 std::barrier? - Why C++ has introduced separate std::latch and std::barrier? 为什么这个分配器不适用于`std::allocate_shared`? 奇怪的模板替换错误 - Why does this allocator not work with `std::allocate_shared`? Bizarre template substitution errors std :: vector如何分配对象? - How does std::vector allocate objects? std :: vector在哪里分配其内存? - Where does a std::vector allocate its memory? 为什么 Clang 分配 std::complex 这么快? - Why Clang allocate std::complex so fast? 为什么boost :: allocate_shared <T> (alloc)忽略alloc.construct()并执行std :: allocate_shared <T> (alloc)表现如何? - Why does boost::allocate_shared<T> (alloc) ignore alloc.construct() and does std::allocate_shared<T> (alloc) behave alike? 为什么MPI_Barrier在C ++中导致分段错误 - Why does MPI_Barrier cause a segmentation fault in C++
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM