使用GCC-9.2.0(x86)删除CMOV指令

使用GCC-9.2.0(x86)删除CMOV指令,gcc,g++,x86-64,branch-prediction,Gcc,G++,X86 64,Branch Prediction,我希望使用传统的GCC优化(如使用-O2/3)编译一组基准测试套件,并将其与不使用cmov指令的相同基准测试进行比较。我已经看到了一些关于这个问题的帖子/网站(都是几年前发布的,因此引用了比9.2.0更旧的GCC版本)。基本上,这些问题的答案是使用以下四个标志(这是我在网上找到的所有内容的一个很好的总结): 根据这个建议,我使用以下命令编译我的基准测试(理论上没有cmov指令) 然而,我仍在寻找使用cmov的实例。如果我将优化标志更改为-O0,则不会生成cmov指令,因此我假设必须有某种方法在G

我希望使用传统的GCC优化(如使用-O2/3)编译一组基准测试套件,并将其与不使用cmov指令的相同基准测试进行比较。我已经看到了一些关于这个问题的帖子/网站(都是几年前发布的,因此引用了比9.2.0更旧的GCC版本)。基本上,这些问题的答案是使用以下四个标志(这是我在网上找到的所有内容的一个很好的总结):

根据这个建议,我使用以下命令编译我的基准测试(理论上没有cmov指令)

然而,我仍在寻找使用cmov的实例。如果我将优化标志更改为
-O0
,则不会生成cmov指令,因此我假设必须有某种方法在GCC中禁用此功能,而无需修改c代码/程序集

下面是我试图禁用的代码片段示例(最后一条指令是我希望避免的cmov):


如果有人有任何建议或指导,我们将不胜感激。

对于32位代码(
-m32
),您可以使用
-march=pentium-mtune=skylake
;CMOV是P6的新版本,不受P5奔腾的支持。但是,您必须使用32位代码,其遗留堆栈args调用约定和一半寄存器
-march=pentium
不能用于64位代码,CMOV是x86-64的基线。)感谢您提供的信息。我不太熟悉gcc是如何工作的(或者根本不熟悉),但经过更多的研究,我发现并通过了处理if转换的过程。除了前面提到的标志外,通过使用-fdisable tree phiopt[1-4]和-fdisable rtl ce[1-3]标志,我似乎能够在大多数情况下阻止生成cmov指令。我不太清楚GCC内部结构,比如哪个过程到底做了什么。这些过程还可能包括其他重要的优化,因此,如果您希望实际对生成的代码进行基准测试,那么这可能不是一个公平的比较。如果您修改了GCC源代码,那么您可能可以构建一个不知道用于x86-64的CMOV的版本,但仍然可以进行其他优化。这可能更接近公平,尽管可能有一些GCC调优试探法是在假设CMOV是可能的情况下进行调优的。对于32位代码(
-m32
),您可以使用
-march=pentium-mtune=skylake
;CMOV是P6的新版本,不受P5奔腾的支持。但是,您必须使用32位代码,其遗留堆栈args调用约定和一半寄存器
-march=pentium
不能用于64位代码,CMOV是x86-64的基线。)感谢您提供的信息。我不太熟悉gcc是如何工作的(或者根本不熟悉),但经过更多的研究,我发现并通过了处理if转换的过程。除了前面提到的标志外,通过使用-fdisable tree phiopt[1-4]和-fdisable rtl ce[1-3]标志,我似乎能够在大多数情况下阻止生成cmov指令。我不太清楚GCC内部结构,比如哪个过程到底做了什么。这些过程还可能包括其他重要的优化,因此,如果您希望实际对生成的代码进行基准测试,那么这可能不是一个公平的比较。如果您修改了GCC源代码,那么您可能可以构建一个不知道用于x86-64的CMOV的版本,但仍然可以进行其他优化。这可能更接近公平,尽管可能有一些GCC调优试探法是在假设CMOV是可能的情况下进行调优的。也许没什么大不了的,艾德克。
-fno-if-conversion -fno-if-conversion2 -fno-tree-loop-if-convert -fno-tree-loop-if-convert-stores
g++-9.2.0 -std=c++11 -O2 -g -fno-if-conversion -fno-if-conversion2 -fno-tree-loop-if-convert -fno-tree-loop-if-convert-stores -fno-inline *.C -o bfs-nocmov
  int mx = 0;
  for (int i=0; i < n; i++)
  41bc8a:   45 85 e4                test   %r12d,%r12d
  41bc8d:   7e 71                   jle    41bd00 <_Z11suffixArrayPhi+0xe0>
  41bc8f:   41 8d 44 24 ff          lea    -0x1(%r12),%eax
  41bc94:   48 89 df                mov    %rbx,%rdi
.../suffix/src/ks.C:92
  int mx = 0;
  41bc97:   31 c9                   xor    %ecx,%ecx
  41bc99:   48 8d 54 03 01          lea    0x1(%rbx,%rax,1),%rdx
  41bc9e:   66 90                   xchg   %ax,%ax
.../suffix/src/ks.C:94
    if (s[i] > mx) mx = s[i];
  41bca0:   44 0f b6 07             movzbl (%rdi),%r8d
  41bca4:   44 39 c1                cmp    %r8d,%ecx
  41bca7:   41 0f 4c c8             cmovl  %r8d,%ecx
  for (int i=0; i < n; i++) 
 c67:   8b 45 e8                mov    -0x18(%rbp),%eax
 c6a:   3b 45 d4                cmp    -0x2c(%rbp),%eax
 c6d:   7d 34                   jge    ca3 <_Z11suffixArrayPhi+0x105>
.../suffix/src/ks.C:94
    if (s[i] > mx) mx = s[i];
 c6f:   8b 45 e8                mov    -0x18(%rbp),%eax
 c72:   48 63 d0                movslq %eax,%rdx
 c75:   48 8b 45 d8             mov    -0x28(%rbp),%rax
 c79:   48 01 d0                add    %rdx,%rax
 c7c:   0f b6 00                movzbl (%rax),%eax
 c7f:   0f b6 c0                movzbl %al,%eax
 c82:   39 45 e4                cmp    %eax,-0x1c(%rbp)
 c85:   7d 16                   jge    c9d <_Z11suffixArrayPhi+0xff>
.../suffix/src/ks.C:94 (discriminator 1)
 c87:   8b 45 e8                mov    -0x18(%rbp),%eax
 c8a:   48 63 d0                movslq %eax,%rdx
 c8d:   48 8b 45 d8             mov    -0x28(%rbp),%rax
 c91:   48 01 d0                add    %rdx,%rax
 c94:   0f b6 00                movzbl (%rax),%eax
 c97:   0f b6 c0                movzbl %al,%eax
 c9a:   89 45 e4                mov    %eax,-0x1c(%rbp)