Страницы

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

понедельник, 23 декабря 2019 г.

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

#cpp #qt #qt5


В справочном примере для макроса 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? Может быть существуют какие-либо
критерии для определения характерных ситуаций, в которых использовании обозначенных
макросов имеет смысл?
    


Ответы

Ответ 1



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

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

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