boost::thread 数据结构大小太荒谬了?

2023-12-01

编译器:linux 上的 clang++ x86-64。

我已经有一段时间没有编写任何复杂的低级系统代码了,而且我通常针对系统原语(Windows 和 pthreads/posix)进行编程。所以,进出的事情已经从我的记忆中消失了。我正在与boost::asio and boost::thread眼下。

为了针对异步函数执行器模拟同步 RPC(boost::io_service具有多个线程io::service::run'ing 请求在哪里io_serviced::post'ed),我正在使用增强同步原语。出于好奇,我决定sizeof原始人。这就是我所看到的。

struct notification_object
{
  bool ready;
  boost::mutex m;
  boost::condition_variable v;
};
...
std::cout << sizeof(bool) << std::endl;
std::cout << sizeof(boost::mutex) << std::endl;
std::cout << sizeof(boost::condition_variable) << std::endl;
std::cout << sizeof(notification_object) << std::endl;
...

Output:

1
40
88
136

互斥锁有四十个字节? ?? ?卧槽! 88 表示条件变量!请记住,我对这种臃肿的尺寸感到厌恶,因为我正在考虑一个可以创建数百个应用程序的应用程序notification_object's

这种可移植性的开销似乎很荒谬,有人可以证明这一点吗?据我所知,这些原语应该是 4 或 8 字节宽,具体取决于 CPU 的内存模型。


当您查看任何类型的同步原语的“大小开销”时,请记住这些cannot包装得太紧密。之所以如此,是因为例如共享缓存行的两个互斥体如果同时使用,最终会导致缓存垃圾(错误共享),即使获取这些锁的用户从不“冲突”。 IE。想象两个线程运行两个循环:

for (;;) {
    lock(lockA);
    unlock(lockA);
}

and

for (;;) {
    lock(lockB);
    unlock(lockB);
}

与一个线程运行一个循环相比,在两个不同线程上运行时,您将看到迭代次数的两倍当且仅当两个锁是不在同一个缓存行内. If lockA and lockB都在同一个cacheline中,迭代次数每个线程将会减半 - 因为带有这两个锁的缓存行将在执行这两个线程的 CPU 核心之间永久地反弹。

因此,尽管实际数据大小自旋锁或互斥体底层的原始数据类型可能只是一个字节或一个 32 位字,有效数据大小这种物体的体积通常较大。

在断言“我的互斥体太大”之前请记住这一点。事实上,在 x86/x64 上,40 字节是太小为了防止错误共享,缓存行目前至少有 64 字节。

除此之外,如果您高度关注内存使用情况,请考虑通知对象不必是唯一的 - 条件变量可以触发不同的事件(通过predicate that boost::condition_variable知道)。因此,可以对整个状态机使用单个互斥体/CV 对,而不是每个状态一对。同样适用于例如线程池同步——拥有比线程更多的锁并不一定是有益的。

Edit:有关“错误共享”(以及在同一缓存行中托管多个原子更新变量所造成的负面性能影响)的更多参考,请参阅(除其他外)以下 SO 帖子:

  • boost::detail::spinlock_pool 中的错误共享?
  • 错误共享和 pthreads
  • 错误共享和原子变量

如前所述,当在多核、每核缓存配置中使用多个“同步对象”(无论是原子更新的变量、锁、信号量……)时,允许每个对象有一个单独的缓存行空间。您在这里用内存使用来换取可扩展性,但实际上,如果您进入软件需要数百万个锁(需要 GB 内存)的区域,您要么有资金购买几百 GB 内存(以及一百个CPU核心),或者你在软件设计中做错了什么。

在大多数情况下(特定实例的锁/原子)class / struct),只要包含原子变量的对象实例足够大,您就可以免费获得“填充”。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

boost::thread 数据结构大小太荒谬了? 的相关文章

  • 无法在 QGLWidget 中设置所需的 OpenGL 版本

    我正在尝试在 Qt 4 8 2 中使用 QGLWidget 我注意到 QGLWidget 创建的默认上下文不显示 OpenGL 3 1 以上的任何输出 Qt wiki 有一个教程 http qt project org wiki How t
  • copy_from_user() 错误:目标大小太小

    我正在为内核模块编写 ioctl 处理程序 我想从用户空间复制数据 当我编译禁用优化的代码时 O0 gflags 编译器返回以下错误 include linux thread info h 136 17 error call to bad
  • SOAP Web 服务:多台服务器,一个接口

    我有一个场景 需要任意数量的服务器来提供相同的 SOAP Web 服务 我想生成一组代理类 并能够为它们提供一个位置 以便在运行时将它们指向不同的服务器 不幸的是 看起来好像wsdl port节点 子节点wsdl service 要求对特定
  • 无法在 CUDA 中找到 1 到 100 数字的简单和?

    我正在研究使用 CUDA 的图像处理算法 在我的算法中 我想使用 CUDA 内核找到图像所有像素的总和 所以我在cuda中制作了内核方法 来测量16位灰度图像的所有像素的总和 但我得到了错误的答案 所以我在cuda中编写了一个简单的程序来查
  • 来自 double 的 static_cast 可以优化分配给 double 吗?

    我偶然发现了一个我认为不必要的功能 并且通常让我感到害怕 float coerceToFloat double x volatile float y static cast
  • 如何在 C++ 中为指针“this”赋值

    在函数中 如何分配this一个新的价值 您可以分配对象this点于 this XY 但你不能分配直接值this this XY Error Expression is not assignable
  • 每个元素的 asp.net Web 表单自定义错误消息

    我创建了一个 Web 应用程序 表单 以及后端 SQL 插入和查询 目前我正在显示所有用户错误消息 div style padding 1em div
  • 从结构调用 C++ 成员函数指针

    我找到了有关调用 C 成员函数指针和调用结构中的指针的信息 但我需要调用结构内部存在的成员函数指针 但我无法获得正确的语法 我在类 MyClass 的方法中有以下代码片段 void MyClass run struct int MyClas
  • Visual Studio 2013 调试器显示 std::string 的奇怪值

    我有一个大型的 cmake 生成的解决方案 其中包含许多项目 由于某种原因 我无法查看字符串的内容 因为根据调试器 Bx Buf含有一些垃圾 text c str 正确返回 Hello 该问题不仅仅发生在本地字符串上 返回的函数std st
  • 在 C# 中解析 JS Date.toIsoString

    我需要将 JS 日期存储为 ISO 8601 日期 我目前正在从格式为 2019 06 22T00 00 00 000Z 的表单中获取日期 正如 JS 的 toIsoString 方法所期望的那样 当这个日期传递到我的 API 控制器时 我
  • C# 结构默认值

    我有一个方法 它接受一个包含许多具有基本数据类型的字段的结构 我想传递大部分默认值 但需要进行一些调整 但我了解结构声明中的基本字段不能包含默认值声明 例如struct S int a 42 现在是这样的 OptionsStruct opt
  • 用于 C++ 中图像分析的 OpenCV 二进制图像掩模

    我正在尝试分析一些图像 这些图像的外部周围有很多噪声 但内部有一个清晰的圆形中心 中心是我感兴趣的部分 但外部噪声正在影响我对图像的二进制阈值处理 为了忽略噪音 我尝试设置一个已知中心位置和半径的圆形蒙版 从而使该圆之外的所有像素都更改为黑
  • MINIX内部碎片2

    我正在用 C 语言编写一些软件 它递归地列出给定目录中的所有文件 现在我需要计算出内部碎片 我花了很长时间研究这个问题 发现 ext2 上的内部碎片只发生在最后一个块中 我知道理论上你应该能够从索引节点号获得第一个和最后一个块地址 但我不知
  • 如何在VS2005中使用从.bat而不是.exe启动的外部程序进行调试?

    在我的 c 项目的调试属性中 我选择了 启动外部程序 并选择了我希望将调试器附加到的程序的 exe 但是 现在我需要从 bat 文件而不是 exe 启动程序 但 VS2005 似乎不允许这样做 这可能吗 编辑 为了澄清 我需要调试从 bat
  • 让 Windows 尝试读取文件

    我正在对 Windows 文件系统进行某种封装 当用户请求打开文件时 Windows 调用我的驱动程序来提供数据 在正常操作中 驱动程序返回缓存的文件内容 但是 在某些情况下 实际文件没有缓存 我需要从网络下载它 问题是是否有可能让 Win
  • 查找数组中的多个索引

    假设我有一个像这样的数组 string fruits watermelon apple apple kiwi pear banana 是否有一个内置函数可以让我查询 apple 的所有索引 例如 fruits FindAllIndex ap
  • 为什么存在系统调用

    我一直在阅读有关系统调用及其在 Linux 中如何工作的内容 我还有更多的阅读要做 但我读过的一件事都没有回答 那就是 为什么我们需要系统调用 我知道系统调用是用户空间程序要求内核执行某些操作的请求 但我的问题基本上是 为什么用户空间程序本
  • 如何配置 qt Creator 以显示 C++ 代码而不是反汇编程序?

    昨天我做了很多事情 比如更新 GCC Clang 和重新安装 Qt Creator 今天 在逐步调试我的代码时 调试器显示的是反汇编代码 而不是我编写的 C 代码 紧迫F10 or F11 调试器正在进入汇编代码而不是 cpp nor h我
  • 稀疏矩阵超定线性方程组c/c++库

    我需要一个库来解决 Ax b 系统 其中 A 是一个非对称稀疏矩阵 每行有 8 个条目 而且可能很大 我认为实现双共轭梯度的库应该没问题 但我找不到一个有效的库 我尝试过 iml 但 iml sparselib 包中缺少一些标头 有小费吗
  • 将同步 zip 操作转换为异步

    我们有一个现有的库 其中一些方法需要转换为异步方法 但是我不确定如何使用以下方法执行此操作 错误处理已被删除 该方法的目的是压缩文件并将其保存到磁盘 请注意 zip 类不公开任何异步方法 public static bool ZipAndS

随机推荐

  • 按组计算平均值

    我有一个类似于此的大型数据框 df lt data frame dive factor sample c dive1 dive2 10 replace TRUE speed runif 10 gt df dive speed 1 dive1
  • 安卓兼容包

    尝试使 Fragments 示例在低于 11 SDK 的版本上运行时 出现错误 setListAdapter new ArrayAdapter
  • 从数据绑定 DevExpress CheckedListBoxControl 获取项目索引

    我试图从以下位置找到特定值的索引选中列表框控件 CheckedListBoxControl 有一个 DataSource DisplayMember ValueMember 分别设置为 DataTable 和两列 现在我必须将 Checke
  • 如何找到我当前位置附近的位置?

    我需要一些关于使用 android 如何找到我所在位置附近的医院 学校 餐厅 的想法 怎么可能 一步步 Google place api用于访问附近的anloaction地标 Step 1 进入API控制台获取Place API https
  • 如何在 OSGi 中使用 Apache POI

    我想在 OSGi 中使用 Apache POI 通过流式 OOXML API SXSSF 编写 Excel 工作簿 流媒体 API 自 POI 3 9 起可用 由于最新的 Apache POI 3 11 jar 不是捆绑包 让 POI 在
  • Android Studio:编译时 APK META-INF/DEPENDENCIES 中复制的重复文件

    我使用此链接中的说明从 Eclipse 导出项目并导入到 Android Studio http developer android com sdk installing migrate html 当我构建时 出现错误 Duplicate
  • PHP 从 MySQL 导出到 CSV

    我需要将数据从 MySQL 导出到 CSV 但需要从特定 ID 导出 表包含 ID ParentID 和名称 下面是导出所有记录的代码
  • 对 require 的调用期望正好有 1 个字符串文字参数

    我想根据传递下来的道具来渲染图像 第一个注释掉的 filePath 是源文件 我尝试了几种变体 但它总是给我同样的错误 React 文档并没有真正涵盖在 30 多种不同场景的情况下你会做什么 我可以向该组件添加一个状态并让它包含所有文件变体
  • VideoJS:不适用于 IOS

    我使用了 videojs 它在所有浏览器 包括 IE 和 Android 上运行良好 但它不适用于 IOS 设备 iphone 和 ipad IOS 版本 6 这是我用来将视频添加到页面的代码
  • 实体框架是否支持并行异步查询? [复制]

    这个问题在这里已经有答案了 当我们启动多个异步实体框架查询时会发生什么并行运行它们 它们在物理上是并行执行的吗 它们是由实体框架序列化的吗 这是不支持的吗 它会导致异常吗 public async Task QueryDatabase us
  • 给定尺寸的值范围的组合

    我使用以下代码创建数组的索引列表 但是 我希望索引按 Fortran 顺序运行 即内部循环是更快的变化循环 有没有办法在 python 中实现这一点 目前 我得到的输出是 C 顺序的 np transpose np nonzero np o
  • 延迟 JQuery 效果

    我想在延迟几秒钟后淡出一个元素及其所有子元素 但我还没有找到一种方法来指定效果应在指定的时间延迟后开始 setTimeout function foo fadeOut 5000 5000 是五秒 以毫秒为单位
  • 使用 PHP 将数据从 MySQL 下载到 csv 文件

    如何指定从数据库下载的文件 main php include databaseConnection php result mysql query SELECT FROM participants while row mysql fetch
  • 使用 Angular 登录 Twitter

    我正在尝试使用 angular2 实现 singin 功能 也请阅读官方文档从这里 但是没明白流程是怎么回事 我的问题是 访问第一步 即 outh token 的参数是什么 有没有任何教授流程的工作示例或最佳文章 我已经阅读了很多关于 SO
  • 将 JWT SecurityToken 传递给 WCF 客户端

    我需要根据用户名 密码身份验证生成并向客户端颁发令牌 我尝试了多种方法来解决这个问题 但所有方法都遇到了问题 我的第一个计划是在我的 WCF 端点上实施 WS Trust Issue 我找到的示例使用了以下方法 OperationContr
  • 有没有办法覆盖`{}`对象?

    我试图使我的程序中的所有哈希都是 ActiveSupport OrderedHash 我可以通过以下方式重写 Hash new 构造函数 Hash ActiveSupport OrderedHash but class仍然是哈希 def 给
  • 为什么不使用 ASP.NET 中的 GDI+

    有人告诉我 从 ASP NET 使用 GDI 是危险且未定义的 这是因为没有设备上下文的保证吗 有人可以解释一下吗 有哪些替代方案 这是MSDN来源 http msdn microsoft com en us library system
  • 当虚拟不起作用时

    目前我的 C 类中有一个奇怪的错误 我有一个 ActiveX 包装类 作为 wxWidgets 的一部分 我向其中添加了一个新的虚拟函数 我有另一个类继承自 ActiveX 类 wxIEHtmlWin 但是 ActiveX 类总是调用它自己
  • 显示无效的 SQL 类型:sqlKind = UNINITIALIZED 错误

    String s1 PasswordText4 getText String s2 ConfirmText4 getText String s3 NameText4 getText String s4 UsernameText4 getTe
  • boost::thread 数据结构大小太荒谬了?

    编译器 linux 上的 clang x86 64 我已经有一段时间没有编写任何复杂的低级系统代码了 而且我通常针对系统原语 Windows 和 pthreads posix 进行编程 所以 进出的事情已经从我的记忆中消失了 我正在与boo