在实践中,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:如果你读取一个原子,对值做一些事情,然后尝试更新原子,交错线程可能已经改变了原子的值。使用成本稍高的互斥锁可以轻松避免这种情况。
我正在编写的一个程序需要在 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:如果你读取一个原子,对值做一些事情,然后尝试更新原子,交错线程可能已经改变了原子的值。使用成本稍高的互斥锁可以轻松避免这种情况。