代码之家  ›  专栏  ›  技术社区  ›  lornova

带内函数的前导零点计算

  •  4
  • lornova  · 技术社区  · 14 年前

    这个 default implementation 使用宏和查阅表格:

    /* 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 在x86和 clz 手臂上( http://www.devmaster.net/articles/fixed-point-optimizations/ ),这应该更有效率。

    在Windows CE上,我们有一个内在函数 _CountLeadingZeros

    一个依赖于专用ASM指令的内部函数怎么可能慢4倍呢?

    1 回复  |  直到 14 年前
        1
  •  5
  •   Igor Skochinsky    14 年前

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

    此功能可以通过 调用运行时函数。

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

    /QRarch5 ARM5 Architecture
    /QRarch5T ARM5T Architecture
    

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