Сравнение в цикле (оптимизация)

Давайте рассмотрим ситуацию:

bool b = checking_some_condition();

for (int i = 0; i < 1000000; ++i)
{
if (b)
do_something(i);
else
do_something_else(i);
}

Очевидно ли, что компилятор оптимизирует приведенный выше код в нечто подобное? :

if (b)
{
for (int i = 0; i < 1000000; ++i)
do_something(i);
}
else
{
for (int i = 0; i < 1000000; ++i)
do_something_else(i);
}

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

0

Решение

Как было упомянуто в комментариях выше, вы не можете сделать безопасное предположение, что компилятор оптимизирует или не оптимизирует. Это их «свобода» делать эти вещи или нет.

Если вы хотите понять, что происходит, лучше всего взглянуть на сгенерированную сборку, которая даст вам объективный способ аргументировать, что, возможно, сделал компилятор. https://godbolt.org/z/W-5Hve показывает простой пример, который вы опубликовали выше.

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

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

Как немного больше: objdump -M intel -dC executable покажет вам сборку исполняемого файла.

4

Другие решения

Других решений пока нет …