如果别名会降低运行时性能,为什么编译器要执行别名?

2024-04-05

我出于纯粹的兴趣而学习 C 和计算机科学主题,这让我对编译器产生了兴趣。我读过的所有内容都告诉我,别名会导致程序集输出速度变慢,需要在每次迭代时重新加载值。

我已经能够使用 Intel C / C++ 编译器使用该标志在一些基准测试中获得轻微的提高-fno-alias。 GCC 和 Clang / LLVM 没有等效的标志。有-fargument-noalias and -fargument-noalias-global我猜这会禁用函数参数的别名 -如果我错了请纠正我- 但我没有注意到它对运行时甚至编​​译时性能有任何影响。

是否声明

别名会阻止编译器进行某些优化,从而影响性能。

始终如此,编译器别名有什么好处?为什么它是现代编译器的一个功能,除了英特尔编译器之外,不能通过标志轻松关闭?不使用别名进行编译会导致代码不符合 ABI 标准吗?


编译器不执行别名。您的程序可能会执行别名操作。

编译器要么允许您执行别名,要么假设您没有执行别名,然后编写在您执行别名时不起作用的机器代码。

例如,您编写这样的代码:

void f(int *x, int *y, int *z) {
    *y += *x;
    *z += *x;
}

该函数只是添加*x to *y and *z, 正确的?那么汇编代码应该是这样的吧? (我用伪C语言编写了汇编代码)

eax = argument x
ebx = argument y
ecx = *eax
*ebx += ecx
ebx = argument z
*ebx += ecx

Wrong. If y and x指向同一个地方,此汇编代码的工作方式与 C 代码不同,因为它使用old *x。为了正常工作,它必须是这样的:

eax = argument x
ebx = argument y
ecx = *eax
*ebx += ecx
ebx = argument z
ecx = *eax // extra instruction
*ebx += ecx

这是又一条指令,只有在以下情况下才有用:x==y,但编译器必须将其放在那里以防万一。Aliasing意思是*x and *y是同一个变量的不同名称。如果编译器假设x and y不能是相同的指针(即没有别名),那么它可以跳过该指令,因此指令更少,程序运行得更快。

您可以使用单词告诉编译器他们不使用别名restrict, 像这样:

void f(int *restrict x, int *restrict y, int *restrict z) {
    *y += *x;
    *z += *x;
}

-fno-alias告诉英特尔编译器别名不能在任何地方发生。这可能会产生错误某处因为参数有时会产生别名 - 尽管它可能在它们都没有的小程序上工作得很好。restrict更仔细地针对您知道不会别名的特定参数。

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

如果别名会降低运行时性能,为什么编译器要执行别名? 的相关文章

  • 为什么 GCC 交叉编译不构建“crti.o”?

    在尝试为arm构建gcc 4 x x交叉编译器时 我陷入了缺失的困境crti o文件在 BUILD DIR gcc子目录 An strace在顶层Makefile表明编译后的xgcc正在调用交联器ld with crti o 作为一个论点
  • 如何将 pem 公钥转换为 openssl RSA* 结构

    假设我必须像这样公开 pem 密钥 BEGIN PUBLIC KEY MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC7vbqajDw4o6gJy8UtmIbkcpnk O3Kwc4qsEnSZp TR fQi
  • Reflection.Emit 中的短格式操作码错误

    我正在制作一种与以下非常相似的小语言hlsl但仅支持像素着色器 该语言使用reflection emit构建实现相同功能的 NET 程序集 我目前正在测试分支指令的实现if在我的一个单元测试中 一个大的if与内if elses 失败并显示以
  • C# - 如何将 IntPtr 缓冲区数据保存到文件(最快的方法)?

    我使用此代码将非托管代码中的 IntPtr 缓冲区中的字节保存到文件中 这是一个简单的回调函数 private void callback IntPtr buffer int length byte bytes new byte lengt
  • popen2()在c中如何工作?

    我尝试使用管道 叉子和 dup 在我的程序中执行 md5sume 命令 我发现总和代码运行成功 但我无法理解某些代码行 这是我的代码 int infp outfp char buf 128 if popen2 md5sum infp out
  • Xamarin 无法从异步获取实例

    我编写了一个通过蓝牙连接到 ESP32 的 Xamarin Forms 应用程序 现在我想从 MainPage xaml 页面的 CustomControl JoystickControl 获取值 我已经这样尝试过了 MainPage xa
  • Boost async_write问题

    我将展示一些代码 void wh const boost system error code ec std size t bytes transferred std cout lt lt test int main int argc cha
  • 允许 .NET WebApi 忽略 DOCTYPE 声明

    我正在尝试通过 WebApi 方法将 XML 反序列化为对象 我有以下课程 XmlRoot IsNullable false public class MyObject XmlElement Name public string Name
  • 为什么 MISRA:2012 需要函数原型?

    我想知道为什么 MISRA 2012 需要函数原型 在下面的示例中 这两个原型并不是真正必要的 include
  • 如何在 Xamarin.Mac 中执行终端命令并读入其输出

    我们正在编写一个 Xamarin Mac 应用程序 我们需要执行像 uptime 这样的命令 并将其输出读取到应用程序中进行解析 这可以做到吗 在 Swift 和 Objective C 中都有 NTask 但我似乎无法在 C 中找到任何示
  • gcc 中的“假设”子句

    gcc 最新版本 4 8 4 9 是否有类似于以下的 假设 子句 assume 内置icc支持吗 例如 assume n 8 0 从 gcc 4 8 2 开始 gcc 中没有 assume 的等效项 我不知道为什么 这会非常有用 马夫索建议
  • 在同一条线上铸造两次

    我在项目中看到了这段代码 b的类型是void void b int a int unsigned long b 这条线毫无意义吗 我的意思是 这与a int b在所有情况下 这可能会避免 64 位 Unix 系统上的编译器警告unsigne
  • 如何从标准输入读取一行,阻塞直到找到换行符?

    我试图从命令行的标准输入一次读取任意长度的一行 我不确定是否能够包含 GNU readline 并且更喜欢使用库函数 我读过的文档表明getline应该可以工作 但在我的实验中它不会阻塞 我的示例程序 include
  • lambda 表达式是多线程的吗?

    lambda 表达式是多线程的吗 假设当你将数学公式编写为 lambda 方法时 当你将其传递给另一个方法时 它会是多线程的吗 不是100 清楚你问的是什么 您是否想问 lambda 是否自然地在不同的线程上运行 如果是这样 则它们只是 S
  • 父窗体中的居中消息框[重复]

    这个问题在这里已经有答案了 有没有一种简单的方法可以在 net 2 0中将MessageBox居中于父窗体中 我在 C 中确实需要这个并发现中心消息框 C http bytes com topic c sharp answers 26712
  • jquery ajax“发布”调用

    我是 jQuery 和 Ajax 的新手 并且在 发布 方面遇到问题 我正在使用 jQuery Ajax post 调用将数据保存到数据库 当我尝试保存数据时 它将 null 传递给我的 C 方法 jQuery 看起来像这样 functio
  • 为什么C#不支持多重继承? [复制]

    这个问题在这里已经有答案了 可能的重复 C 应该包含多重继承吗 https stackoverflow com questions 191691 should c include multiple inheritance 为什么C 不支持多
  • 为了清楚起见,是否应该在返回类型上使用无用的类型限定符?

    当我们的头文件中有原型时 我们的静态分析工具会抱怨 返回类型上有无用的类型限定符 例如 const int foo 我们这样定义它是因为该函数返回一个永远不会改变的常量 认为 API 看起来更清晰const到位 为了清楚起见 我觉得这类似于
  • 组合框由于某种原因被链接

    我有以下代码来填充 3 个组合框 private void PopulateDDLs SqlConnection connection SqlCommand command SqlDataReader reader DataTable dt
  • 你将如何开始自动化我的工作? - 第2部分

    后续这个问题 https stackoverflow com questions 2796128 how would you start automating my job 在经历了第一波进货 9 小时的复制 粘贴 后 我现在相信我已经满足

随机推荐

  • Locust 95 百分位数高于最大值

    有时 当我在某些场景下运行 Locust 时 95 百分位数值会超过最大值 据我了解 95 意味着 95 的请求花费的时间比这个少 那么最大值怎么会小于 95 呢 我在这里做错了什么 我还发现只有当请求数量非常少 例如 15 个或更少 时才
  • 使用 CakePHP 2 的特征和命名空间的正确方法是什么?

    我正在使用 CakePHP 2 4 5 和 PHP 5 5 并且想使用一个特征 我在 Utility VariablesTrait php 中有一个称为VariablesTrait 为了利用命名空间 我给了它一个命名空间App Utilit
  • Json序列化Swift 3类型错误

    我使用以下代码从推送通知接收自定义数据 但收到以下错误 无法将类型 NSArrayM 0x1b0776cf0 的值转换为 NSDictionary 0x1b0777128 在下面一行 let jsonData try JSONSeriali
  • 网页查看历史记录

    WebView中什么时候将页面添加到前进后退列表中 我有 webview setMaintainsBackForwardList YES 但是 webview canGoBack 在我执行了几个 webview mainFrame load
  • Gtk Widget 到 Winform

    是否可以使用 System Windows Forms 将 Gtk 小部件嵌入到应用程序中 谢谢 两个工具包都使用自己单独的 UI Mainloop 来处理事件 例如鼠标移动 按钮按下等 因此 将两者混合实际上是不可能的 尽管几年前 Gtk
  • 使用多个参数记录

    我目前正在开发一个程序 其中我必须将所有输出写入日志文件 我需要编写一个日志方法 它应该按照我指定的顺序给出一个输出 其中包含级别 消息 对象值 另一条消息 一个整数值 另一条消息和另一个整数值 我似乎找不到执行此操作的日志方法 我在用Ja
  • 如何升级SQLite版本?

    我正在开发我的第一个应用程序 并使用以下代码查看我的 SQLite 版本 Cursor cursor SQLiteDatabase openOrCreateDatabase memory null rawQuery select sqlit
  • 如何设置 Eclipse 项目引用

    我的工作区中有一个 Web 项目 它依赖于工作区中的 java 项目 在项目引用中 我使我的 Web 项目引用了 java 项目 但仍然存在构建错误 表明我的 java 项目中的类未被我的 Web 项目引用 一个答案 这不是对您的问题的直接
  • Eclipse 找不到 MinGW。为什么?

    我都正确安装了 但是无论我是否正确设置编译器路径都没关系 因为它找不到 gcc 和 g 我用资源管理器检查过 它们位于正确的位置 我尽了一切努力 甚至以向后兼容模式并以管理员身份运行 Eclipse 编辑 如果 Eclipse 不能至少像用
  • 如何从 Javascript 或 Jquery 数组中选择随机值? [复制]

    这个问题在这里已经有答案了 我试图显示数组中的 3 个随机值 以下脚本仅从 javaScript 数组返回单个项目 var arrayNum One two three four five six seven eight nine var
  • 如何使用SessionState获取剩余会话超时时间?

    是否可以使用 ASP net 中的 sessionState 获取剩余会话超时 这是我的 webconfig 文件中的 sessionState 代码
  • 如何输出未包含在分组依据中的属性及其计数

    我在这里想要实现的是 我希望从该 LINQ 查询返回具有两个属性的列表 billNo 和同一 fromDate 上导入代码出现的次数 因此 这里我们的 billNo 1 和 2 都具有相同的导入代码 该导入代码在同一日期 01 01 202
  • 如何在 macOS 上将 libxml2 与 python 一起使用?

    我在 OSX Lion 上 安装了 libxml2 默认情况下 并且安装了 python 默认情况下 但它们不互相通信 在 Lion 上实现此功能的最简单方法是什么 python c import libxml2 Traceback mos
  • 在Ubuntu 18.04、Python 3.6.7 64位、Mono 5.16上安装pythonnet失败

    我想在 Ubuntu 上安装 pythonnet 但失败了 这就是我到目前为止所尝试的 usr bin python3 m pip install U pythonnet user Error Collection pythonnet Us
  • DOM 中两个元素之间的距离(以 px 为单位)

    如何获取 DOM 中两个元素之间的距离 我正在考虑使用获取边界客户端矩形 https developer mozilla org en US docs Web API Element getBoundingClientRect 但我不知道如
  • C# POCO 的 DbGeography 替代方案

    我正在编写一个应用程序 我需要查询某个位置半径内的记录 我一开始在 PCO 上只使用了一对经纬度属性 但意识到 SQL 中的空间搜索是针对地理列类型完成的 该地理列类型可转换为 POCO 中的 DbGeography 在另一篇 SO 帖子中
  • SharePoint 中的跨方法处置模式

    我编写了一个类 可以对 SharePoint 网站的内容进行各种修改 在该类中 我实现了一个惰性解析属性 private SPWeb rootSite get if site null SPSite site new SPSite url
  • 订阅 RSS 源

    我正在编写一个非常简单的 RSS 阅读器 它所需要做的就是获取 xml 文档 并将每个项目的标题和发布日期打印到控制台 我开始使用这两个问题 如何开始制作 C RSS 阅读器 https stackoverflow com question
  • Hbase连接zookeeper错误

    环境 Ubuntu 14 04 hadoop 2 2 0 hbase 0 98 7 当我启动hadoop和hbase 单节点模式 时 都成功 我还检查了hadoop的网站8088 hbase的网站60010 jps 4507 Seconda
  • 如果别名会降低运行时性能,为什么编译器要执行别名?

    我出于纯粹的兴趣而学习 C 和计算机科学主题 这让我对编译器产生了兴趣 我读过的所有内容都告诉我 别名会导致程序集输出速度变慢 需要在每次迭代时重新加载值 我已经能够使用 Intel C C 编译器使用该标志在一些基准测试中获得轻微的提高