Results 1 to 11 of 11

Thread: Dividing by divisors.

  1. #1

    Thread Starter
    Fanatic Member BlindSniper's Avatar
    Join Date
    Jan 2011
    Location
    South Africa
    Posts
    865

    Dividing by divisors.

    Hi all,
    I'm Writing a program and I'm curious about something. If you have a value and you are always dividing by a divisor, is there something faster than Integer division ? Like some sort of bit manipulation ?


    EDIT:
    I just realized that Integer Division is just one instruction, it would be hard to beat it by using more instructions, but in the case of me being wrong, I'll leave the thread open.
    Last edited by BlindSniper; May 19th, 2012 at 04:50 PM.

    Useful CodeBank Entries of mine
    Expand Function
    Code Compiler
    Sudoku Solver
    HotKeyHandler Class

    Read this to get Effective help on VBForums
    Hitchhiker's Guide to Getting Help at VBF

  2. #2
    Only Slightly Obsessive jemidiah's Avatar
    Join Date
    Apr 2002
    Posts
    2,431

    Re: Dividing by divisors.

    Well... if the divisor is a power of 2, you can of course bit shift, which might be faster.

    In the case of gigantic numbers, you could store the prime factorization instead of the number itself, canceling the relevant factors in a division operation. That would probably be faster than a general-purpose BigInt with a huge number of digits, but again it depends on the specifics of your program--are there other gains from storing prime factorizations, or is it wildly inefficient, for instance because of lots of add operations?

    One other thing to consider is that a single instruction can take multiple clock cycles to complete, so one instruction is not always the fastest possible. I don't know how many cycles integer division takes, though it can be pipelined, so in a loop it effectively takes 1 cycle (with a huge number of case-specific caveats I'm not qualified to discuss).

    You might get more informed opinions on another board. This is not really a math question.
    The time you enjoy wasting is not wasted time.
    Bertrand Russell

    <- Remember to rate posts you find helpful.

  3. #3
    Hyperactive Member Lenggries's Avatar
    Join Date
    Sep 2009
    Posts
    353

    Re: Dividing by divisors.

    Generally speaking, multiplication is much faster than division, so instead of dividing, you can multiply by the reciprocal. For example, 12.5 / 10 = 1.25 is slower than 12.5 * 0.1 = 1.25

    Thus, if you can cheaply compute the reciprocal, than just use that.

  4. #4

    Re: Dividing by divisors.

    Quote Originally Posted by Lenggries View Post
    Generally speaking, multiplication is much faster than division, so instead of dividing, you can multiply by the reciprocal. For example, 12.5 / 10 = 1.25 is slower than 12.5 * 0.1 = 1.25

    Thus, if you can cheaply compute the reciprocal, than just use that.
    The easiest way I know of to calculate a reciprocal is to simply raise the number to a power of -1. So, I decided to test out your theory Leggrines in a quick C# console application. The results were as assumed: multiplication is faster than division.

    I tested two equations:
    1) 5 / 9
    2) 5 * (9 ^ - 1)

    I ran those equations 100,000,000 times to see which one went "faster". These tests were run multiple times, and here are the results

    Trial 1
    Equation 1:
    • Average: 81 ticks
    • Total Ticks: 816643

    Equation 2:
    • Average: 78 ticks
    • Total Ticks: 787932


    Trial 2
    Equation 1:
    • Average: 81 ticks
    • Total Ticks: 811916

    Equation 2:
    • Average: 78 ticks
    • Total Ticks: 787409


    Trial 3
    Equation 1:
    • Average: 81 ticks
    • Total Ticks: 814381

    Equation 2:
    • Average: 78 ticks
    • Total Ticks: 783546


    The results are pretty conclusive. Although slim, using reciprocal multiplication does in fact yield faster results than regular division (in C# on my machine; results may vary).

  5. #5

    Re: Dividing by divisors.

    Just a side note, I went ahead and changed a few variables to make the fraction more..."simple". Instead of 9, I changed to an 8 so I could add in Decimal Multiplication to see if I can go even faster. Apparently no, I cannot. Reciprocal multiplication is still the fastest method given.

  6. #6
    PowerPoster boops boops's Avatar
    Join Date
    Nov 2008
    Location
    Holland/France
    Posts
    3,201

    Re: Dividing by divisors.

    What if the divisor is repeated? It might save time to precalculate the reciprocal. So Formless, how does this equation perform in your test:
    3) 5 * 0.111111111111

    BB

  7. #7

    Re: Dividing by divisors.

    Quote Originally Posted by boops boops View Post
    What if the divisor is repeated? It might save time to precalculate the reciprocal. So Formless, how does this equation perform in your test:
    3) 5 * 0.111111111111

    BB
    I remember running a floating point test with a repeating divisor; I believe calculating the reciprocal was averaging the same time as just multiplying by the decimal value. I'll run a few more tests to confirm.

  8. #8

    Thread Starter
    Fanatic Member BlindSniper's Avatar
    Join Date
    Jan 2011
    Location
    South Africa
    Posts
    865

    Re: Dividing by divisors.

    I ran a few tests and in my case Integer Division is Always faster than multiplying with the reciprocal.
    Some Conditions:
    I start out with a Integer.
    I divide with a integer (Which is always a divisor of the first one)
    I need the Result as a Integer.

    The code I used:
    vb.net Code:
    1. Sub Main()
    2.         While True
    3.             Dim st As New Stopwatch
    4.             Dim result As Integer = 0
    5.             Dim Counter As Long = 0
    6.             For i = 1 To 1000
    7.                 st.Start()
    8.                 result = 20 \ 4
    9.                 st.Stop()
    10.                 Counter += st.ElapsedTicks
    11.                 st.Reset()
    12.             Next
    13.             st.Reset()
    14.             Console.WriteLine("Integer division Average {0} Total {1}", (Counter / 1000).ToString, Counter.ToString)
    15.  
    16.  
    17.             Dim result2 As Integer = 0
    18.             Dim Counter2 As Long = 0
    19.             Dim reciprocal As Double
    20.             st.Start()
    21.             reciprocal = 4 ^ -1 'Can't forget to time this.
    22.             st.Stop()
    23.             For i = 1 To 1000
    24.                 st.Start()
    25.                 result2 = CInt(20 * reciprocal)
    26.                 st.Stop()
    27.                 Counter2 += st.ElapsedTicks
    28.                 st.Reset()
    29.             Next
    30.             st.Reset()
    31.             Console.WriteLine("Multiplication Average {0} Total {1}", (Counter2 / 1000).ToString, Counter2.ToString)
    32.             Console.ReadLine()
    33.         End While
    34.  
    35.     End Sub

    Results :
    Integer Division is almost always about 45 ticks faster than multiplication with a reciprocal
    Last edited by BlindSniper; May 27th, 2012 at 03:46 AM.

    Useful CodeBank Entries of mine
    Expand Function
    Code Compiler
    Sudoku Solver
    HotKeyHandler Class

    Read this to get Effective help on VBForums
    Hitchhiker's Guide to Getting Help at VBF

  9. #9
    Cumbrian Milk's Avatar
    Join Date
    Jan 2007
    Location
    0xDEADBEEF
    Posts
    2,448

    Re: Dividing by divisors.

    Be careful with drawing concrete conclusions from these sort of tests. Compilers even the JIT compiler utilise some cunning tricks to optimise your code and as such it can be difficult to tell exactly what you are testing. For example A Mod 256 might appear to be as fast as A And 255 where in truth Mod is slower but the compiler substituted the Mod for an And.

    Have you come across SIMD? There are a bunch of SIMD instructions in X86. AFAIK there is no SIMD support in Net but you might come across them if you dabble in C/C++. There is no division at all in SIMD, to achieve it you have to use other means.

    With integers if your numbers are relatively small you can approximate division with a multiplication followed by a left shift. For example if my divisor was 119 and my numbers never exceed 65535 I can approximate the division by multiplying by 17623 and then left shifting 21 spaces.
    W o t . S i g

  10. #10

    Thread Starter
    Fanatic Member BlindSniper's Avatar
    Join Date
    Jan 2011
    Location
    South Africa
    Posts
    865

    Re: Dividing by divisors.

    Well i'm actually programming in assembly, but i'm still very new so I don't know how to time my code.
    Can you explain how your division method works please ?
    Last edited by BlindSniper; May 27th, 2012 at 06:54 AM.

    Useful CodeBank Entries of mine
    Expand Function
    Code Compiler
    Sudoku Solver
    HotKeyHandler Class

    Read this to get Effective help on VBForums
    Hitchhiker's Guide to Getting Help at VBF

  11. #11
    Cumbrian Milk's Avatar
    Join Date
    Jan 2007
    Location
    0xDEADBEEF
    Posts
    2,448

    Re: Dividing by divisors.

    It is only an approximation.

    Say you have a bunch of numbers that you want divide.

    multiplier = (1 << shift) / divisor.

    for each number in bunchONumbers
    result = (number * multiplier) >> shift.

    the key is finding a highest shift you can use without overflow.
    W o t . S i g

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width