utils.scm 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214
  1. (use-modules (srfi srfi-1)
  2. (ice-9 pretty-print)
  3. (ice-9 receive))
  4. (define (take-up-to n xs)
  5. (cond [(or (zero? n) (null? xs)) '()]
  6. [else (cons (car xs)
  7. (take-up-to (- n 1) (cdr xs)))]))
  8. (define (drop-up-to to-drop xs)
  9. (cond [(or (= to-drop 0) (null? xs)) xs]
  10. [else (drop-up-to (- to-drop 1) (cdr xs))]))
  11. (define (split-into-chunks-of-size-n xs n)
  12. (cond [(null? xs) '()]
  13. [else (let ([first-chunk (take-up-to n xs)]
  14. [rest (drop-up-to n xs)])
  15. (cons first-chunk (split-into-chunks-of-size-n rest n)))]))
  16. (define (split-into-n-chunks xs n)
  17. (let* ([number-of-elements (length xs)]
  18. [size-of-chunks (inexact->exact (ceiling (/ number-of-elements n)))])
  19. (split-into-chunks-of-size-n xs size-of-chunks)))
  20. ;; (define (chunkify xs n)
  21. ;; (define (distribute-remaining-elems partitions remaining)
  22. ;; (cond [(<= (length partitions) (length remaining))
  23. ;; (throw 'wrong-argument
  24. ;; #f
  25. ;; (string-append
  26. ;; "remaining should have less elements than the partitions,"
  27. ;; " but has more or an equal amount of elements")
  28. ;; #f
  29. ;; #f)]
  30. ;; [else
  31. ;; (cond [(null? remaining) partitions]
  32. ;; [else
  33. ;; (cons (cons (car remaining)
  34. ;; (car partitions))
  35. ;; (distribute-remaining-elems (cdr partitions)
  36. ;; (cdr remaining)))])]))
  37. ;; (let* ([len (length xs)]
  38. ;; [start-length]
  39. ;; [start-elems (take-up-to (remainder length n) xs)]
  40. ;; [rest-elems (drop-up-to (remainder length n) xs)])
  41. ;; (let ([split-rest-res (split-into-n-chunks rest-elems n)])
  42. ;; (display "split-rest-res: ")
  43. ;; (pretty-print split-rest-res)
  44. ;; (newline)
  45. ;; (distribute-remaining-elems split-rest-res start-elems))))
  46. (define (assert-test? a b test?)
  47. (unless (test? a b)
  48. (throw 'assertion-failure
  49. #f
  50. "assertion failure: ~S and ~S with ~A"
  51. a b test?
  52. #f)))
  53. (define (assert-equal? a b)
  54. (assert-test? a b equal?))
  55. ;; (assert-equal? (chunkify (iota 9) 4)
  56. ;; '((0 1 2) (3 4) (5 6) (7 8)))
  57. ;; (assert-equal? (chunkify (iota 11) 6)
  58. ;; '((0 1)
  59. ;; (2 3)
  60. ;; (4 5)
  61. ;; (6 7)
  62. ;; (8 9)
  63. ;; (10)))
  64. (define (busy-work limit)
  65. (if (> limit 0)
  66. (begin (sqrt (+ (expt limit limit) 1))
  67. (busy-work (- limit 1)))
  68. 'done))
  69. (n-par-map (current-processor-count)
  70. busy-work
  71. (list 20000 20000))
  72. (define (busy-work-2 lst)
  73. (cond [(null? lst) 'done]
  74. [else
  75. (expt (car lst) (car lst))
  76. (busy-work-2 (cdr lst))]))
  77. (define (time thunk)
  78. (define starting-time (current-time))
  79. (define res (thunk))
  80. (define ending-time (current-time))
  81. (display "elapsed time: ")
  82. (display (- ending-time starting-time))
  83. (display "s")
  84. (newline)
  85. res)
  86. (define (partition-4 numbers)
  87. (define (loop numbers rc0 rc1 rc2 rc3)
  88. (cond [(null? numbers) (list (reverse rc0)
  89. (reverse rc1)
  90. (reverse rc2)
  91. (reverse rc3))]
  92. [else
  93. (let* ([number (car numbers)]
  94. [residue (remainder number 4)])
  95. (cond [(= residue 0) (loop (cdr numbers)
  96. (cons number rc0)
  97. rc1
  98. rc2
  99. rc3)]
  100. [(= residue 1) (loop (cdr numbers)
  101. rc0
  102. (cons number rc1)
  103. rc2
  104. rc3)]
  105. [(= residue 2) (loop (cdr numbers)
  106. rc0
  107. rc1
  108. (cons number rc2)
  109. rc3)]
  110. [(= residue 3) (loop (cdr numbers)
  111. rc0
  112. rc1
  113. rc2
  114. (cons number rc3))]))]))
  115. (loop numbers '() '() '() '()))
  116. (n-par-map (current-processor-count)
  117. busy-work-2
  118. (split-into-n-chunks (iota 30000) 4))
  119. (time
  120. (lambda ()
  121. (n-par-map (current-processor-count)
  122. busy-work-2
  123. (split-into-n-chunks (iota 30000) 4))))
  124. (time
  125. (lambda ()
  126. (n-par-map (current-processor-count)
  127. busy-work-2
  128. (split-into-n-chunks (iota 30000) 2))))
  129. (time
  130. (lambda ()
  131. (n-par-map (current-processor-count)
  132. busy-work-2
  133. (receive (evens odds)
  134. (partition even? (iota 30000))
  135. (list evens odds)))))
  136. ;; test with 2 cores
  137. (let ([evens-and-odds (receive (evens odds)
  138. (partition even? (iota 30000))
  139. (list evens odds))])
  140. (time
  141. (lambda ()
  142. (par-map busy-work-2
  143. evens-and-odds))))
  144. ;; test with 4 cores
  145. ;; parallel
  146. (let ([residue-classes (partition-4 (iota 30000))])
  147. (time
  148. (lambda ()
  149. (parallel (busy-work-2 (car residue-classes))
  150. (busy-work-2 (cadr residue-classes))
  151. (busy-work-2 (caddr residue-classes))
  152. (busy-work-2 (cadddr residue-classes))))))
  153. (let ([residue-classes (partition-4 (iota 50000))])
  154. (time
  155. (lambda ()
  156. (parallel (busy-work-2 (car residue-classes))
  157. (busy-work-2 (cadr residue-classes))
  158. (busy-work-2 (caddr residue-classes))
  159. (busy-work-2 (cadddr residue-classes))))))
  160. ;; par-map
  161. (let ([residue-classes (partition-4 (iota 30000))])
  162. (time
  163. (lambda ()
  164. (par-map busy-work-2
  165. residue-classes))))
  166. ;; n-par-map - max cores
  167. (let ([residue-classes (partition-4 (iota 30000))])
  168. (time
  169. (lambda ()
  170. (n-par-map (current-processor-count)
  171. busy-work-2
  172. residue-classes))))
  173. ;; n-par-map - 2 cores
  174. (let ([residue-classes (partition-4 (iota 30000))])
  175. (time
  176. (lambda ()
  177. (n-par-map 2
  178. busy-work-2
  179. residue-classes))))
  180. ;; n-par-map - 1 core
  181. (let ([residue-classes (partition-4 (iota 30000))])
  182. (time
  183. (lambda ()
  184. (n-par-map 1
  185. busy-work-2
  186. residue-classes))))
  187. ;; test with single core to see speedup
  188. (time
  189. (lambda ()
  190. (par-map busy-work-2
  191. (list (iota 30000)))))