Я собираюсь скомпилировать набор тестов с использованием традиционных оптимизаций G CC (как при использовании -O2 / 3) и сравнить его с тем же тестом без использования команд cmov. Я видел несколько сообщений / веб-сайтов, посвященных этой проблеме (все за несколько лет go и, следовательно, ссылающихся на более старую версию G CC, чем 9.2.0). По сути, ответы на них заключались в использовании следующих четырех флагов ( this - хорошее резюме всего, что я нашел в Интернете):
-fno-if-conversion -fno-if-conversion2 -fno-tree-loop-if-convert -fno-tree-loop-if-convert-stores
Следуя этому совету, я использую следующая команда для компиляции моих тестов (теоретически без инструкций cmov).
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
Однако я все еще нахожу примеры использования cmov. Если я изменяю флаг оптимизации на -O0
, команды cmov не генерируются, поэтому я предполагаю, что должно быть какое-то время, чтобы отключить это в G CC без изменения c кода / сборки.
Ниже пример кода, который я пытаюсь отключить (последняя инструкция - это cmov, которого я хочу избежать):
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
Наконец, вот фрагмент кода, сгенерированный с помощью -O0
. Я не могу использовать какой-либо уровень оптимизации ниже -O2
, и хотя ручное манипулирование кодом является опцией, у меня есть много тестов, которые я использую, поэтому я хотел бы найти общее решение.
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)
Если У кого-то есть совет или направление, это было бы очень признательно.