В наши дни это сложнее, чем «одна инструкция». Современные процессоры - это сложные звери, и их инструкции нужно разбить на выпуск / выполнение / задержку. Это также обычно зависит от ширины деления / по модулю - сколько битов задействовано.
В любом случае, я не знаю, что 32-битная задержка одного цикла на любом ядре, ARM или нет. В «современном» ARM есть инструкции целочисленного деления, но только в некоторых реализациях, и, что особенно важно, не в самых распространенных - Cortex A8 и A9.
В некоторых случаях компилятор может избавить вас от необходимости преобразования деления / модуля по битам / операций сдвига / маски. Однако это возможно только в том случае, если значение известно во время компиляции . В вашем случае, если компилятор может видеть наверняка , что 'm' всегда является степенью двойки, то он оптимизирует его для битовых операций, но если это переменная, переданная в функцию (или иначе вычисляется), то не может и прибегнет к полному разделению / модулю. Этот вид построения кода часто работает (но не всегда - зависит от того, насколько умен ваш оптимизатор):
unsigned page_size_bits = 12;
unsigned foo(unsigned address) {
unsigned page_size = 1U << page_size_bits;
return address / page_size;
}
Хитрость заключается в том, чтобы сообщить компилятору, что "page_size" является степенью двойки. Я знаю, что gcc и варианты будут в особом случае, но я не уверен насчет других компиляторов.
Как правило, для любого ядра - ARM или нет (даже x86), предпочитайте битовое смещение / маску делить / по модулю. Даже если ваше ядро имеет аппаратный разрыв, это будет быстрее сделать это вручную.