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

What is the memory footprint of std::atomic in C++11, in practice?

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

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

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

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

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

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

您可以在这里自己检查:https://godbolt.org/g/6zjJCU - 在没有打开优化的情况下,std::atomic 和常规变量占用相同的内存量。

但是,不同之处在于对变量的访问。尝试取消对该块的注释...您将获得所有静态调用和数据保护。

如果你做很多 read/writes,互斥量可能更有效 - 也许你可以锁定互斥量然后读取,比如说,100 字节的数据?另外,注意脏 reads/writes:如果你读取一个原子,对值做一些事情,然后尝试更新原子,交错线程可能已经改变了原子的值。使用成本稍高的互斥锁可以轻松避免这种情况。