GCC循环展开标志真的有效吗?

2024-01-23

在C中,我有一个任务,我必须用以下方法进行乘法、反转、转置、加法等。huge矩阵分配为二维数组(数组的数组)。

我找到了 gcc 标志-funroll-all-loops。如果我理解正确,这将自动展开所有循环,而无需程序员做任何努力。

我的问题:

a)gcc 是否包含这种优化以及各种优化标志:-O1, -O2 etc.?

b)我必须使用任何pragmas 在我的代码中利用循环展开还是自动识别循环?

c)如果展开可以提高性能,为什么默认情况下不启用此选项?

d)为了以最佳方式编译程序,推荐的 gcc 优化标志是什么? (我必须运行针对单个 CPU 系列优化的程序,这与我编译代码的机器相同,实际上我使用march=native and -O2 flags)

EDIT

似乎关于展开的使用存在争议,在某些情况下可能会降低性能。在我的情况下,有多种方法可以在 2 个嵌套的 for 循环中执行简单的数学运算,以迭代对大量元素完成的矩阵元素。在这种情况下,展开如何降低或提高性能?


为什么展开循环?

现代处理器流水线指令。他们喜欢知道接下来会发生什么,并根据指令执行顺序的假设进行各种奇特的优化。

但在循环结束时,有两种可能性!要么返回顶部,要么继续。处理器对将要发生的情况做出有根据的猜测。如果做对了,一切都好。如果没有,它必须刷新管道并暂停一段时间,同时准备采用另一个分支。

正如您可以想象的那样,展开循环消除了分支和这些停顿的可能性,特别是在可能性与猜测相反的情况下。

想象一个代码循环执行 3 次,然后继续。如果您假设(处理器可能会这样做)最后您将重复循环。 2/3的时间,你是对的!但有 1/3 的时间你会停滞不前。

另一方面,想象同样的情况,但代码循环 3000 次。在这里,展开的时间增益可能只有 1/3000。

Why not展开循环?

上述处理器的部分功能涉及将内存中可执行文件的指令加载到处理器的板载指令高速缓存(简称为 I 高速缓存)中。它保存了可以快速访问的有限数量的指令,但当需要从内存加载新指令时可能会停止。

让我们回到前面的例子。假设循环内的代码量相当小nI 高速缓存的字节数。如果我们展开循环,它现在就占用了n * 3字节。多一点,但它可能适合单个缓存行,这样您的缓存就会以最佳状态工作,并且不需要停止从主内存读取。

然而,3000 循环展开后需要使用一个巨大的n * 3000I 高速缓存的字节数。这将需要从内存中进行多次读取,并且可能将程序中其他地方的一些其他有用的内容从 I-cache 中推出。

那我该怎么办?

正如您所看到的,展开为较短的循环提供了更多好处,但如果您打算循环多次,最终会降低性能。

通常,智能编译器会对要展开的循环进行适当的猜测,但如果您愿意,您可以强制它sure你比较清楚。如何更好地了解?唯一的方法就是两种方法都尝试一下并比较时间!

过早的优化是万恶之源——唐纳德·高德纳

首先进行配置,然后进行优化。

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

GCC循环展开标志真的有效吗? 的相关文章

随机推荐

  • 用于 C# 的 SCIM(跨域身份管理系统)库

    SCIM 标准的创建是为了通过定义表示用户和组的架构以及用于所有必要的 CRUD 操作的 REST API 来简化云中的用户管理 它旨在取代旧的 SPML 协议 有没有 成熟 的 C 库 我在 google 上搜索的大部分内容都是针对 Ja
  • 错误:ld.so:无法预加载对象 LD_PRELOAD:忽略

    我使用的是ubuntu 12 04 每次我启动 bash 终端以及每次输入完命令 并按 Enter 键 时 我都会收到以下消息 错误 ld so 对象 usr lib liblunar calendar preload so 来自 LD P
  • 将弹出窗口位置锁定到元素,或伪造带有图层的弹出窗口,以便在 ItemsControl 中进行就地编辑

    我想要实现的本质上是对数据绑定对象进行就地编辑ItemsControl在 wpf 中 my ItemsControl是一个水平的WrapPanel包含用户控件的多个实例 NameControl 它显示为带有人名的粉红色小字形 看起来像这样
  • C# REPL 工具;类似控制台的快速编译工具

    很多时候 我启动一个新的 Visual Studio 实例 只是为了创建一个具有一些输出和 或输入的控制台应用程序 这是一个临时沙箱 我用它来测试方法或其他东西 并在几分钟后关闭 您能想到任何工具来替代它吗 我曾经有一个具有两个文本字段的应
  • Model.find().then() 在实际加载记录之前触发

    我想加载整个集合 然后只剥离记录以一次用作模型 而不是每次都与服务器进行往返 我已经弄清楚如何使用 Ember Deferred 返回承诺 但我无法在正确的时间得到解决的承诺 以下代码每次都只输出 Found 0 App PersonRou
  • watir-webdriver 在保持浏览器打开的情况下更改代理

    我正在 Ruby 中使用 Watir Webdriver 库来检查一些页面 我知道我可以使用代理通过代理连接 profile Selenium WebDriver Firefox Profile new create a new profi
  • numpy 矩阵到 pandas 系列

    这是一个简单的问题 我有一个 numpy 矩阵 A 我想将其转换为数据帧 系列 中的列 保留矩阵的多重索引 我的意思是 矩阵中的 i j 位置将转换为 pandas 中的 i j 行索引 In 68 A np array 1 2 3 4 拿
  • 在开源项目中包含 Highcharts [关闭]

    Closed 这个问题不符合堆栈溢出指南 help closed questions 目前不接受答案 我想包括高图表 http www highcharts com 开源项目中的库 scala笔记本 https github com Ole
  • 如何将多个 *.zip 存档文件解压缩到单独的文件夹中?

    我用 Google 搜索 但没有找到适用于 Windows 的内容 如何将多个文件提取到多个文件夹中 例如 a zip b zip and c zip进入文件夹a b and c 我正在寻找命令提示符命令或批处理文件解决方案 Thanks
  • 我可以在界面生成器中为 NSTextField 的文本添加下划线吗?

    我可以在界面生成器中为 NSTextField 的文本添加下划线吗 到目前为止 我只能改变它的颜色 有没有办法加下划线 thanks 仅适用于 iOS 是的 设置属性文本 然后选择文本 单击鼠标右键 gt 字体 gt 下划线
  • 如何将两个过程合二为一?

    只是想知道是否有一种语法快捷方式可以获取两个过程并将它们连接起来 以便将一个过程的输出传递给另一个过程 相当于 a gt x x 1 b gt x x 10 c gt x b a x 当处理诸如此类的事情时 这会派上用场method abc
  • mysql tinyint(2) 与学说的布尔值映射不正确

    我使用 symfony2 和命令对数据库进行了逆向工程 php app console doctrine mapping convert php app console doctrine mapping import php app con
  • Android:setContentView() == getViewInflate().inflate()?

    我尽我最大的努力想出一种巧妙的方法来清理成堆的东西Blah blah Blah this findViewById R id blah 否则会污染我的小 Activity 的字段和 onCreate 方法 为此 我觉得我不应该对 XML 中
  • 当模块同名时导入 python 包

    我有一个模块blah time我在正常时间和日期操作周围进行一些健全性检查和包装函数 import time def sleep n time sleep n 当我打电话时sleep 它只会抛出最大递归错误 我猜命名空间是错误的 所以我尝试
  • HAVING 子句后面可以有 WHERE 子句吗?

    是否可以在 HAVING 子句后使用 WHERE 子句 我首先想到的是子查询 但我不确定 附 如果答案是肯定的 您能举一些例子吗 不 不在同一个查询中 The where子句位于having和group by 如果您想在分组之前过滤掉记录
  • 如何添加窗口消息事件监听器-Android WebView

    如何添加事件监听器来处理window message事件在一个WebView 我试过这个 webView evaluateJavascript window addEventListener message function e Andro
  • 如何获取 jinja2 模板中所有变量的列表

    我正在尝试获取模板中所有变量和块的列表 我不想创建自己的解析器来查找变量 我尝试使用以下代码片段 from jinja2 import Environment PackageLoader env Environment loader Pac
  • 我应该开发什么最低的 BlackBerry 操作系统?

    我正在为 BlackBerry 移动设备开发 Netflix 应用程序 我需要决定我应该开发的最低操作系统版本 取决于我选择的版本会产生一些设计影响 例如我可以使用哪些浏览器字段类等 归根结底是 我应该支持低于 OS 5 0 的版本吗 我会
  • 如何确定我使用哪个 GC?

    我没有指定任何GC 我认为我的JVM默认没有启用任何GC 当然我知道OpenJDK8默认使用ParallelGC 但我认为它应该可以通过命令行打印 如下所示 java XX PrintFlagsFinal grep Use grep GC
  • GCC循环展开标志真的有效吗?

    在C中 我有一个任务 我必须用以下方法进行乘法 反转 转置 加法等 huge矩阵分配为二维数组 数组的数组 我找到了 gcc 标志 funroll all loops 如果我理解正确 这将自动展开所有循环 而无需程序员做任何努力 我的问题