5

我正在尝试优化一些在嵌入式系统中工作的代码(FLAC 解码、Windows CE、ARM 926 MCU)。

默认实现使用宏和查找表:

/* counts the # of zero MSBs in a word */
#define COUNT_ZERO_MSBS(word) ( \
 (word) <= 0xffff ? \
  ( (word) <= 0xff? byte_to_unary_table[word] + 24 : \
              byte_to_unary_table[(word) >> 8] + 16 ) : \
  ( (word) <= 0xffffff? byte_to_unary_table[word >> 16] + 8 : \
              byte_to_unary_table[(word) >> 24] ) \
)

static const unsigned char byte_to_unary_table[] = {
    8, 7, 6, 6, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4,
    3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
};

bsr然而,大多数 CPU在 x86 和clzARM ( http://www.devmaster.net/articles/fixed-point-optimizations/ ) 上已经有一个专用指令,这应该更有效。

在 Windows CE 上,我们有内部函数_CountLeadingZeros,它应该只是调用那个值。然而,它比宏慢 4 倍(以 1000 万次迭代测量)。

(应该)依赖于专用 ASM 指令的内在函数怎么可能慢 4 倍?

4

1 回答 1

6

检查拆卸。您确定编译器插入了指令吗?在备注部分有以下文本:

该功能可以通过调用运行时函数来实现。

我怀疑这就是你的情况。

请注意,CLZ 指令仅在 ARMv5 及更高版本中可用。如果需要 ARMv5 代码,则需要告诉编译器:

/QRarch5 ARM5 Architecture
/QRarch5T ARM5T Architecture

(微软错误地使用“ARM5”而不是“ARMv5”)

于 2010-10-28T16:45:20.050 回答