Integer arithmetic performance 32 vs 64-bit

I have 2 machines with F # 2.0 Interactive build 4.0.30319.1 on vs 2010. Some of my programs ran much slower on a faster machine. The problem is that integer arithmetic performance on 32-bit Windows is significantly slower than 64 Windows.

On a slightly slower 64-bit Windows 7 machine (program listed below):

primeCount = 1270607
Real: 00: 00: 07.553, CPU: 00: 00: 07.519, GC gen0: 0, gen1: 0, gen2: 0

On a slightly faster Windows XP SP2 machine:

primeCount = 1270607
Real: 00: 00: 32.800, CPU: 00: 00: 32.796, GC gen0: 0, gen1: 0, gen2: 0

Thus, the 32-bit version takes up more than 4 times to the 64-bit version. I assume that there is no significant difference due to different operating systems, except for the word length that is supported.

Program:

let isPrime(n) = if n < 2 then false elif (n % 2) = 0 then // take care of even case if n = 2 then true else false else // n is odd let ms = int(sqrt(float(n))) let rec isPrimeUtil(m) = if m > ms then true elif n % m = 0 then false else isPrimeUtil(m + 2) isPrimeUtil(3) let nums = [1 .. 20000000] let pcountref = ref 0 // # of primes found let primeCount = pcountref := 0 for x in nums do if (isPrime x) then incr pcountref do primeCount printfn "primeCount = %d" !pcountref 

Send the program interactive. #time;; Then, to measure the elapsed time for processing, rather than generate a range of nums, select the line

 let pcountref = ref 0 

and all subsequent lines and send to interactive.

+4
source share
3 answers

I think the more likely explanation is that the 64-bit JIT performs tail call optimization, which is not in the 32-bit JIT. isPrimeUtil function can be optimized

Please note that this example does not use BigInteger in any case, there is also the opportunity for algorithmic improvements - the sieve will work much faster

+3
source

float is 64 bits, so calling sqrt(float(n)) is probably your performance receiver. (And would explain why a 64-bit machine can do this much better.)

Try float32 if you don't need / accuracy.

See: http://msdn.microsoft.com/en-us/library/dd233210.aspx

I don't have a 32-bit machine for testing, but on my 64-bit machine, just checking sqrt code takes a reasonable piece of time.

 let nums = [1 .. 20000000] let ans = List.map (fun n -> int(sqrt(float(n))) nums 

Gives real time 5.120s - this is a significant piece of your runtime.

+1
source

These results make sense. BigNum implementations often use an integer of a machine until they detect an overflow, and then switch to a more complex representation. 64-bit integers can contain much larger values ​​than 32-bit integers. Your test program probably does a lot more tests that perform fast arithmetic on a machine when it runs on a 64-bit version.

0
source

Source: https://habr.com/ru/post/1393857/


All Articles