【问题标题】:gcc -march=native. Way to detect binary built for wrong architecture?gcc -march=native。检测为错误架构构建的二进制文件的方法?
【发布时间】:2016-08-12 00:19:18
【问题描述】:

最近我的云服务器上的基础架构发生了变化,看起来像 我遇到了用gcc -march=native(Ubuntu 14.04,gcc 4.8)编译的代码

它过去总是在 16 核 Intel Xeon E5-2650 v2 上运行,而现在(我猜取决于可用性)它有时会换成更快的 Xeon E5-2650 v3。

二进制工作,但现在看起来在无锁线程同步代码中有奇怪的未定义行为,而以前它曾经 100% 工作。我唯一能想到的是,代码以某种方式为 v3 编译并在 v2 上运行(或相反),两者之间存在一些不兼容。

我宁愿以后避免这种情况。有没有一种好方法可以检测为错误架构编译的二进制文件?


编辑:我检查了,gcc 文档对-march=native 非常清楚:

-march=cpu 类型
为机器类型 cpu-type 生成指令。与 -mtune=cpu-type 相比,它仅针对指定的 cpu-type 调整生成的代码,-march=cpu-type 允许 GCC 生成可能根本无法在指定处理器以外的处理器上运行的代码。指定 -march=cpu-type 意味着 -mtune=cpu-type。

‘原生’
这通过确定编译机的处理器类型来选择 CPU 在编译时为其生成代码。使用 -march=native 启用本地机器支持的所有指令子集(因此结果可能无法在不同的机器上运行)。

gcc -march=native 底层使用的标志判断(strings prg | grep march 如果 prg 是使用调试符号编译的),v2 和 v3 之间的差异看起来相当大。 v3 添加了所有这些并更改了 l2-cache-size:

-mabm -mavx2 -mbmi -mbmi2 -mfma -mlzcnt -mmovbe

如果使用这些新指令集中的任何一个,它就像为 MMX 编译一些东西并期望它在非 MMX 架构上运行......

【问题讨论】:

  • 如果二进制文件被重建,代码是否再次 100% 工作?这听起来更像是因 CPU 更改而暴露的软件错误。
  • 试图重现但很难测试(不能只选择我得到的 cpu...)。可能是一个错误,但不太可能,软件在不同的架构上一直很稳定。
  • @lemonsqueeze x86 内存模型最近没有改变。您可以查看较新 CPU 的勘误表,看看是否有任何可疑之处,但我强烈怀疑这是软件错误。
  • 如果新指令集被使用,它将在不支持它们的架构上SIGILL
  • 它没有得到SIGILL'ed,所以它更有可能是一个错误......

标签: c linux ubuntu gcc pthreads


【解决方案1】:

GCC 将为它使用的架构定义一个预定义的宏 - 例如-march=core2 将定义一个宏__core2。您可以在程序中包含一个命令行选项,该选项使用这些宏来显示编译时所针对的体系结构 - 在这种情况下,您需要检查 __ivybridge__haswell

或者(或同样),您可以让程序显示用于编译它的编译器标志(通过让您的构建系统向程序提供这些标志)。不过,如果您使用的是 -march=native,那将无济于事。

听起来你的问题更有可能是程序中的一个潜在错误,特别是因为它涉及线程同步 - 较新的机器可能更积极地重新排序内存访问,这暴露了你的无锁算法中缺少的障碍。

【讨论】:

  • 谢谢,不知道这些宏,可以派上用场!现在我找到了一种方法,通过检查包装脚本中嵌入在调试符号中的 gcc 标志,使用错误的 cpu 时使其中止,但这并不漂亮......
猜你喜欢
  • 2017-03-09
  • 2016-07-30
  • 1970-01-01
  • 2017-01-14
  • 1970-01-01
  • 2018-08-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多