2013-03-26 12 views

risposta

9

Se si intende su più core del processore, l'approccio più generale è quello di utilizzare Places.

Le posizioni consentono lo sviluppo di programmi paralleli che sfruttano macchine con più processori, core o thread hardware.

Una posizione è un'attività parallela che è effettivamente un'istanza separata della macchina virtuale Racket. I luoghi comunicano attraverso i canali luogo, che sono endpoint per una comunicazione buffer bidirezionale.

Si potrebbe essere in grado di utilizzare l'altra tecnica parallelizzazione, Futures, ma le condizioni per farlo funzionare sono relativamente limitate, per operazioni in virgola mobile esempio, come descritto here.


EDIT: In risposta al commento:

C'è un'implementazione di parallelo mappa utilizzando luoghi da qualche parte?

In primo luogo, dovrei eseguire il backup. Potresti non aver bisogno di Luoghi. È possibile ottenere simultanea utilizzando i thread Racket. Ad esempio, ecco una map/thread:

#lang racket 

(define (map/thread f xs) 
    ;; Make one channel for each element of xs. 
    (define cs (for/list ([x xs]) 
       (make-channel))) 
    ;; Make one thread for each elemnet of xs. 
    ;; Each thread calls (f x) and puts the result to its channel. 
    (for ([x xs] 
     [c cs]) 
    (thread (thunk (channel-put c (f x))))) 
    ;; Get the result from each channel. 
    ;; Note: This will block on each channel if not yet ready. 
    (for/list ([c cs]) 
    (channel-get c))) 

;; Use: 
(define xs '(1 2 3 4 5)) 
(map add1 xs) 
(map/thread add1 xs) 

Se il lavoro fatto comporta il blocco, per esempio Richieste di I/O, questo vi darà il "parallelismo" nel senso di non rimanere bloccati su I/O. Tuttavia i thread Racket sono thread "verdi", quindi solo uno alla volta utilizzerà la CPU.

Se hai veramente bisogno di un uso parallelo di più core CPU, allora ti occorrono Futures o Places.

A causa del modo in cui i Paesi vengono implementati --- efficacemente come più istanze di Racket --- Non vedo immediatamente come scrivere un generico map/place. Per esempi di utilizzo di posti in un modo "su misura", vedi:

+0

Grazie Greg. Ho provato un tentativo rapido di mappare la funzione fattoriale su un elenco di interi di grandi dimensioni usando i futures, ma il calcolo sembrava legato a un nucleo. Tuttavia, ovviamente stavo usando i bignum - non avevo capito che i futures sono limitati ai galleggianti. – Chris

+0

BTW Ero un po 'disinvolto nella mia descrizione. Non è tanto il "punto fluttuante". Sia il punto fisso che il floating potrebbero funzionare; la chiave è se sono 'fixnum' o' flonum' e non hanno bisogno di essere inscatolati/allocati. È un po 'complicato. Ecco perché ho suggerito Places come la cosa più generale da provare. Solo se stai facendo cose numeriche e sei disposto a rivedere attentamente il codice, probabilmente troverai utili i Futures (per quanto ne so io, qualcun altro che ne sa di più potrebbe saltare e correggermi). –

+0

Grazie per il chiarimento, Greg. – Chris

2

non so in Racket, ma ho implementato una versione in SISC Scheme.

(define (map-parallel fn lst) 
    (call-with-values (lambda() 
         (apply parallel 
          (map (lambda (e) 
            (delay (fn e))) 
            lst))) 
    list)) 

Solo parallel non è R5RS.

Esempio di utilizzo:

Utilizzando una normale map:

(time (map (lambda (a) 
     (begin 
      (sleep 1000) 
      (+ 1 a))) 
    '(1 2 3 4 5))) 
=> ((2 3 4 5 6) (5000 ms)) 

Utilizzo del map-parallel:

(time (map-parallel (lambda (a) 
     (begin 
      (sleep 1000) 
      (+ 1 a))) 
    '(1 2 3 4 5))) 
=> ((2 3 4 5 6) (1000 ms)) 
Problemi correlati