与普通指针相比,按值传递“unique_ptr”是否会降低性能?

2023-11-26

普遍的智慧是std::unique_ptr不会带来性能损失 (不使用删除器参数时不会造成内存损失),但我最近偶然发现了一个讨论,表明它实际上引入了一个额外的间接,因为unique_ptr无法在具有 Itanium ABI 的平台上的寄存器中传递。发布的示例类似于

#include <memory>

int foo(std::unique_ptr<int> u) {
    return *u;
}

int boo(int* i) {
    return *i;
}

与 boo 相比,它在 foo 中生成额外的汇编指令。

foo(std::unique_ptr<int, std::default_delete<int> >):
        mov     rax, QWORD PTR [rdi]
        mov     eax, DWORD PTR [rax]
        ret
boo(int*):
        mov     eax, DWORD PTR [rdi]
        ret

解释是安腾 ABI 要求unique_ptr由于构造函数不平凡,因此不应在寄存器中传递,因此它在堆栈上创建,然后将该对象的地址传递在寄存器中。

我知道这并不会真正影响现代 PC 平台的性能,但我想知道是否有人可以提供更多详细信息,说明为什么不应将其复制到寄存器。由于零成本抽象是 C++ 的主要目标之一,我想知道这是否已在标准化过程中作为可接受的偏差进行讨论,或者是否是实现质量问题。考虑到好处时,性能损失肯定足够小,尤其是在现代 PC 平台上。

评论者指出,这两个函数并不完全等效,因此比较是有缺陷的,因为foo还将调用删除器unique_ptr参数但是boo不释放内存。然而,我只对通过考试所带来的差异感兴趣unique_ptr按值传递与传递普通指针相比。我修改了示例代码并添加了对delete释放普通指针;呼叫在呼叫者中,因为unique_ptr的删除器也会在调用者的上下文中被调用,以使生成的代码更加相同。此外,手册delete还检查ptr != nullptr因为析构函数也会这样做。仍然,foo不传递寄存器中的参数,并且必须 进行间接访问。

我还想知道为什么编译器不忽略对nullptr打电话之前operator delete因为无论如何这都被定义为 noop 。我猜可能是unique_ptr可以专门为默认删除器不在析构函数中执行检查,但这将是一个非常小的微观优化。


System V ABI 使用 Itanium C++ ABI 并引用它。尤其,C++ 安腾 ABI指定

如果参数类型对于调用而言很重要,则 调用者必须为临时对象分配空间并传递该临时对象 参考。

具体来说:

...

如果该类型具有重要的析构函数,则调用者会在控制权返回给它之后(包括调用者引发异常时)、在封闭完整表达式的末尾调用该析构函数。

所以简单回答一下问题“为什么它没有传递到寄存器中" is "因为它不能".

现在,一个有趣的问题可能是'为什么 C++ Itanium ABI 决定这样做'.

虽然我不会声称我对基本原理有深入的了解,但我想到了两件事:

  • 如果函数的参数是临时的,这允许复制省略
  • 这使得尾调用优化更加强大。如果被调用者需要调用其参数的析构函数,那么对于任何接受非平凡参数的函数来说,TCO 都是不可能的。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

与普通指针相比,按值传递“unique_ptr”是否会降低性能? 的相关文章

  • 插入多重集中:在该值第一次出现之前而不是最后一次出现之后

    正如标题所示 multiset 在所有相同值的范围末尾插入一个值 例如 在多重集中插入 21 2 2 3做到了1 2 2 new 2 3 如何在所有相同值的范围开头插入新值 例如 在多重集中插入 21 2 2 3应该使1 new 2 2 2
  • ExecuteNonQueryAsync 并在 SQL 事务中提交

    我正在寻求对我创建的一段代码的帮助 我正在尝试在事务中从 C 进行异步 SQL 调用 例如我可能正在更新或删除表中的行 这是我到目前为止所拥有的 但我似乎无法找到有关在事务中执行此操作的太多信息 根据我在这里所拥有的以及到目前为止我所理解的
  • asm、asm 易失性内存和破坏性内存之间的区别

    在实现无锁数据结构和定时代码时 通常需要抑制编译器的优化 通常人们使用asm volatile with memory在 clobber 列表中 但有时你会看到asm volatile或者只是一个简单的asm破坏记忆 这些不同的语句对代码生
  • 如何防止函数中的隐式转换?

    我正在编写一个实用程序类 其中包含 IsEquals 和 IsGreaterThanEquals 等接受 double 类型参数的方法 当我将浮点值发送到方法时 它们会隐式转换为双精度值并进行比较 我不希望这种事发生 当我发送 float
  • 如何使用 CMake 链接多个库

    我有一些与 DCMTK 相关的代码 如果我从命令行使用 g 我可以成功构建并运行它 这是代码 include dcmtk config osconfig h include dcmtk dcmdata dctk h int main Dcm
  • 减少最大值并保存其索引

    int v 10 2 9 1 3 5 7 1 2 0 0 int maximo 0 int b 0 int i pragma omp parallel for shared v private i reduction max maximo
  • 具有 Nhibernate 设计问题的领域模型

    我正在尝试进入 DDD with C 世界 我使用NHibernate作为我的ORM工具 因此尝试开发一个PI Persistence Ignorance 模型 但是 在我的一些实体 表示为 POCOS 中 我的属性设置器中有业务规则 例如
  • 使用 rhino 模拟进行 lambda 单元测试失败

    如果我有这个测试 Expect Call session Single
  • C++ 访问嵌套类的私有成员

    标题可能有点误导 我有以下问题 我有一棵由叶子和内部节点组成的树 用户应该能够在叶子中存储任何信息and该树有一些方法可以获取一组用户定义的值 并且需要在恒定时间内 未摊销 访问相应的叶子 我提出了以下想法 但它不起作用 因为不幸的是我无法
  • 即使在不活动状态下,Hangfire 也会继续运行 SQL 查询

    我正在开发一个 ASP net MVC 5 网站 并使用 Hangfire 来安排一些任务 在本例中每 3 分钟一次 我知道一个事实是 运行这样的任务 以及与之相关的数据库查询 只需要几秒钟 我面临的问题是 Hangfire 似乎让我的 S
  • ofstream::operator<<(streambuf) 是一种复制文件的缓慢方法

    我需要一种跨平台 无需外部库的复制文件的方式 在我的第一遍中 我想出了 省略错误处理 char buffer LEN ifstream src srcFile ios in ios binary ofstream dest destFile
  • 使用 MemoryCache 而不是普通的旧 Dictionary 的令人信服的理由是什么

    我刚刚遇到内存缓存 http msdn microsoft com en us library system runtime caching memorycache aspx这是 NET 4 中的新增功能 我知道如果你想的话它会很有用 限制
  • 如何在运行时统一捕捉两个对象?

    这是 3D 模型 我想将另一个像这样的模型连接到顶部的银色连接器 并将另一个模型连接到右侧 所以请帮助我捕捉它 https i stack imgur com qoWwl png我想知道如何在运行时将两个 3D 对象对齐在一起 即 在 玩
  • 如何根据条件退出 PostSharp 方面的 OnEntry 方法中的方法

    我希望方面根据如下条件退出方法调用 AttributeUsage AttributeTargets Method public class IgnoreIfInactiveAttribute OnMethodBoundaryAspect p
  • COM Interop 挂起会冻结整个 COM 系统。如何取消COM调用

    我正在使用通过 COM Interop 包装器公开的第三方 dll 然而 其中一个 COM 调用经常冻结 至少不会返回 为了至少让我的代码更加健壮 我异步包装了调用 getDeviceInfoWaiter is a ManualResetE
  • 基于 C++ 组件的类

    Hi 我正在使用容器编写一个基于组件的类 但是在考虑了许多不同的方法之后 我找不到真正符合我想要的方法 这是总体思路的一个例子 我已经写的代码 Abstract class Component class Component public
  • Pythonlibs3 CMake 和 macOS

    更新2 将以下两行添加到我的 CMake 文件中时 成功找到了 python 3 及其库 这只在终端中工作的原因是因为 CLion 使用其捆绑版本的 CMake 3 6 3 而我的终端使用的更新版本 3 7 2 正确找到了 python F
  • TPL架构问题

    我目前正在开展一个项目 我们面临并行处理项目的挑战 到目前为止没什么大不了的 现在来说说问题 我们有一个 ID 列表 我们定期 每 2 秒 为每个 ID 调用一个 StoredProcedure 需要单独检查每个项目的 2 秒 因为它们是在
  • Interlocked.CompareExchange 可以抛出 NullReferenceException 吗?

    From https msdn microsoft com en us library bb297966 v vs 110 aspx https msdn microsoft com en us library bb297966 v vs
  • 如何用纯色填充位图?

    我需要使用唯一的 RGB 颜色创建 24 位位图 分辨率 100x100 像素 并将生成的图像保存到磁盘 我目前使用的是SetPixel http msdn microsoft com en us library 6c7eyzyb aspx

随机推荐

  • 如何禁用一个类或整个包的记录器?

    我在用Apache Commons 日志记录 现在我想用SimpleLog实现 但是当我更改级别时 库中的记录器出现了 我希望它能把它们关掉 有没有一种简单的方法来更改整个包的日志级别 Log4j 可以做到这一点 我尝试过设置 org ap
  • Swift 运算符的优先级是什么?

    我想查找一些运算符的优先级 某处有所有这些的列表吗 我还没找到 更新为 Swift 3 0 斯威夫特3 0 现在有一个page在 Swift 文档中 下面列出了所有优先级组 也可以通过命令单击import Swift precedenceg
  • 本地通知的通知服务扩展

    系统将加载通知服务扩展并调用其didReceive withContentHandler iOS 10 中的本地通知 如果是的话我们该怎么做 否 接受的答案描述了通知Content扩展 允许您在展开的通知视图中呈现 ViewControll
  • 如何获取Android中支持的摄像机分辨率?

    我正在编写一个应用程序 允许用户使用手机摄像头捕捉视频 我使用自己的代码来录制视频 而不是 Android 内置的相机应用程序 一切工作正常 除了我需要能够访问支持的相机分辨率列表 以便我可以在运行时选择使用哪一个 我正在寻找类似的东西ge
  • 如何使用 ssh 使用 Nodegit 克隆 git 存储库

    我正在尝试使用库nodegit 版本0 2 4 和ssh从我们的teamforge服务器在node js中克隆git存储库 我们的服务器请求用户进行身份验证 当我尝试仅使用克隆方法而不传递选项时 我收到错误 回调无法初始化 SSH 凭据 我
  • ASP.Net WebAPI OWIN:为什么 Request.GetOwinContext() 返回 null?

    在我的生产代码中 我们遇到了 Request GetOwinContext 始终返回 null 的问题 我设置了一个小型测试 WebAPI 控制器来尝试隔离问题 public class TestController ApiControll
  • 如何正确使用 SET XACT_ABORT ON

    我们最近被空降到一个新的 ETL 项目 该项目的代码非常糟糕 我手中有一个包含 700 行和各种更新的查询 我想用它来调试它SET XACT ABORT ON 目标是如果只有一个事务失败则回滚所有事务 但我找到了几种将其存档在 StackO
  • 为什么 scala 函数限制为 22 个参数?

    并不是说我实际上已经接近这个极限 但我一直想知道 为什么他们停在Function22 Tuple22 JVM 限制 任意选择 函数和元组被编译器重写为对象 并且仅Function0通过Function22 and Tuple0通过Tuple
  • Jinja2 按月/年分组

    我正在尝试按月 年对 Jinja 的日期 时间列表进行分组 这是我现在的代码 for group in EventsList groupby date b group grouper b br for event in group list
  • if 和 if 不为 None 之间的区别

    在编写一些 XML 解析代码时 我收到了警告 FutureWarning The behavior of this method will change in future versions Use specific len elem or
  • .NET 中 UTC 和 GMT 标准时间的差异

    在 NET 中 以下语句返回不同的值 Response Write TimeZoneInfo ConvertTime DateTime Parse 2010 07 01 5 30 00 000 TimeZoneInfo FindSystem
  • 使用对象的 n 个克隆创建 java 集合

    在Java中 是否有一种单行方法来创建一个初始化的集合n对象的克隆 我想要这样的等价物 foo vector
  • 检查字符串是否包含数组中的值[重复]

    这个问题在这里已经有答案了 我正在尝试检测一个字符串是否至少包含一个存储在数组中的 URL 这是我的数组 owned urls array website1 com website2 com website3 com 该字符串由用户输入并通
  • 如何使用bind_rows()并忽略列名[重复]

    这个问题在这里已经有答案了 这个问题以前可能已经回答过 但我似乎找不到答案 你怎么用bind rows 只是union两个表并忽略列名 有关的文档bind rows 有以下示例 Columns don t need to match whe
  • 如何在用 [ApiController] 装饰的控制器中对模型验证进行单元测试?

    正如指出的这个答案 to Asp Net Core 2 1 ApiController 在单元测试下不会自动验证模型 ASP NET Core 2 1 的 ApiControllerAttribute 为我们提供的自动 ModelState
  • 在 xcode 6.1 中,界面生成器删除 ui 元素

    我有一个包含一些表格视图和一些集合视图以及一些按钮和标签的视图 我不确定这是否是 Xcode 6 1 的新功能 因为我已经有一段时间没有从事该项目的 ui 方面的工作了 但是 当我尝试调整视图中的任何内容时 我的表视图和集合视图 以及可能还
  • Syntastic for Vim:~/.vimrc 中需要哪些行? (PHP错误检查)

    我发现这些文件令人沮丧 我需要添加到配置文件中才能使其正常工作的基本行是什么 从技术上来说 没什么 如果您已将 Syntastic 提取到您的 vim目录 尝试使用 SyntasticEnableVim 中的命令为当前打开文件的文件类型启用
  • 带有代码签名 .exe 文件的 Windows 10 SmartScreen

    我创建了一个 setup exe 文件并将其加载到我的网站上以供下载 exe 文件已使用 godaddy 的证书进行了代码签名 当使用 win7 从我的网站下载 exe 文件时 它会检测到证书并将其显示为安全下载 在 win10 上 exe
  • 使用 matplotlib 具有不同顺序颜色的堆叠条形图

    我是Python的初学者 我正在尝试制作具有不同顺序颜色的水平条形图 我有一个如下所示的数据集 dataset A 19 B 39 C 61 D 70 A 34 B 68 C 32 D 38 A 35 B 45 C 66 D 50 A 23
  • 与普通指针相比,按值传递“unique_ptr”是否会降低性能?

    普遍的智慧是std unique ptr不会带来性能损失 不使用删除器参数时不会造成内存损失 但我最近偶然发现了一个讨论 表明它实际上引入了一个额外的间接 因为unique ptr无法在具有 Itanium ABI 的平台上的寄存器中传递