Удаление инструкций CMOV с помощью G CC -9.2.0 (x86) - PullRequest
1 голос
/ 24 марта 2020

Я собираюсь скомпилировать набор тестов с использованием традиционных оптимизаций 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)

Если У кого-то есть совет или направление, это было бы очень признательно.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...