和快于整数模运算?

时间:2011-10-06 16:11:00

标签: assembly arm

可以重新表达:

  • i%m

as:

  • i& (M-1)

其中,

  • 我是无符号整数
  • m是2
  • 的幂

我的问题是:AND操作更快吗?现代CPU在单个指令中不支持硬件中的整数模数吗?我对ARM感兴趣,但是在其指令集中没有看到模运算。

6 个答案:

答案 0 :(得分:9)

这些日子比“单一教学”更复杂。现代CPU是复杂的野兽,需要将其指令分解为问题/执行/延迟。它通常还取决于除法/模数的宽度 - 涉及多少位。

在任何情况下,我都不知道32位是任何内核(ARM)上的单周期延迟。在“现代”ARM上有整数除法指令,但仅限于某些实现,最值得注意的是不是最常见的指令 - Cortex A8和A9。

在某些情况下,编译器可以省去将分频/模数转换为位移/屏蔽操作的麻烦。但是,只有在编译时已知值时才可以执行此操作。在你的情况下,如果编译器可以看到肯定,'m'总是一个2的幂,那么它会优化它到位操作,但如果它是一个传递给函数的变量(或否则计算),然后它不能,并将采取完全分裂/模数。这种代码构造通常有效(但并非总是如此 - 取决于优化器的智能程度):

unsigned page_size_bits = 12;
unsigned foo(unsigned address) {
  unsigned page_size = 1U << page_size_bits;
  return address / page_size;
}

诀窍是让编译器知道“page_size”是2的幂。我知道gcc和变体会特殊情况,但我不确定其他编译器。

作为任何核心的经验法则 - 无论是否为ARM(甚至是x86),更喜欢使用位移/掩码来除/模。即使您的核心存在硬件鸿沟,手动执行也会更快。

答案 1 :(得分:5)

您可能对Embedded Live: Embedded Programmers' Guide to ARM’s Cortex-M Architecture感兴趣。

ARM Cortex-M系列具有无符号和有符号的除法指令UDIV和SDIV,需要2到12个周期。没有MOD指令,但通过{S,U} DIV后跟乘法和减法指令MLS获得等效结果,该指令需要2个周期,总共4-14个周期。

AND指令是单周期,因此快4-14倍。

答案 2 :(得分:4)

ARM非常通用。有很多不同的ARM,并且有ARM没有分区指令(正如Ray Toal已经提到过的,模数通常是作为除法实现的附加结果实现的)。因此,如果你不想调用一个非常慢的除法子程序,逻辑运算要快得多(并且正如cyco130所提到的,任何好的编译器都会自己识别它并自己生成逻辑运算 - 所以为了清楚程序代码我会留在师里(除了你编程汇编程序,然后你当然要自己编程,然后你应该采取逻辑运算)。

答案 3 :(得分:4)

如果m在编译时是已知的(或者甚至它不是),则可以使用乘法魔术“乘法逆”来重新表达整数除法和模数。除法的结果以高32位结束,余数(模数)以低32位结束:

http://www.hackersdelight.org/magic.htm

以下链接声称它是标准编译器强度降低:

http://www.flounder.com/multiplicative_inverse.htm

答案 4 :(得分:1)

如果您正在使用具有优化功能的合适C编译器,它将已经将其优化为更快的速度,这种技术称为“强度降低”。如果您正在进行手写组装,那么只有确定的测试方法才能对其进行基准测试。但请注意,即使同一处理器的不同型号也可能会产生不同的结果。

答案 5 :(得分:1)

根据http://www.coranac.com/tonc/text/asm.htm,ARM没有除法指令。如果这是真的,那么我也不希望它有MOD指令。