Programmazione parallela - C

ha ragione analizzator a seconda dell'algoritmo l'overhead fa perdere tutto il vantaggio.
ma con OpenMp l'overhead è minore rispetto a pthread ( con pthread in algoritmi con complessità logaritmica mi è capitato di avere un programma parallelizzato più lento )
grazie tanto delle ultime risp,
vado sulla openMP, ho dato un'occhiata al tutorial e c'è una slide in cui parallelizza un ciclo (in cui i singoli passi sono indipendenti) con un solo piccolo #pragma, semplice ed indolore.
A me ovviamente va tutto in seg fault, ora si tratta quindi di aprire quel maledetto libro della MIT Press.

Ll.


Usare pthread così come boost richiede la manipolazione di puntatori a fuzioni e puntatori a void per passare i parametri.
Anche per me è una cazzata abissale, il problema è che non sono proprio le cose più basilari del C che si studiano.
Il più delle volte usare bene la bash su linux può essere un ottimo sistema di parallelizzare l'esecuzione.


ma di che io sono un pro (ehm).
cmq,

si il codice è parallelizzabile semplicemente perchè l'esito di ogni simulazione è indipendente dalle altre. Io faccio una stessa cosa 500 volte dopodichè medio, fine. Poi.
Il codice è ottimizzato per quanto riesce a me fare :-) L'algoritmo è un monte carlo noto in letteratura, l'ha fatto Gillespie il che significa che è sacrosanto e intoccabile quasi quanto la teoria della gravità del bischero del thread sopra. Eventuali cappellate vanno ricercate quindi nella mia implementazione. Tra le possibili:

-> Ho scelto di gestire lo stato dell'intera simulazione tramite con un mega vettorone da 200 mega e passa, per evitare accesso a file o database. Ovviamente nel segmento stack non ci entra manco per il cazzo così lo alloco dinamicamente (pur sapendo a priori le dimensioni) in modo da spedirlo nell'heap. Essendo inoltre a 3 dimensioni indicizzo a mano l'offsett con una macro, del tipo:

#define A(j,t,k) k+NUM_SIM*(t+STEPS*j)

quello che mi chiedo è se ho gestito gli accessi in modo da ottimizzare la roba caricata in cache, c'è un modo per vederlo agile?

-> nonostante il vettorone si presti naturalmente ad un tipo "int" io ho scelto double, in modo da evitare casting che sarebbero inevitabili per come il montecarlo è strutturato. Tengo (spero) il roundoff sotto controllo.

-> uso ran1 del NR come generatore di numeri casuali. C'è di meglio? Con che periodo di ricorrenza?

-> Alla fine della sim plotto un megafile di testo e faccio il parsing con uno script python con cui lancio gnuplot per mostrare le mie belle figurine.

-> la trasformata di fourier è la FFTW

Se volete vi mando il codice via mail :-)

Ll.
allora, per come l'hai descritto è sicuramente parallelizzabile. assolutamente da evitare l'idea di usare la bash, perché sennò allochi 500 volte i 200MB di informazioni per il lookup di Monte Carlo.

a maggior ragione ritengo i thread una buona idea: tutti i processi leggeri attingono dagli stessi dati condivisi, allocati una volta sola.

CUDA potresti utilizzarlo, perché le schede video moderne gestiscono agilmente tali quantità di memoria e sfruttando decine di pipelines il guadagno è sicuramente superiore.

non sono convinto che sia una buona idea utilizzare double piuttosto che int, occupi il doppio della memoria e in genere vengono trattati con più difficoltà.

sulla casualità non ti saprei dire, non ho idea di cosa sia ran1 ma non credo sia lì il bottleneck.

tuttavia, non abbiamo visto veri e propri algoritmi in tutto questo. se hai preso del codice noto, probabilmente è già ottimizzato e non è lì il problema.
Per quanto riguarda i generatori di numeri casuali, ROOT sicuramente ne fornisce diversi, anche con periodi molto maggiori del ran1 delle Numerical Recipes. Non ho idea delle prestazioni in confronto al ran1.Trovi la descrizione degli algoritmi qua http://root.cern.ch/root/html/TRandom.html. L' unico problema è che non penso esistanto dei bindings per il C. Detto questo, per capire dove il tuo programma passa il maggior numero di tempo potresti provare a lanciare una simulazione con il profiling attivato.
Comunque immagino che l'algoritmo sia questo - http://en.wikipedia.org/wiki/Gillespie_algorithm - giusto?

Invece, relativamente a CUDA, (di cui sono men che meno esperto e quindi nel caso qualcuno mi corregga) sapevo che solo di recente è stato introdotto il supporto a doppia precisione e so che quando viene usato diminuisce di molto le prestazioni. Su internet trovi diverse pagine, per esempio https://www.cs.virginia.edu/~csadmin/wiki/index.php/CUDA_Support/Enabling_double-precision, http://www.ddj.com/cpp/210102115 e altre ancora. Avevo anche letto che è consigliato avere una seconda scheda dedicata ai calcoli in quanto se il sistema video richiedeva più memoria (e.g. cambio di risoluzione etc..) crashava l'applicazione. Inoltre molto dipende dalla tua scheda.

Per il resto sono interessato a capire (anche a titolo personale) cosa Aresius (che se non sbaglio è informatico puro) pensa di OpenMP.
Sul CUDA non ho tanta voglia di smattarci, apparte che il codice l'ho già scritto e va (il Gillespie non l'ho preso con codice noto, me lo sono scritto) ma poi quoto i motivi di Analizzator. Col valgrind ho dato un'occhiata al codice e non c'è che dire, trasformate di fourier e output vanno in un attimo, tutto il grosso sta (ovviamente) nelle 500 simulate col Gillespie. I double occupano + memoria ma vanno veramente + veloci degli interi, la prima versione era con i long int e ti assicuro non c'è storia.
Anche io sono in attesa del parere di Aresius sulle OpenMP.

La cosa che veramente mi interessa ora è cercare un generatore di numeri casuali che viaggia, root caca tutto in C++ e mi fa fatica interfacciarmici, pensavo di guardare qualcosa sulla GSL. Tra l'altro non so se avete visto ma le Numerical Recipies hanno una licenza che fa rabbrividire, mi garberebbe spostarmi in toto sulla GSL, qualcuno l'ha usata e sa come va?

Ll.
è pressoché certo che in doppia precisione la scheda video faccia fatica: sono ottimizzate per i floating point. negli shaders di solito non esistono nemmeno gli overload per manipolare dati in double.

riguardo OpenMP, non ci ho mai pastrugnato. :\

ho guardato gli esempi cmq, non sembra trascendentale. anzi, concettualmente è semplice: scrivi il codice e a botte di compilazione condizionale (pragma et similia) indichi le zone da parallelizzare.

c'è un altro utente del forum (il.nonno) che gira l'europa in virtù delle sue competenze di calcolo parallelo, ora gli segnalo il thread.
giusto qualche giorno fa, cmq, mi son scritto una mini-classe per rendere un thread indipendente qualsiasi funzione statica. come diceva giustamente Analizzator, devi avere una minima infarinatura di puntatori, soprattutto per gestire i parametri.

cmq è roba Windows, non POSIX. se ti interessa una traduzione di una roba del genere, te la programmo al volo.
Allora basta con sta storia che usare la bash = allocare 500 volte 200mb

1) imparare ad usare argc e argv, quel define in cima al codice fa paura
2) scrivi un programma che sia in grado di fare il conto dagli indici i e j.
E poi lanci con bash
$ ./free-fall-average-acceleration-metropolis 1 200&
$ ./free-fall-average-acceleration-metropolis 201 400&
$ ./free-fall-average-acceleration-metropolis 401 500&

aspetti, poi fai un bel cat e plotti tutto, xmgrace può essere un buon sostituto di python + gnuplot.
Matlab sarebbe ancora meglio ma se paga

Sennò potresti farti del bene ed imparare mpi o una threading library qualsiasi. MPI è sicuramente più complessa ma ti consente in linea di principio di scalare il codice su N macchine. MPI ha anche il supporto per l'accesso ai file concorrente di modo da scrivere le cose in ordine
Analizzator, ti sbagli di grosso.

i suoi define non sono i parametri, sono solo una macro per fare un lookup in O(1) nella memoria; inoltre, il metodo di montecarlo di obbliga ad avere montagne di informazioni, devi comunque allocarle anche per fare una sola ricerca.. non c'entra niente passare gli argomenti


Ah scusa, era solo un pregiudizio verso i fisici

Comq scrivere che l'unico modo di parallelizzare con bash è lanciare 500 volte l'eseguibile equivale a dire che per parallelizzare quel codice devi fare 500 thread una cazzata anche più grossa di quelle che si leggono nel thread qua sotto


ma io veramente l'avevo scritto chiaro e tondo, bastava leggere invece di infamarmi.

Ll.
infatti, non c'è motivo

cmq ho deliberato: per fare tutto tu usa OpenMP, piazza le sezioni condizionali nel codice e parallelizza easy
http://en.wikipedia.org/wiki/Hardware_random_number_generator
così stai sicuro.

La macro per indicizzare il vettore è per la pulizia del codice immagino più che per la velocità visto che la macro sostanzialmente sostituisce quello che hai scritto a destra al posto di quello che hai scritto a sinistra.
Ed in quel caso il vantaggio non c'è. Si usa alle volte di scrivere macro per min, max e cose del genere di modo da togliere l'overhead della chiamata a funzione, ma forse i moderni compilatori sono in grado di buttare il codice nel punto giusto, in c++ c'è inline che compila le funzioni/metodi ripetendo il codice. invece che col salto.


che figa
Riguardo ai generatori hardware, recentemente mi è capitato di vedere citato questo (non in ambito scientifico ma relativamente alla entropy pool per le connessione criptate) - http://www.entropykey.co.uk/ - che in teoria è in vendita per sole 36 sterline... devo ammettere che la curiosità di comprarlo ce l'ho
questo device sembra più studiato per fornire sequenze siano autocorrelate il meno possibile, forse però ha un basso throughput; non vedo indicato quanti byte al secondo riesce a sparare fuori, hce non è cosa da poco per i vostri integralacci

Quelli da calcolo se non erro forniscono anche quanti byte riescono a buttar fuori al secondo
Sarei curioso di sapere se qualcuno usa questa roba per fare i conti
il generatore hw è il mio sogno :-)

Ll.


Fuori i nomi dei modelli di quelli da calcolo che sono curioso
Comunque, un altro tipo di hardware che mi ha sempre incuriosito, sono le schede di accellerazione dedicate - qui un riassunto di alcune http://www.phys.uu.nl/~steen/web08/fpga-accel.html.