【问题标题】:When compiling programs to run inside a VM, what should march and mtune be set to?在编译程序以在 VM 中运行时,march 和 mtune 应该设置为什么?
【发布时间】:2026-01-23 09:05:03
【问题描述】:

由于虚拟机从属于主机提供的任何内容,应该向 gcc 提供哪些编译器标志?

我通常认为-march=native 将是您在编译专用框时会使用的,但-march=native 将如this article 所示的精细细节让我非常谨慎地使用它。

那么...在 VM 中设置 -march-mtune 是什么?


举个具体的例子……

我现在的具体情况是在基于 KVM 的“云”主机内的 linux 客户机中编译 python(以及更多),我无法真正控制主机硬件(除了像 CPU GHz m CPU 这样的“简单”东西计数和可用 RAM)。目前,cpuinfo 告诉我我有一个“AMD Opteron(tm) 处理器 6176”,但老实说,我还不知道这是否可靠,以及客人是否可以转移到我身上的不同架构来见面主机的基础架构改组需求(听起来很麻烦/不太可能)。

我能真正保证的是我的操作系统,它是一个 64 位 Linux 内核,uname -m 产生 x86_64

【问题讨论】:

  • 大概cpuid 信息应该领先于-march。 KVM 可以合成一个受限制的 CPUID,然后将映像移动到任何匹配或超过该受限制 CPUID 的硬件。例如。如果 KVM 声明 SSE2,它可以将虚拟机随机分配到任何支持 SSE2 的 CPU。 -mtune 有点猜测,因为您不知道要调整哪个 CPU。

标签: linux gcc virtualization compiler-optimization


【解决方案1】:

GCC 4.6.3 Standard C++ Library Manual3.17.14 Intel 386 and AMD x86-64 Options 部分的一些不完整和乱序的摘录(我希望是相关的)。

-march=cpu-type
  Generate instructions for the machine type cpu-type.  
  The choices for cpu-type are the same as for -mtune.  
  Moreover, specifying -march=cpu-type implies -mtune=cpu-type. 

-mtune=cpu-type
  Tune to cpu-type everything applicable about the generated code,  
  except for the ABI and the set of available instructions.  
  The choices for cpu-type are:
    generic
      Produce code optimized for the most common IA32/AMD64/EM64T processors. 
    native
      This selects the CPU to tune for at compilation time by determining
      the processor type of the compiling machine. 
      Using -mtune=native will produce code optimized for the local machine
      under the constraints of the selected instruction set.
      Using -march=native will enable all instruction subsets supported by
      the local machine (hence the result might not run on different machines). 

我发现最有趣的是specifying -march=cpu-type implies -mtune=cpu-type。我对其余部分的看法是,如果你指定 both -march-mtune 你可能太接近了,无法调整过度杀伤力。

我的建议是只使用-m64 并且您应该足够安全,因为您在 x86-64 Linux 中运行,对吗?

但是,如果您不需要在另一个环境中运行,并且您感到幸运且具有容错能力,那么 -march=native 可能也适合您。

-m32
  The 32-bit environment sets int, long and pointer to 32 bits  
  and generates code that runs on any i386 system.     
-m64
  The 64-bit environment sets int to 32 bits and long and pointer  
  to 64 bits and generates code for AMD's x86-64 architecture.

为了它的价值......

出于好奇,我尝试使用您引用的文章中描述的技术。我在作为 VMware Player 来宾运行的 64 位 Ubuntu 12.04 中测试了 gcc v4.6.3。 VMware VM 在使用 Intel Pentium Dual-Core E6500 CPU 的桌面上在 Windows 7 中运行。

gcc 选项 -m64 仅替换为 -march=x86-64 -mtune=generic

但是,使用 -march=native 编译会导致 gcc 使用以下所有更具体的编译器选项。

-march=core2 -mtune=core2 -mcx16 
-mno-abm -mno-aes -mno-avx -mno-bmi -mno-fma -mno-fma4 -mno-lwp 
-mno-movbe -mno-pclmul -mno-popcnt -mno-sse4.1 -mno-sse4.2 
-mno-tbm -mno-xop -msahf --param l1-cache-line-size=64 
--param l1-cache-size=32 --param l2-cache-size=2048

所以,是的,正如 gcc 文档在“使用 -march=native ... 结果可能无法在不同的机器上运行”时所述。为了安全起见,您可能应该只使用-m64 或显然等效的-march=x86-64 -mtune=generic 进行编译。

我看不出你会有什么问题,因为这些编译器选项的目的是 gcc 将生成能够在 any x86-64/amd64 兼容 CPU 上正确运行的代码。 (没有?)

坦率地说,我对 gcc -march=native CPU 选项的具体程度感到惊讶。我不知道如何使用 CPU 的 L1 缓存大小为 32k 来微调生成的代码。但显然 如果 有办法做到这一点,那么使用 -march=native 将允许 gcc 做到这一点。

我想知道这是否会带来明显的性能提升?

【讨论】:

【解决方案2】:

有人会认为客户操作系统报告的 CPU 架构是您应该优化的。否则,我会称之为错误。有时出现错误可能是有正当理由的,但是...

请注意,并非所有虚拟机管理程序都必须相同。

查看特定虚拟机管理程序的邮件列表可能是个好主意。

【讨论】:

    最近更新 更多