What's the fastest way to divide an integer by 3?

后端 未结 12 2124
天涯浪人
天涯浪人 2020-11-29 03:40
int x = n / 3;  // <-- make this faster

// for instance

int a = n * 3; // <-- normal integer multiplication

int b = (n << 1) + n; // <-- potentiall         


        
12条回答
  •  眼角桃花
    2020-11-29 03:49

    There is a faster way to do it if you know the ranges of the values, for example, if you are dividing a signed integer by 3 and you know the range of the value to be divided is 0 to 768, then you can multiply it by a factor and shift it to the left by a power of 2 to that factor divided by 3.

    eg.

    Range 0 -> 768

    you could use shifting of 10 bits, which multiplying by 1024, you want to divide by 3 so your multiplier should be 1024 / 3 = 341,

    so you can now use (x * 341) >> 10
    (Make sure the shift is a signed shift if using signed integers), also make sure the shift is an actually shift and not a bit ROLL

    This will effectively divide the value 3, and will run at about 1.6 times the speed as a natural divide by 3 on a standard x86 / x64 CPU.

    Of course the only reason you can make this optimization when the compiler cant is because the compiler does not know the maximum range of X and therefore cannot make this determination, but you as the programmer can.

    Sometime it may even be more beneficial to move the value into a larger value and then do the same thing, ie. if you have an int of full range you could make it an 64-bit value and then do the multiply and shift instead of dividing by 3.

    I had to do this recently to speed up image processing, i needed to find the average of 3 color channels, each color channel with a byte range (0 - 255). red green and blue.

    At first i just simply used:

    avg = (r + g + b) / 3;

    (So r + g + b has a maximum of 768 and a minimum of 0, because each channel is a byte 0 - 255)

    After millions of iterations the entire operation took 36 milliseconds.

    I changed the line to:

    avg = (r + g + b) * 341 >> 10;

    And that took it down to 22 milliseconds, its amazing what can be done with a little ingenuity.

    This speed up occurred in C# even though I had optimisations turned on and was running the program natively without debugging info and not through the IDE.

提交回复
热议问题