Почему компилятор не оптимизирует эту простую идиому? - PullRequest
4 голосов
/ 25 февраля 2020

У меня есть этот код, и мне интересно, почему компилятор не соединяет двухсимвольные сравнения с 16-битным сравнением.

inline bool beginswith (char c0, char c1, const char* s) {
    return (s[0] == c0) & (s[1] == c1);
}

bool test(const char* s) {
    return beginswith('0', 'x', s);
}

Я ожидаю две версии в моем Godbolt ссылка (test и test2) для компиляции с эквивалентными инструкциями. Есть ли что-то, чего я упускаю, потому что это кажется довольно тривиальной оптимизацией.

Редактировать: причина, по которой я хотел бы, чтобы компилятор выполнил эту оптимизацию, состоял в том, чтобы я мог писать переносимый код без неопределенного поведения и по-прежнему заполняться производительность.

1 Ответ

1 голос
/ 25 февраля 2020

Похоже, что компиляторы просто недостаточно умны, чтобы рассматривать встраивание как особый случай. Они генерируют тот же код, что и в случае, когда функция имеет внешнюю связь, и в этом случае связь между параметрами c0 и c1 не предполагается.

Внутри функции c0 и c1 находятся в локальных копиях в соответствии с соглашением о вызовах ABI, которое не обязательно размещает их рядом друг с другом для выравниваемого доступа - даже если это действительно case в вашем конкретном примере c x86.

Изменение кода вызывающего абонента на alignas(int) char str[2] = {'0', 'x'}; return beginswith(str[0],str[1],s); не имеет значения, поэтому выравнивание также не является (единственной) причиной.

Однако, если вы измените функцию следующим образом:

inline bool beginswith (char c0, char c1, const char* s)
{
    char tmp[2] = {c0, c1};
    return memcmp(tmp, s, 2);
}

Тогда вы получите идентичный машинный код в обоих случаях ( godbolt ].

test(char const*):
  cmp WORD PTR [rdi], 30768
  setne al
  ret

Следует отметить, что *(const short*)s в test2 - неопределенное поведение, строгое нарушение псевдонимов. Машинный код для этой строки может не оставаться детерминированным c, когда программа начинает масштабироваться или когда настройки оптимизатора Это в основном качество реализации, где стандарт не дает никаких гарантий и test2 может сломаться в любой момент.

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