Skip to content

Instantly share code, notes, and snippets.

@DarinM223
Created December 13, 2019 13:28
Show Gist options
  • Save DarinM223/134c0fe1c7562b0fb7a4fb9669c4b2ce to your computer and use it in GitHub Desktop.
Save DarinM223/134c0fe1c7562b0fb7a4fb9669c4b2ce to your computer and use it in GitHub Desktop.
Concurrency+Parallelism examples (test 1 and 4 are good, 2 and 3 are bad)
#lang racket/base
(require racket/async-channel racket/future ffi/unsafe/os-thread)
(define (mandelbrot iterations x y n)
(let ([ci (- (/ (* 2.0 y) n) 1.0)]
[cr (- (/ (* 2.0 x) n) 1.5)])
(let loop ([i 0] [zr 0.0] [zi 0.0])
(if (> i iterations)
i
(let ([zrq (* zr zr)]
[ziq (* zi zi)])
(cond
[(> (+ zrq ziq) 4) i]
[else (loop (add1 i)
(+ (- zrq ziq) cr)
(+ (* 2 zr zi) ci))]))))))
; Should be fast
(let test1 ([v (make-vector 10)]
[finished-count 0]
[sema (make-os-semaphore)])
(os-semaphore-post sema)
(for ([i 10])
(call-in-os-thread
(λ ()
(define result (mandelbrot 10000000 62 500 1000))
(os-semaphore-wait sema)
(vector-set! v i result)
(set! finished-count (+ finished-count 1))
(os-semaphore-post sema))))
(time
(let loop ()
(if (= finished-count 10)
v
(loop)))))
; Should be slow
(let test2 ()
(time (for/vector ([i 10])
(mandelbrot 10000000 62 500 1000))))
; Should be slow
(let test3 ()
(define workers
(for/list ([i 10])
(thread
(λ ()
(mandelbrot 10000000 62 500 1000)))))
(time (for-each thread-wait workers)))
; Should be fast
(let test4 ()
(define (do-mandelbrots chan)
(define v (make-vector 10))
(define sema (make-fsemaphore 1))
(define futures
(for/list ([i 10])
(future
(λ ()
(define result (mandelbrot 10000000 62 500 1000))
(vector-set! v i result)))))
(thread
(λ ()
(for-each touch futures)
(async-channel-put chan v)))
(void))
(define chan (make-async-channel))
(do-mandelbrots chan)
(time (async-channel-get chan)))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment