Страницы

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

воскресенье, 26 января 2020 г.

Оптимизирует ли это код?

#ресурсы #c #оптимизация #cpp #производительность


Имеется 2 цикла:
for (i = 0; i < a + 1; i++) { }

и
b = a + 1;
for (i = 0; i < b; i++) { }

Вычисляет ли процессор по новой при каждом прохождении цикла значение a + 1?
То есть, по другому говоря, с точки зрения экономии ресурсов код №2 лучше №1?    


Ответы

Ответ 1



Вот результат gcc-4.6.1 на x86-64: #include int main() { int a = 10; for (int i = 0; i < a + 1; i++) { printf("iteration: %d\n", i); } } Собираем gcc -O2 -g -Wall -std=c99 -o test test.c В gdb видим вот такое: 0x400440
push %rbx 0x400441 xor %ebx,%ebx 0x400443 nopl 0x0(%rax,%rax,1) 0x400448 mov %ebx,%edx 0x40044a xor %eax,%eax 0x40044c mov $0x40063c,%esi 0x400451 mov $0x1,%edi 0x400456 add $0x1,%ebx 0x400459 callq 0x400430 <__printf_chk@plt> 0x40045e cmp $0xb,%ebx 0x400461 jne 0x400448 0x400463 xor %eax,%eax 0x400465 pop %rbx 0x400466 retq Т.е. видим, что компилятор сам все прекрасно довел до константы 11 (см. main+30). С другой стороны, вызовы функций стоит делать руками. Вот такое gcc уже не потянул, printf в функции сбил его с толку: #include int foo() { printf("called foo\n"); return 10; } int main() { for (int i = 0; i < foo() + 1; i++) { printf("iteration: %d\n", i); } } Там уже call на каждую итерацию. Premature optimization is the root of all evil —Donald Knuth

Ответ 2



Если код, находящийся внутри цикла не имеет побочных эффектов и компилятору это известно, то он может оптимизироваться и выполниться только один раз. Если функция импортируется, например из dll, то компилятор не может знать что внутри, и будет вызывать её на каждой итерации. То же самое будет, если этот код изменяет внешнюю переменную.

Ответ 3



Тут все зависит от компилятора, какой машинный код он сделает. Современные компиляторы (типа gcc) такие ситуации хорошо оптимизируют. Т.е. они все-таки вычислят перед циклом сумму и уже с ней будут делать сравнение.

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

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