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