123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081 |
- (use-modules
- (ice-9 futures)
- (ice-9 threads)
- (ice-9 match)
- ;; SRFI 19 for time related procedures
- (srfi srfi-19))
- ;; Just defining a timing macro here to conveniently measure elapsed time of
- ;; evaluating expressions.
- (define-syntax time
- (syntax-rules ()
- [(time expr expr* ...)
- (begin
- (define start-time (current-time time-monotonic))
- expr
- expr* ...
- (define end-time (current-time time-monotonic))
- (let* ([diff (time-difference end-time start-time)]
- [elapsed-ns (+ (/ (time-nanosecond diff) 1e9)
- (time-second diff))])
- (display (format #t "~fs~%" elapsed-ns))))]))
- ;; Here is a prime number which needs some calculation time: 39916801
- (define prime?-inefficient
- (lambda (num)
- (let loop ([divisor 2])
- (cond
- [(< divisor num)
- (if (= (remainder num divisor) 0)
- #f
- (loop (+ divisor 1)))]
- [else
- #t]))))
- ;; Define a procedure, which checks 2 numbers in parallel.
- (define (any-prime? num1 num2)
- (let ((a-future (future (prime?-inefficient num1))))
- ;; If the first branch of or returns false, only then the other branch is
- ;; evalutated, as a shortcut behavior, so the future needs to be started
- ;; before entering the or expression.
- (or (prime?-inefficient num2)
- (touch a-future))))
- (time (any-prime? 39916801 39916801))
- (time (prime?-inefficient 39916801))
- ;; Or define a parallel map procedure as shown on:
- ;; https://www.gnu.org/software/guile/docs/master/guile.html/Futures.html#Futures
- (define (par-map proc lst)
- (match lst
- (()
- '())
- ((head tail ...)
- (let ((tail (future (par-map proc tail)))
- (head (proc head)))
- (cons head (touch tail))))))
- ;; Only every <num of cores> added list element will increase runtime:
- (time
- (par-map prime?-inefficient
- '(39916801
- 39916801
- 39916801
- 39916801)))
- ;; Or make use of letpar to calculate let bindings in parallel:
- (time
- (letpar ([res0 (prime?-inefficient 39916801)]
- [res1 (prime?-inefficient 39916801)]
- [res2 (prime?-inefficient 39916801)]
- [res3 (prime?-inefficient 39916801)])
- (and res0 res1 res2 res3)))
- ;; Futures are only suitable for side effect free function calls. See:
- ;; https://www.gnu.org/software/guile/docs/master/guile.html/Futures.html#Futures
|