【问题标题】:Choose a C binary according to the enviroment根据环境选择一个C二进制
【发布时间】:2015-10-27 04:38:39
【问题描述】:

我已使用特定标志(-Os、-O2、-march=native 及其组合)编译了我的代码,以便产生更快的执行时间。

但我的问题是我并不总是在同一台机器上运行(因为在我的实验室里有几台不同的机器)。有时我在 MacOS 或 Linux 中运行(在这两种情况下使用不同的操作系统版本)。

我想知道是否有一种方法可以根据二进制文件运行的环境(我的意思是缓存大小、cpu 内核和特定机器的其他属性)来确定运行哪个二进制文件?换句话说,如何根据使用的具体机器(程序加载时)选择速度更快的二进制文件(之前编译时使用不同的目标二进制文件大小和指令集扩展名)?

提前致谢。

【问题讨论】:

  • 用所有机器指纹和二进制名做字典。但我想知道您可能获得的潜在速度改进是否值得麻烦。
  • 对不起@rodrigo,但我没看懂这句话Do dictionary with all the machine fingerprint and the binary name。是的,由于我使用的是 Sotf-Sphere Molecular Dynamics 模拟,因此改进可能非常显着。事实上,加快速度可能意味着执行时间可能会减少数天
  • 我的意思是:构建您需要的所有二进制文件,但名称不同;然后编写一个脚本/程序来检查机器,选择正确的程序并exec()s 它。
  • 只需要问一下 - 您是否考虑过在 Apple 机器上使用 Linux 虚拟机?它可能会比本机执行慢一点,但如果您的 Linux 和 Apple 机器都是 x86-64,那么硬件虚拟化功能可能会将速度降到最低。
  • @tonysdg 您的建议可以在所有计算机中使用唯一的可执行文件(通过选择特定的 -O 标志创建以获得测试机器的最佳二进制文件),但可能我会得到更好的结果用-O2 -march=native在每台机器上编译。

标签: c++ c compilation conditional-compilation


【解决方案1】:

您所说的称为胖二进制文件(不是 FAT,首字母缩写词)。来自维基百科1

胖二进制文件(或多架构二进制文件)是一种计算机可执行程序,它已扩展(或“胖化”)了多个指令集的本机代码,因此可以在多种处理器类型上运行。这导致文件比普通的单一架构二进制文件大,因此得名。

乍一看,似乎没有太多支持(有关更多信息,请参阅 Programmer StackExchange 的this question)。 Apple 在从 PowerPC 过渡到 Intel 时短暂地实现了这一点,但从那时起似乎并没有进行太多探索。

从技术上讲,胖二进制文件是指可以在多个体系结构上运行的单个二进制文件……但我想前提将适用于在多个操作系统上运行的单个二进制文件。这又回到了 Bizkit 在他/她/zir 的回答中提出的观点 - 通常,您会提前为您所处的环境编译源代码。

【讨论】:

  • 我赞成您的回答,因为它提供了另一种解决问题的方法。但是正如您所建议的那样, fat binary 并不是这样做的实用方法。您自己提供的链接很好地说明了这一点,而且形式简单明了。
  • @Bruce_Warrior 很抱歉没有提供更好的答案 - 不幸的是,我不知道有一个答案,但我认为这可能会提供一些有用的信息。对于它的价值,我投票赞成并收藏了你的问题,因为我有兴趣看到答案:)
  • 英特尔编译器也会创建胖二进制文件。
【解决方案2】:

您可以预先构建一堆可执行文件并根据环境变量或uname 之类的内容选择一个。解决问题的更好方法是选择能够执行 JIT、安装时优化和/或运行时优化的工具链,例如 llvm。

【讨论】:

    【解决方案3】:

    你有什么理由不能在每台机器上重新编译你的源代码?编译器已经针对这类东西进行了编写和优化。只需在该机器架构上重新编译您的源代码,您就会拥有在该机器上运行良好的二进制文件。

    【讨论】:

    • 对缓存大小或内核数量没有帮助。
    • 是的,但唯一有助于提高内核数量的方法是自己实际编写一些多线程代码;没有脚本或编译器会为您做到这一点。无论如何,串行代码都将在单个内核上运行。至于缓存大小,编译器不是为了以打包/对齐结构的形式优化缓存大小而编写的吗?
    • 什么 ass-backwards 编译器会根据它运行的硬件进行优化?有关目标架构和所需功能集的信息由开发人员传递给编译器。
    • AFAIK,编译器目前不会在缓存大小的阻塞/平铺循环级别上重构程序。这仍然只是源级优化。 ATLAS(一个矩阵数学库)在其构建系统中运行一些基准测试,以查找缓存属性并为正在编译的机器选择最佳大小。 math-atlas.sourceforge.net 重点是,我不知道有任何 gcc/clang 功能可以利用缓存属性。
    • @Bizkit 我可以在每台机器上重新编译代码,但我想按照我的要求找到每台机器的最佳编译。我读到基准取决于机器、SO、编译器甚至编译器版本,因此必须确定每台机器中更好的优化是一项繁琐的工作。但显然,为了产生安全和更快的执行,最直接的方法是使用-O2 -march=native 标志(无论是 gcc 还是 clang)进行编译。在这种形式下,我不必在每台机器上方便地检查所有可能的 -O 优化及其排列。
    【解决方案4】:

    如果您希望您的代码针对您运行的机器的缓存大小进行调整,请查看Automatically Tuned Linear Algebra Software (ATLAS) 的做法。当你编译它时,它会运行一些测试来找到用于缓存阻塞其循环的大小,并将其放入头文件中。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-11-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-06-26
      • 2019-03-13
      相关资源
      最近更新 更多