Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Why nim-1.6.20 only takes 2s but nim-2.0.14 66s when calculating fib(46) #24574

Open
forchid opened this issue Dec 27, 2024 · 9 comments
Open

Comments

@forchid
Copy link

forchid commented Dec 27, 2024

Description

Nim-2.0.14 takes too long time (about 66s) when calculating fib(46) than nim-1.6.20 (only 2s), and nim-2.0.8 also takes 33s.

The test case

import times

proc fib(n: int): int =
 if n <= 1:
   return n
 else:
   return fib(n - 1) + fib(n - 2)

let a = cpuTime()
let r = fib(46)
let b = cpuTime()
echo "fib(46) = " & $r & "(" & $(b - a) & "s)"

Nim Version

nim-1.6.20, nim-2.0.8, and nim-2.0.14

Current Output

>nim c -d:release fib.nim
Hint: used config file '..\nim-1.6.20\config\nim.cfg' [Conf]
...
Hint: gc: refc; opt: speed; options: -d:release
43862 lines; 0.813s; 60.84MiB peakmem; proj: ..\fib.nim; out: ..\fib.exe [SuccessX]
perf>fib
fib(46) = 1836311903(2.133s)

>%nim2014_home%\bin\nim c -d:release fib.nim
Hint: used config file '..\nim-2.0.14\config\nim.cfg' [Conf]
..................
Hint: mm: orc; threads: on; opt: speed; options: -d:release
46463 lines; 4.234s; 74.207MiB peakmem; proj: ..\fib.nim; out: ..\fib.exe [SuccessX]
>fib
fib(46) = 1836311903(66.274s)

>%nim20_home%\bin\nim c -d:release fib.nim
Hint: used config file '..\nim-2.0.8\config\nim.cfg' [Conf]
..................
Hint: mm: orc; threads: on; opt: speed; options: -d:release
46354 lines; 4.203s; 71.148MiB peakmem; proj: ..\fib.nim; out: ..\fib.exe [SuccessX]
>fib
fib(46) = 1836311903(33.569s)

Expected Output

nim-2.0.8 and nim-2.0.14 takes a few seconds.

Known Workarounds

No response

Additional Information

No response

@juancarlospaco
Copy link
Collaborator

Memory management changed?
refc to orc, and also --threads:on became default, try --gc:arc --threads:off ?

@forchid
Copy link
Author

forchid commented Dec 28, 2024

@juancarlospaco This is a table of testing gc and threads in nim-2.0.14:
--mm --threads time

arc on 67s
arc off 3s
refc on 2s
refc off 2s

The test details

>%nim2014_home%\bin\nim c -d:release --mm:arc --threads:on fib.nim
Hint: used config file '..\nim-2.0.14\config\nim.cfg' [Conf]
Hint: used config file '..\nim-2.0.14\config\config.nims' [Conf]
...
Hint: mm: arc; threads: on; opt: speed; options: -d:release
45886 lines; 3.344s; 74.223MiB peakmem; proj: ..\fib.nim; out: ..\fib.exe [SuccessX]

>fib
fib(46) = 1836311903(67.44399999999999s)

>%nim2014_home%\bin\nim c -d:release --mm:arc --threads:off fib.nim
Hint: used config file '..\nim-2.0.14\config\nim.cfg' [Conf]
Hint: used config file '..\nim-2.0.14\config\config.nims' [Conf]
...
Hint: mm: arc; opt: speed; options: -d:release
44592 lines; 4.655s; 74.301MiB peakmem; proj: ..\fib.nim; out: ..\fib.exe [SuccessX]

>fib
fib(46) = 1836311903(3.624s)

>%nim2014_home%\bin\nim c -d:release --mm:refc --threads:on fib.nim
Hint: used config file '..\nim-2.0.14\config\nim.cfg' [Conf]
Hint: used config file '..\nim-2.0.14\config\config.nims' [Conf]
...
Hint: mm: refc; threads: on; opt: speed; options: -d:release
47578 lines; 4.391s; 73.598MiB peakmem; proj: ..\fib.nim; out: ..\fib.exe [SuccessX]

>fib
fib(46) = 1836311903(2.135s)

>%nim2014_home%\bin\nim c -d:release --mm:refc --threads:off fib.nim
Hint: used config file '..\nim-2.0.14\config\nim.cfg' [Conf]
Hint: used config file '..\nim-2.0.14\config\config.nims' [Conf]
...
Hint: mm: refc; opt: speed; options: -d:release
46178 lines; 3.969s; 74.047MiB peakmem; proj: ..\fib.nim; out: ..\fib.exe [SuccessX]

>fib
fib(46) = 1836311903(2.106s)

This shows that its' too slow when using --mm:arc and --threads:on.

@rockcavera
Copy link
Contributor

With --threads:off there is an improvement, but the real problem is in --exceptions:goto. Just compile with --exceptions:setjmp and the time is the same between versions

@rockcavera
Copy link
Contributor

Of course, the analysis must go deeper and perform a disassembly of the executables to see if there is a difficulty for the C compiler to optimize (pre-calculate) the C code generated by Nim with --exceptions:goto.

@forchid
Copy link
Author

forchid commented Dec 28, 2024

With --threads:off there is an improvement, but the real problem is in --exceptions:goto. Just compile with --exceptions:setjmp and the time is the same between versions

Sure!

@Araq
Copy link
Member

Araq commented Dec 28, 2024

You don't have to change the exceptions mode globally, a single .quirky should also do the trick:

proc fib(n: int): int {.quirky.} =
 if n <= 1:
   return n
 else:
   return fib(n - 1) + fib(n - 2)

I doubt 1.6 supports this annotation though.

@forchid forchid closed this as completed Dec 28, 2024
@forchid
Copy link
Author

forchid commented Dec 28, 2024

You don't have to change the exceptions mode globally, a single .quirky should also do the trick

@Araq After adding the pragma .quirky, there has been a significant improvement, and the cost time 8s of this nim-2.0.14 program is same as java, rust, or c++, but is greater than the nim-1.6.20's.

@forchid forchid reopened this Dec 28, 2024
@Araq
Copy link
Member

Araq commented Dec 28, 2024

The nim-1.6 uses a cheat that nim-2.0 could reimplement but it pretty much improves the one meaningless fib benchmark and nothing else. You still get this cheat with 2.0 and mm:refc.

@juancarlospaco
Copy link
Collaborator

Maybe {.quirky.} can be documented?, is it supported on the stdlib? 🤔

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants