在实践中,C++11 中 std::atomic 的内存占用是多少?

Posted

技术标签:

【中文标题】在实践中,C++11 中 std::atomic 的内存占用是多少?【英文标题】:What is the memory footprint of std::atomic in C++11, in practice? 【发布时间】:2018-05-28 05:14:35 【问题描述】:

我正在编写的程序需要在 RAM 中存储大量数据(数 GB),以供许多线程以原子方式访问。 std::atomic 似乎是一种合理的方法,因为它的访问可能比将所有访问包装在一个或多个 std::mutexs 中更有效,因为在最坏的情况下,它将在内部使用互斥体并且是等效的。

我的数据被组织成一组Chunk 对象,其中包括一个包含大部分数据的数组成员。现在,我正在考虑将其定义为std::array<std::atomic<unsigned int>, SOME_CONSTANT_HERE>,但这只有在std::atomic 在诸如unsigned int 等内置类型上的内存占用不比unsigned int 本身差的情况下才会有效,因为,根据我的计算,以我需要存储的数据量,目前普通的内存容量勉强够用。

我看到的唯一替代方案(欢迎其他替代方案)是让每个块都有自己的 std::mutex 实例,但这是有问题的,因为通常线程需要同时处理多个块(并非几乎所有, 然而),并且持有多个锁对于死锁都是有问题的,并且会由于各种线程访问哪些块的模式而导致严重的争用。

那么,对于整数类型,std::atomic 的 x86_64 上的实际内存占用是多少?

编辑:我尝试在 Google 上四处搜索,甚至在 GNU 标准库源代码中进行了一些挖掘,但无济于事。

【问题讨论】:

【参考方案1】:

您可以在此处自行检查:https://godbolt.org/g/6zjJCU - 在未启用优化的情况下,std::atomic 和常规变量占用相同的内存量。

然而,区别在于对变量的访问。尝试取消注释该块...您将获得所有静态调用和数据保护。

如果您进行大量读/写操作,互斥锁可能更有效 - 也许您可以锁定互斥锁,然后读取 100 字节的数据?另外,要小心脏读/写:如果你读取一个原子,对值做一些事情,然后尝试更新原子,交错线程可能已经改变了原子的值。使用成本稍高的互斥体可以轻松避免这种情况。

【讨论】:

【参考方案2】:

根据this 参考atomic 有一个模板类型的成员。它还专门针对unsigned int,尽管它没有提供比基本类型那么多的功能。记忆方面,你应该没问题。

【讨论】:

以上是关于在实践中,C++11 中 std::atomic 的内存占用是多少?的主要内容,如果未能解决你的问题,请参考以下文章

在 C++11 中以无锁方式原子交换两个 std::atomic<T*> 对象?

c++11 std::atomic

std::atomic 负载中的段错误?

C++并发与多线程 11_std::atomic叙谈std::launch(std::async) 深入

在C ++ 11中重置struct值

std::atomic 和 std::condition_variable 等待、notify_* 方法之间的区别