Now that truly concurrent threading is working fairly well I decided to benchmark Gambit against Python for a simple threaded program (threaded Fibonacci with a thread granularity of roughly 50 microseconds creating 30,000 threads). I was happy to see that Gambit performs well. Here are the timings:
% time gsi -:p4 tfib.scm
real 0m0.355s user 0m1.234s sys 0m0.041s
% time python3 tfib.py
real 0m3.965s user 0m3.326s sys 0m1.535s
On 4 processors Gambit has a “user” time that is about 4 times the “real” time, and the system time is almost nil.
But wait a second… the Python system time is huge and the user and real times are roughly the same… after a little bit of research I just recalled the GIL (Global Interpreter Lock) that effectively serializes the execution of the interpreter so only one thread is active at any point in time (when in the interpreter). I can’t believe how such a crapily implemented language can be so popular…
Any suggestions for a popular and efficient threaded language to compare to?
Marc
Afficher les réponses par date
From
https://en.wikipedia.org/wiki/List_of_concurrent_and_parallel_programming_la..., Java, C# and Clojure could all be good candidates.
Nicolas
Le 2017-03-10 à 18:50, Marc Feeley a écrit :
Now that truly concurrent threading is working fairly well I decided to benchmark Gambit against Python for a simple threaded program (threaded Fibonacci with a thread granularity of roughly 50 microseconds creating 30,000 threads). I was happy to see that Gambit performs well. Here are the timings:
% time gsi -:p4 tfib.scm
real 0m0.355s user 0m1.234s sys 0m0.041s
% time python3 tfib.py
real 0m3.965s user 0m3.326s sys 0m1.535s
On 4 processors Gambit has a “user” time that is about 4 times the “real” time, and the system time is almost nil.
But wait a second… the Python system time is huge and the user and real times are roughly the same… after a little bit of research I just recalled the GIL (Global Interpreter Lock) that effectively serializes the execution of the interpreter so only one thread is active at any point in time (when in the interpreter). I can’t believe how such a crapily implemented language can be so popular…
Any suggestions for a popular and efficient threaded language to compare to?
Marc
Gambit-list mailing list Gambit-list@iro.umontreal.ca https://webmail.iro.umontreal.ca/mailman/listinfo/gambit-list
Perl6 would be a interesting candidate. it does not have the GIL.
- Jo
On Fri, Mar 10, 2017 at 7:07 PM, Nicolas Hurtubise < nicolas.k.hurtubise@gmail.com> wrote:
From https://en.wikipedia.org/wiki/List_of_concurrent_and_parallel_programming_ languages#Multi-threaded, Java, C# and Clojure could all be good candidates.
Nicolas
Le 2017-03-10 à 18:50, Marc Feeley a écrit :
Now that truly concurrent threading is working fairly well I decided to
benchmark Gambit against Python for a simple threaded program (threaded Fibonacci with a thread granularity of roughly 50 microseconds creating 30,000 threads). I was happy to see that Gambit performs well. Here are the timings:
% time gsi -:p4 tfib.scm
real 0m0.355s user 0m1.234s sys 0m0.041s
% time python3 tfib.py
real 0m3.965s user 0m3.326s sys 0m1.535s
On 4 processors Gambit has a “user” time that is about 4 times the
“real” time, and the system time is almost nil.
But wait a second… the Python system time is huge and the user and real
times are roughly the same… after a little bit of research I just recalled the GIL (Global Interpreter Lock) that effectively serializes the execution of the interpreter so only one thread is active at any point in time (when in the interpreter). I can’t believe how such a crapily implemented language can be so popular…
Any suggestions for a popular and efficient threaded language to compare
to?
Marc
Gambit-list mailing list Gambit-list@iro.umontreal.ca https://webmail.iro.umontreal.ca/mailman/listinfo/gambit-list
Gambit-list mailing list Gambit-list@iro.umontreal.ca https://webmail.iro.umontreal.ca/mailman/listinfo/gambit-list
Super!!! Perl 5 may be a good candidate as well. Regards, Kashyap
On Fri, Mar 10, 2017 at 4:28 PM, Bradley Lucier lucier@math.purdue.edu wrote:
Would a multi-threaded http server test what you want to test?
Brad _______________________________________________ Gambit-list mailing list Gambit-list@iro.umontreal.ca https://webmail.iro.umontreal.ca/mailman/listinfo/gambit-list
I considered Ruby… but then learned that MRI only implements green threads…
Thanks for the suggestions for other languages… Perl actually supports threads? Who would have thought!
Can I ask for your help in translating the benchmark program?
The actual computation performed by the “short-delay” procedure doesn’t matter, but it should take about 50 microseconds (in order to isolate the performance related to the implementation of threads).
Marc
;;; Compute fib using threads.
(declare (standard-bindings) (fixnum) (not safe) (block))
(define big 0)
(define (granularity-set! g) (set! big (expt 11 g)))
(define (short-delay) (integer-sqrt big))
(define (tfib n) (short-delay) (if (< n 2) 1 (let* ((x (thread-start! (make-thread (lambda () (tfib (- n 2)))))) (y (tfib (- n 1)))) (+ (thread-join! x) y))))
(define (range i j) (let loop ((j (- j 1)) (lst '())) (if (< j i) lst (loop (- j 1) (cons j lst)))))
(define (go n repeat) (let ((threads (map (lambda (i) (make-thread (lambda () (tfib n)))) (range 0 repeat)))) (for-each thread-start! threads) (map thread-join! threads)))
(granularity-set! 0)
(go 15 100)
(granularity-set! 1001) ;; granularity of about 50us per thread
(go 15 20)
On Mar 10, 2017, at 7:30 PM, C K Kashyap ckkashyap@gmail.com wrote:
Super!!! Perl 5 may be a good candidate as well. Regards, Kashyap
On Fri, Mar 10, 2017 at 4:28 PM, Bradley Lucier lucier@math.purdue.edu wrote: Would a multi-threaded http server test what you want to test?
Brad _______________________________________________ Gambit-list mailing list Gambit-list@iro.umontreal.ca https://webmail.iro.umontreal.ca/mailman/listinfo/gambit-list
Here's an Erlang version, with lots of grains of salt added: AFAIK Erlang doesn't provide bigint expt and sqrt, so they had to be added to the Erlang src. And Erlang isn't exactly known for numerical performance. With that in mind, here goes:
-module(fib). -export([main/1]). -mode(compile).
expt(_, 0) -> 1; expt(A, 1) -> A; expt(A, B) -> A * expt(A, B-1).
isqrt(Num, M, N) when abs(M - N) =< 1 -> if N * N =< Num -> N; true -> N - 1 end;
isqrt(Num, _, N) -> isqrt(Num, N, (N + Num div N) div 2).
integer_sqrt(Value) when Value >= 0 -> isqrt(Value, 1, (1 + Value) div 2).
short_delay(Value) -> integer_sqrt(Value).
range(I, J) -> lists:seq(I, J-1).
tfib(0, GV) -> short_delay(GV), 1; tfib(1, GV) -> short_delay(GV), 1; tfib(N, GV) -> short_delay(GV), Pid = self(), spawn(fun() -> Pid ! tfib(N-2, GV) end), Y = tfib(N-1, GV), receive Result -> Result + Y end.
goloop(0) -> ok; goloop(ThreadsRemaining) -> receive _ -> goloop(ThreadsRemaining - 1) end.
go(N, Repeat, Granularity) -> Pid = self(), GV = expt(11, Granularity), Threads = [spawn(fun() -> Pid ! tfib(N, GV) end) || _ <- range(0, Repeat)], goloop(length(Threads)).
main(_) -> go(15, 100, 0), go(15, 20, 1001).
$ time escript fib.erl
real 1m22.728s user 7m54.460s sys 0m0.396s
Ran on a six-core machine, Erlang used up all cores up to nearly 100%.
Leif
2017-03-11 1:45 GMT+01:00 Marc Feeley feeley@iro.umontreal.ca:
I considered Ruby… but then learned that MRI only implements green threads…
Thanks for the suggestions for other languages… Perl actually supports threads? Who would have thought!
Can I ask for your help in translating the benchmark program?
The actual computation performed by the “short-delay” procedure doesn’t matter, but it should take about 50 microseconds (in order to isolate the performance related to the implementation of threads).
Marc
;;; Compute fib using threads.
(declare (standard-bindings) (fixnum) (not safe) (block))
(define big 0)
(define (granularity-set! g) (set! big (expt 11 g)))
(define (short-delay) (integer-sqrt big))
(define (tfib n) (short-delay) (if (< n 2) 1 (let* ((x (thread-start! (make-thread (lambda () (tfib (- n 2)))))) (y (tfib (- n 1)))) (+ (thread-join! x) y))))
(define (range i j) (let loop ((j (- j 1)) (lst '())) (if (< j i) lst (loop (- j 1) (cons j lst)))))
(define (go n repeat) (let ((threads (map (lambda (i) (make-thread (lambda () (tfib n)))) (range 0 repeat)))) (for-each thread-start! threads) (map thread-join! threads)))
(granularity-set! 0)
(go 15 100)
(granularity-set! 1001) ;; granularity of about 50us per thread
(go 15 20)
On Mar 10, 2017, at 7:30 PM, C K Kashyap ckkashyap@gmail.com wrote:
Super!!! Perl 5 may be a good candidate as well. Regards, Kashyap
On Fri, Mar 10, 2017 at 4:28 PM, Bradley Lucier lucier@math.purdue.edu
wrote:
Would a multi-threaded http server test what you want to test?
Brad _______________________________________________ Gambit-list mailing list Gambit-list@iro.umontreal.ca https://webmail.iro.umontreal.ca/mailman/listinfo/gambit-list
Gambit-list mailing list Gambit-list@iro.umontreal.ca https://webmail.iro.umontreal.ca/mailman/listinfo/gambit-list
Thanks for the code. Gambit compares favourably to Erlang (19.2.3) both when using a 5 microsecond and 50 microsecond granularity. Here are the timings and source code files:
% gsc -exe tfib-5us.scm % time ./tfib-5us 1.69 real 10.17 user 0.14 sys % time escript tfib-5us.erl 2.13 real 11.80 user 1.51 sys % gsc -exe tfib-50us.scm % time ./tfib-50us 12.71 real 96.83 user 0.18 sys % time escript tfib-50us.erl 19.57 real 136.10 user 7.71 sys
I wonder why the system time is much higher for Erlang.
Marc
On Mar 11, 2017, at 5:08 AM, Leif Bruder leifbruder@gmail.com wrote:
Here's an Erlang version, with lots of grains of salt added: AFAIK Erlang doesn't provide bigint expt and sqrt, so they had to be added to the Erlang src. And Erlang isn't exactly known for numerical performance. With that in mind, here goes:
-module(fib). -export([main/1]). -mode(compile).
expt(_, 0) -> 1; expt(A, 1) -> A; expt(A, B) -> A * expt(A, B-1).
isqrt(Num, M, N) when abs(M - N) =< 1 -> if N * N =< Num -> N; true -> N - 1 end;
isqrt(Num, _, N) -> isqrt(Num, N, (N + Num div N) div 2).
integer_sqrt(Value) when Value >= 0 -> isqrt(Value, 1, (1 + Value) div 2).
short_delay(Value) -> integer_sqrt(Value).
range(I, J) -> lists:seq(I, J-1).
tfib(0, GV) -> short_delay(GV), 1; tfib(1, GV) -> short_delay(GV), 1; tfib(N, GV) -> short_delay(GV), Pid = self(), spawn(fun() -> Pid ! tfib(N-2, GV) end), Y = tfib(N-1, GV), receive Result -> Result + Y end.
goloop(0) -> ok; goloop(ThreadsRemaining) -> receive _ -> goloop(ThreadsRemaining - 1) end.
go(N, Repeat, Granularity) -> Pid = self(), GV = expt(11, Granularity), Threads = [spawn(fun() -> Pid ! tfib(N, GV) end) || _ <- range(0, Repeat)], goloop(length(Threads)).
main(_) -> go(15, 100, 0), go(15, 20, 1001).
$ time escript fib.erl
real 1m22.728s user 7m54.460s sys 0m0.396s
Ran on a six-core machine, Erlang used up all cores up to nearly 100%.
Leif
2017-03-11 1:45 GMT+01:00 Marc Feeley feeley@iro.umontreal.ca: I considered Ruby… but then learned that MRI only implements green threads…
Thanks for the suggestions for other languages… Perl actually supports threads? Who would have thought!
Can I ask for your help in translating the benchmark program?
The actual computation performed by the “short-delay” procedure doesn’t matter, but it should take about 50 microseconds (in order to isolate the performance related to the implementation of threads).
Marc
;;; Compute fib using threads.
(declare (standard-bindings) (fixnum) (not safe) (block))
(define big 0)
(define (granularity-set! g) (set! big (expt 11 g)))
(define (short-delay) (integer-sqrt big))
(define (tfib n) (short-delay) (if (< n 2) 1 (let* ((x (thread-start! (make-thread (lambda () (tfib (- n 2)))))) (y (tfib (- n 1)))) (+ (thread-join! x) y))))
(define (range i j) (let loop ((j (- j 1)) (lst '())) (if (< j i) lst (loop (- j 1) (cons j lst)))))
(define (go n repeat) (let ((threads (map (lambda (i) (make-thread (lambda () (tfib n)))) (range 0 repeat)))) (for-each thread-start! threads) (map thread-join! threads)))
(granularity-set! 0)
(go 15 100)
(granularity-set! 1001) ;; granularity of about 50us per thread
(go 15 20)
On Mar 10, 2017, at 7:30 PM, C K Kashyap ckkashyap@gmail.com wrote:
Super!!! Perl 5 may be a good candidate as well. Regards, Kashyap
On Fri, Mar 10, 2017 at 4:28 PM, Bradley Lucier lucier@math.purdue.edu wrote: Would a multi-threaded http server test what you want to test?
Brad _______________________________________________ Gambit-list mailing list Gambit-list@iro.umontreal.ca https://webmail.iro.umontreal.ca/mailman/listinfo/gambit-list
Gambit-list mailing list Gambit-list@iro.umontreal.ca https://webmail.iro.umontreal.ca/mailman/listinfo/gambit-list
Gambit-list mailing list Gambit-list@iro.umontreal.ca https://webmail.iro.umontreal.ca/mailman/listinfo/gambit-list
Not at this point of testing. But it will be an interesting test (if the HTTP requests can be automated to flood the server).
Marc
On Mar 10, 2017, at 7:28 PM, Bradley Lucier lucier@math.purdue.edu wrote:
Would a multi-threaded http server test what you want to test?
Brad
How about Go?
------------ package main
import "fmt"
func fib(n int) int { switch { case n < 2: return 1 case n < 20: return fib(n-1) + fib(n - 2) default: ch := make(chan int) go func() { ch<-fib(n-1) }() fn2 := fib(n-2) return fn2 + <- ch } }
func main() { fmt.Println(fib(45)) } ------------
On Mar 10, 2017, at 3:50 PM, Marc Feeley feeley@iro.umontreal.ca wrote:
Now that truly concurrent threading is working fairly well I decided to benchmark Gambit against Python for a simple threaded program (threaded Fibonacci with a thread granularity of roughly 50 microseconds creating 30,000 threads). I was happy to see that Gambit performs well. Here are the timings:
% time gsi -:p4 tfib.scm
real 0m0.355s user 0m1.234s sys 0m0.041s
% time python3 tfib.py
real 0m3.965s user 0m3.326s sys 0m1.535s
On 4 processors Gambit has a “user” time that is about 4 times the “real” time, and the system time is almost nil.
But wait a second… the Python system time is huge and the user and real times are roughly the same… after a little bit of research I just recalled the GIL (Global Interpreter Lock) that effectively serializes the execution of the interpreter so only one thread is active at any point in time (when in the interpreter). I can’t believe how such a crapily implemented language can be so popular…
Any suggestions for a popular and efficient threaded language to compare to?
Bakul, thanks for the suggestion! I did a quick test and Go does take advantage of multiple cores and performs similarly to Gambit on this benchmark. I will have to investigate further.
Are channels necessary in this program to simulate Gambit’s thread-join! ? I fear this could needlessly add overhead.
Marc
On Mar 10, 2017, at 7:47 PM, Bakul Shah bakul@bitblocks.com wrote:
How about Go?
package main
import "fmt"
func fib(n int) int { switch { case n < 2: return 1 case n < 20: return fib(n-1) + fib(n - 2) default: ch := make(chan int) go func() { ch<-fib(n-1) }() fn2 := fib(n-2) return fn2 + <- ch } }
func main() { fmt.Println(fib(45)) }
On Mar 10, 2017, at 3:50 PM, Marc Feeley feeley@iro.umontreal.ca wrote:
Now that truly concurrent threading is working fairly well I decided to benchmark Gambit against Python for a simple threaded program (threaded Fibonacci with a thread granularity of roughly 50 microseconds creating 30,000 threads). I was happy to see that Gambit performs well. Here are the timings:
% time gsi -:p4 tfib.scm
real 0m0.355s user 0m1.234s sys 0m0.041s
% time python3 tfib.py
real 0m3.965s user 0m3.326s sys 0m1.535s
On 4 processors Gambit has a “user” time that is about 4 times the “real” time, and the system time is almost nil.
But wait a second… the Python system time is huge and the user and real times are roughly the same… after a little bit of research I just recalled the GIL (Global Interpreter Lock) that effectively serializes the execution of the interpreter so only one thread is active at any point in time (when in the interpreter). I can’t believe how such a crapily implemented language can be so popular…
Any suggestions for a popular and efficient threaded language to compare to?
Goroutines are “free running”, which is often sufficient. If you want synchronization, you have to pay for it. Channels are the easiest to use for this and the recommended way. You can factor out channel creation time, by doing so upfront.
On Mar 10, 2017, at 5:23 PM, Marc Feeley feeley@iro.umontreal.ca wrote:
Bakul, thanks for the suggestion! I did a quick test and Go does take advantage of multiple cores and performs similarly to Gambit on this benchmark. I will have to investigate further.
Are channels necessary in this program to simulate Gambit’s thread-join! ? I fear this could needlessly add overhead.
Marc
On Mar 10, 2017, at 7:47 PM, Bakul Shah bakul@bitblocks.com wrote:
How about Go?
package main
import "fmt"
func fib(n int) int { switch { case n < 2: return 1 case n < 20: return fib(n-1) + fib(n - 2) default: ch := make(chan int) go func() { ch<-fib(n-1) }() fn2 := fib(n-2) return fn2 + <- ch } }
func main() { fmt.Println(fib(45)) }
On Mar 10, 2017, at 3:50 PM, Marc Feeley feeley@iro.umontreal.ca wrote:
Now that truly concurrent threading is working fairly well I decided to benchmark Gambit against Python for a simple threaded program (threaded Fibonacci with a thread granularity of roughly 50 microseconds creating 30,000 threads). I was happy to see that Gambit performs well. Here are the timings:
% time gsi -:p4 tfib.scm
real 0m0.355s user 0m1.234s sys 0m0.041s
% time python3 tfib.py
real 0m3.965s user 0m3.326s sys 0m1.535s
On 4 processors Gambit has a “user” time that is about 4 times the “real” time, and the system time is almost nil.
But wait a second… the Python system time is huge and the user and real times are roughly the same… after a little bit of research I just recalled the GIL (Global Interpreter Lock) that effectively serializes the execution of the interpreter so only one thread is active at any point in time (when in the interpreter). I can’t believe how such a crapily implemented language can be so popular…
Any suggestions for a popular and efficient threaded language to compare to?