Является ли бит сдвигом (по меньшей мере, 1 позиции) на коротком или байте быстрее (требуется меньше циклов процессора), чем сдвиг бит на целое (для архитектуры AMD64 или x86)? Я подозреваю, что ответ не из-за того, что в обоих случаях будет использоваться одна и та же 32-разрядная 64-разрядная команда процессора, и оба будут принимать одинаковое количество тактовых циклов. Это правда?Эффективность битового сдвига
ответ
Это зависит. Вообще говоря, если у вас есть N-разрядный процессор, то, скорее всего, все до N бит будут перемещаться в одно и то же время, большие переменные занимают больше времени. Если вы выполняете операции над байтами, но хотите, чтобы вы использовали целочисленное число подходящего размера для скорости, используйте тип .
Но: если вы выполняете смещение битов в цикле, тогда компилятор может иметь возможность векторизовать ваш код. Если у вас есть процессор с инструкциями SSE2, он может выполнять 8 16-разрядных сдвигов в одной инструкции. Если у вас есть AVX или даже AVX512, он может сделать 16 или даже 32 16-битных сдвига в одной инструкции. Однако, эффективнее, чем использование регулярных инструкций, зависит от того, насколько легко загружать многие переменные в регистры SSE, и если вы выполняете больше операций, чем просто сдвиги бит на них.
Поучительно посмотреть на выход ассемблера из компилятора (например, использовать gcc -save-temps
для компиляции вашей программы и посмотреть полученный файл .s
). Обратите внимание, что выбранный уровень оптимизации оказывает очень большое влияние на сгенерированный ассемблер.
Лучший способ определить, какой самый быстрый переменный размер - это просто его измерить.
Код, который был опубликован ранее, был неправильным. Хотя код содержал сдвиг, поскольку результат не был сохранен, компилятор просто пропустил его. Вот простой ИНТ пример:
void main() {
int value = 0;
value = value << 3;
}
Краткое пример:
void foo() {
short value = 0;
value = value << 3;
}
Integer пример генерирует:
.file "main.c"
.text
.globl _Z3foov
.def _Z3foov; .scl 2; .type 32; .endef
.seh_proc _Z3foov
_Z3foov:
.LFB0:
pushq %rbp
.seh_pushreg %rbp
movq %rsp, %rbp
.seh_setframe %rbp, 0
subq $16, %rsp
.seh_stackalloc 16
.seh_endprologue
movl $0, -4(%rbp)
sall $3, -4(%rbp)
nop
addq $16, %rsp
popq %rbp
ret
.seh_endproc
.ident "GCC: (GNU) 5.4.0"
Короткий пример генерирует:
.file "main.c"
.text
.globl _Z3foov
.def _Z3foov; .scl 2; .type 32; .endef
.seh_proc _Z3foov
_Z3foov:
.LFB0:
pushq %rbp
.seh_pushreg %rbp
movq %rsp, %rbp
.seh_setframe %rbp, 0
subq $16, %rsp
.seh_stackalloc 16
.seh_endprologue
movw $0, -2(%rbp)
movswl -2(%rbp), %eax
sall $3, %eax
movw %ax, -2(%rbp)
nop
addq $16, %rsp
popq %rbp
ret
.seh_endproc
.ident "GCC: (GNU) 5.4.0"
Короткий пример выполняет:
movw $0, -2(%rbp)
movswl -2(%rbp), %eax
sall $3, %eax
movw %ax, -2(%rbp)
Integer пример выполняет:
movl $0, -4(%rbp)
sall $3, -4(%rbp)
Так это выглядит, как без какой-либо оптимизации компилятора, целочисленный сдвиг на самом деле быстрее.
Как насчет других процессоров, таких как серия ARM? –
Чувак, никакой сдвиг даже не выполняется ни в одной из этих функций, они оба просто сохраняют ноль в локальной переменной, с двумя различными смещениями кадра для двух разных размеров. –
Ответ на этот вопрос (если вы действительно сдвигаете этот пример), будет занимать 1 такт (или меньше), чтобы сделать shft, если нет стойки конвейера на современном процессоре x86. – drescherjm
Моя гипотеза заключается в том, что сдвиги в 8-битных или 16-разрядных (без знака) целых числах такие же, как сдвиги бит в 32-битных количествах на 32-разрядных машинах слов.
Большинство 32-разрядных процессоров размера слова работают внутри 32-битных величин. Переключатель ствола, арифметический блок и т. Д. Предназначены для 32-разрядных операций. Механизм выборки данных преобразует 8-битное или 16-битное количество в 32-битное количество до того, как произойдет операция сдвига. 32-битное количество не требует каких-либо корректировок, поэтому может быть небольшая задержка с целыми числами меньшего размера.
С другой стороны, могут быть процессоры, имеющие специальные пути данных для 8-битных или 16-разрядных целых чисел.
Способ проверки - это профиль в вашей системе и других целевых системах.
Кроме того, спросите себя, важна или значительна разница во времени выполнения.
- 1. Эффективность кодирования битового сдвига (т. Е. Аккуратные трюки)
- 2. Странное поведение битового сдвига
- 3. Потрясающее поведение битового сдвига
- 4. Арифметическое объяснение битового сдвига (C)
- 5. Переместить бит битового сдвига python
- 6. Оператор битового сдвига со сдвигом по отрицательному числу
- 7. Преобразование в двоичный файл с использованием побитового и битового сдвига
- 8. Преобразовать C++ код (с указателями и битового сдвига) на C#
- 9. Обратное битового сдвига влево в формате 1 << п
- 10. Эффективность слушателей Эффективность
- 11. Эффективность и эффективность алгоритмов
- 12. MIPS Использование операторов битового сдвига для печати десятичного разряда в двоичном формате
- 13. Как сохранить несколько небольших целых чисел в одном целое с помощью битового сдвига?
- 14. VS предупреждение сборник: результат 32-битового сдвига неявно преобразуется в 64 бита
- 15. Есть ли функция для циклического битового сдвига для массива байтов в C#?
- 16. Как оператор битового сдвига реализован в C. Является ли он атомарным?
- 17. Использование оператора бит-сдвига сдвига в ConcurrentHashMap
- 18. Операторы сдвига
- 19. Ошибка битового соединения
- 20. Представьте цвет битового поля
- 21. Алгоритм сжатия битового потока
- 22. Алгоритм битового сопоставления
- 23. Вставка значений битового знака
- 24. AFNetworkActivity битового кода
- 25. _int64 битового поле
- 26. Концепция битового поля
- 27. Операция битового окна
- 28. Java Строка битового массива
- 29. членов повторения битового поля
- 30. Принимая адрес битового поля
Что скажут тесты на вашем оборудовании? Какой машинный код испускается для ваших случаев использования? – tadman
Лучшая ставка здесь - сравнить пример, который правильно отражает вашу проблему. Есть много проблем, не связанных с циклами, потребляемыми одной инструкцией, которая может ускорить или замедлить вашу программу (загрузка/хранение, simd и т. Д.). –
*** Является ли сдвиг бит (не менее 1 позиции) коротким или байтом быстрее (требуется меньше циклов процессора), чем сдвиг бит на целое число (для архитектуры AMD64 или x86)? *** № – drescherjm