Инструкция сдвига быстрее, чем инструкция IMUL? - PullRequest
11 голосов
/ 25 мая 2011

Какой из них быстрее -

val = val*10;

или

val = (val<<3) + (val<<2);

Сколько тактов занимает imul по сравнению с инструкцией сдвига?

Ответы [ 4 ]

60 голосов
/ 25 мая 2011

Это 21 век. Современное оборудование и компиляторы знают, как создавать высокооптимизированный код. Написание умножения с использованием сдвигов не повлияет на производительность, но поможет создать код с ошибками.

Вы сами продемонстрировали это с помощью кода, который умножается на 12, а не на 10.

10 голосов
/ 25 мая 2011

Я бы сказал, просто напишите val = val * 10; или val *= 10;, и позвольте компилятору беспокоиться о таких вопросах.

8 голосов
/ 31 мая 2011

В этом случае они, вероятно, занимают одинаковое количество циклов, хотя для вашей "оптимизации" вручную требуется еще один регистр (который может замедлить окружающий код):

val = val * 10;
lea    (%eax,%eax,4),%eax
add    %eax,%eax

против

val = (val<<3) + (val<<1);
lea    (%eax,%eax,1),%edx
lea    (%edx,%eax,8),%eax

Компилятор знает, как сделать снижение прочности , и, вероятно, намного лучше, чем вы. Кроме того, когда вы переносите свой код на другую платформу (скажем, ARM), компилятор также знает, как снизить нагрузку на эту платформу (x86 LEA предоставляет возможности оптимизации, отличные от ARM ADD и RSB).

3 голосов
/ 25 мая 2011

Выполнение таких глупых «оптимизаций» вручную на языке высокого уровня ничего не даст, кроме как показать людям, что вы не знакомы с современными технологиями и методами программирования.

Если вы пишете на ассемблере напрямую, имеет смысл беспокоиться об этом, но это не так.

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

x *= a[i];

Если профилирование показывает, что это является основным узким местом в вашей программе, вы можете заменить его следующим:

x = (x<<s1[i]) + (x<<s2[i]);

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

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