Last active
December 25, 2015 13:59
-
-
Save Mouq/6987932 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Attempt at making the program correct, though it makes | |
# the program run 4.5 times slower (on my machine). | |
# In fact, I think it works because the threads | |
# spend so much time updating the hash | |
# that the chance of them both selecting the same | |
# indices AND executing the swap at the same time | |
# are made an order of magnitude more negligible. | |
use v6; | |
sub run (Int $vecs, Int $items, Int $threads, Int $iters) { | |
my @vec-refs = [(state$)++ xx $items] xx $vecs; | |
my %touched; | |
my sub swap { | |
my $a := @vec-refs[(^*).pick][(^*).pick]; | |
my $b := @vec-refs[(^*).pick][(^*).pick]; | |
repeat { #`( nothing ) } while $a|$b === any %touched.keys; | |
%touched{$a,$b} = True, True; | |
($a,$b)=($b,$a); | |
%touched{$a,$b}:delete; | |
} | |
my sub report { | |
say <( )>.join: (<[ ]>.join($_) for @vec-refs); | |
say "Distinct:", +@vec-refs.map(*.list).uniq; | |
} | |
report; | |
await Promise.allof($threads Rxx async { swap() for ^$iters }); | |
report; | |
} | |
run 100, 10, 10, 100000; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
; Original program, from the Clojure Wikipedia page | |
; https://en.wikipedia.org/wiki/Clojure#Examples | |
(defn run [nvecs nitems nthreads niters] | |
(let [vec-refs (vec (map (comp ref vec) | |
(partition nitems (range (* nvecs nitems))))) | |
swap #(let [v1 (rand-int nvecs) | |
v2 (rand-int nvecs) | |
i1 (rand-int nitems) | |
i2 (rand-int nitems)] | |
(dosync | |
(let [temp (nth @(vec-refs v1) i1)] | |
(alter (vec-refs v1) assoc i1 (nth @(vec-refs v2) i2)) | |
(alter (vec-refs v2) assoc i2 temp)))) | |
report #(do | |
(prn (map deref vec-refs)) | |
(println "Distinct:" | |
(count (distinct (apply concat (map deref vec-refs))))))] | |
(report) | |
(dorun (apply pcalls (repeat nthreads #(dotimes [_ niters] (swap))))) | |
(report))) | |
(run 100 10 10 100000) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Translation from Clojure | |
# Issues: There isn't (?) a native way to modify | |
# @vec-refs without any simultaneously editing | |
# one of the same positions on | |
# Clojure uses (alter ...) for this | |
# Jakudo often ends up with `Distinct: 999` | |
use v6; | |
sub run (Int $vecs, Int $items, Int $threads, Int $iters) { | |
my @vec-refs = [(state$)++ xx $items] xx $vecs; | |
my sub swap { | |
my $a := @vec-refs[(^*).pick][(^*).pick]; | |
my $b := @vec-refs[(^*).pick][(^*).pick]; | |
($a,$b)=($b,$a); | |
} | |
my sub report { | |
say <( )>.join: (<[ ]>.join($_) for @vec-refs); | |
say "Distinct:", +@vec-refs.map(*.list).uniq; | |
} | |
report; | |
await Promise.allof($threads Rxx async { swap() xx $iters }); | |
report; | |
} | |
run 100, 10, 10, 100000; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment