2010-04-12 5 views
13

J'expérimente le filtrage d'éléments en parallèle. Pour chaque élément, j'ai besoin d'effectuer un calcul de distance pour voir s'il est assez proche d'un point cible. Peu importe que les structures de données existent déjà pour ce faire, je fais juste des expériences initiales pour l'instant. Quoi qu'il en soit, je voulais faire des expériences très basiques où je génère des vecteurs aléatoires et les filtre. Voici ma mise en œuvre qui fait tout cePourquoi Clojure se bloque après avoir effectué mes calculs?

(defn pfilter [pred coll] 
    (map second 
    (filter first 
     (pmap (fn [item] [(pred item) item]) coll)))) 

(defn random-n-vector [n] 
    (take n (repeatedly rand))) 

(defn distance [u v] 
    (Math/sqrt (reduce + (map #(Math/pow (- %1 %2) 2) u v)))) 

(defn -main [& args] 
    (let [[n-str vectors-str threshold-str] args 
     n (Integer/parseInt n-str) 
     vectors (Integer/parseInt vectors-str) 
     threshold (Double/parseDouble threshold-str) 
     random-vector (partial random-n-vector n) 
     u (random-vector)] 
    (time (println n vectors 
     (count 
     (pfilter 
      (fn [v] (< (distance u v) threshold)) 
      (take vectors (repeatedly random-vector)))))))) 

Le code exécute et retourne ce que je pense, c'est le paramètre n (longueur des vecteurs), des vecteurs (le nombre de vecteurs) et le nombre de vecteurs qui sont plus proches qu'un seuil au vecteur cible. Ce que je ne comprends pas, c'est pourquoi les programmes se bloque pendant une minute supplémentaire avant de se terminer.

Voici la sortie d'une course qui démontre l'erreur

 
$ time lein run 10 100000 1.0 
    [null] 10 100000 12283 
    [null] "Elapsed time: 3300.856 msecs" 

real 1m6.336s 
user 0m7.204s 
sys 0m1.495s 

Tous les commentaires sur la façon de filtrer en parallèle en général sont également les bienvenus, comme je l'ai pas encore confirmé que pfilter fonctionne réellement.

Répondre

20

Vous devez appeler shutdown-agents pour supprimer les threads sauvegardant le pool de threads utilisé par pmap. A propos de pfilter, il devrait fonctionner mais tourner plus lentement que filter, puisque votre prédicat est simple. La parallélisation n'est pas gratuite, vous devez donc donner à chaque thread des tâches moyennement intensives pour compenser le surcoût du multithreading. Mettez en lots vos éléments avant de les filtrer.

+0

Ah d'accord, merci. Je ne vais pas vraiment l'utiliser pour de simples requêtes de distance, mais c'était un exemple plus facile. Merci. – Thomas

Questions connexes