Страницы

Поиск по вопросам

вторник, 20 ноября 2018 г.

Q_LIKELY и Q_UNLIKELY как помощь компилятору в оптимизации кода

В справочном примере для макроса Q_LIKELY указан цикл и рассматривается ситуация, когда состояние false может возникнуть, как говорится, в одном случае на миллион:
// the condition inside the "if" will be successful most of the times for(int i = 1; i <= 365; i++) { if(Q_LIKELY(isWorkingDay(i))) { ... } ... }
В целом, эту пользу можно увидеть, учитывая не редкость ситуаций, когда в цикле проверяется значение, подразумевающее нахождение лишь в одном из двух состояний, и при этом одно из них практически всегда будет в подавляющем большинстве случаев.
Но сбивает с толку пример для Q_UNLIKELY, хотя и являющийся, судя по наименованию, всего лишь обратным вариантом:
bool readConfiguration(const QFile &file) { // We expect to be asked to read an existing file if(Q_UNLIKELY(!file.exists())) { qWarning() << "File not found"; return false; }
... return true; }
Какая тут может быть "помощь компилятору" в оптимизации кода, и если она всё-таки имеет место быть, то будет ли справедлива и для Q_LIKELY? Может быть существуют какие-либо критерии для определения характерных ситуаций, в которых использовании обозначенных макросов имеет смысл?


Ответ

В тексте ответа представлено моё субъективное мнение
Я считаю что эти макросы бесполезны в 99.99% случаев и должны применятся лишь после измерений, которые показали, что их использование оправдано. Почему? Потому что то, что сегодня «likely», может стать «unlikely» завтра, а программисты очень часто забывают менять вещи, которое явно не отражаются на программе. Таким образом, у нас может быть какая-то проверка помечена как Q_LIKELY, тогда как на самом деле всё наоборот. И это будет сбивать с толку программиста, который в дальнейшем будет это читать.
«Но как же так, это же оптимизация?!» — довольно спорное заявление, на самом деле, т.к. предсказатели ветвления(branch predictors) в CPU очень хороши, и чем тут реально сможет помочь компилятор непонятно. Вот возьмём цикл из вопроса, после первой же итерации, наиболее вероятно, что CPU начнёт выбирать инструкции по той ветке, что была в первой итерации. Что нам даст явное указание, потенциальный выигрыш в первой итерации? Смехотворно.
Всё это настолько нанооптимизации, что, повторюсь, прибегать к ним стоит лишь по нахождении проблемы с ветвлением, но не раньше. Программисты, помимо плохой памяти, ещё и не очень хороши в определении того, что же будет чаще(likely) исполняться.

Комментариев нет:

Отправить комментарий