Fastest implementation of log2(int) and log2(float)

前端 未结 9 1464
天命终不由人
天命终不由人 2020-12-08 04:57

The question is

Are there any other (and/or faster) implementations of a basic 2log?

Applications

The log2(int) and

相关标签:
9条回答
  • 2020-12-08 05:18

    Took the binary solution already mentioned and removed the branching. Did some testing and it turned out to be 1.3 times faster than DeBruijn.

    public static int Log2(int v)
    {
        int r = 0xFFFF - v >> 31 & 0x10;
        v >>= r;
        int shift = 0xFF - v >> 31 & 0x8;
        v >>= shift; 
        r |= shift;
        shift = 0xF - v >> 31 & 0x4;
        v >>= shift;
        r |= shift;
        shift = 0x3 - v >> 31 & 0x2;
        v >>= shift;
        r |= shift;
        r |= (v >> 1);
        return r;
    }
    
    0 讨论(0)
  • 2020-12-08 05:18

    Here is the fastest implementation of log2(int) for C#:

        [StructLayout(LayoutKind.Explicit)]
        private struct ConverterStruct
        {
            [FieldOffset(0)] public int asInt;
            [FieldOffset(0)] public float asFloat;
        }
    
        public static int Log2(uint val)
        {
            ConverterStruct a;  a.asInt = 0; a.asFloat = val;
            return ((a.asInt >> 23 )+ 1) & 0x1F;
        }
    

    Notes: The inspiration for using the exponent in a float is from SPWorley 3/22/2009. Use with caution on production code since this would fail on architectures that are not little-endianness.

    If you want something "endianness" safe then check out spender 5/3/2012. It also has Zero support.

    Here are some benchmarks: (code here: https://github.com/SunsetQuest/Fast-Integer-Log2)

    Function                 Time1  Time2    Errors  Full-32-Bit Zero_Support
    Log2_SunsetQuest3:        18     18       0        (Y)        (N)
    Log2_SunsetQuest4:        18     18       0        (Y)        (N)
    Log2_SPWorley:            18     18       0        (Y)        (N)
    MostSigBit_spender:       20     19       0        (Y)        (Y)
    Log2_HarrySvensson:       26     29       0        (Y)        (N)
    Log2_WiegleyJ:            27     23       0        (Y)        (N)
    Log2_DanielSig:           28     24    3125        (N)        (N)
    FloorLog2_Matthew_Watson: 29     25       0        (Y)        (Y)
    Log2_SunsetQuest1:        31     28       0        (Y)        (Y)
    HighestBitUnrolled_Kaz:   33     33    3125        (Y)        (Y)
    Log2_Flynn1179:           58     52       0        (Y)        (N)
    GetMsb_user3177100:       58     53       0        (Y)        (N)
    Log2floor_greggo:         89    101       0        (Y)        (Y)
    SomeOtherMethod0:        102     43       0        (Y)        (N)
    Log2_SunsetQuest2:       118    140       0        (Y)        (Y)
    SomeOtherMethod1:        125     60       0        (Y)        (N)
    SomeOtherMethod2:        136    118       0        (Y)        (N)
    Log2_SunsetQuest0:       206    202       0        (Y)        (Y)
    SomeOtherMethod3:        228    240    3125        (N)        (Y)
    SomeOtherMethod4:       2346   1494       0        (Y)        (N)
    
    Zero_Support = Supports Neg Return on Zero
    Full-32-Bit  = Supports full 32-bit (some just support 31 bits)
    Time1 = benchmark for sizes up to 32-bit (same number tried for each size)
    Time2 = benchmark for sizes up to 16-bit (for measuring perf with small numbers)
    SomeOtherMethods = name of function/person left out on purpose
    Benchmark notes: AMD Ryzen CPU, Release mode, no-debugger attached, .net core 2.1
    
    0 讨论(0)
  • 2020-12-08 05:29

    clean reliable and fast!
    (requires .net core 3 or later)

    int val = BitOperations.Log2(x);
    
    0 讨论(0)
提交回复
热议问题