【发布时间】: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