Newsgroup: it.comp.lang.c
Titolo: Vorrei condividere (in lettura) un array (in Linux)

Avrei bisogno di un suggerimento sulla strada da intraprendere.
Vi dico brevemente quello che vorrei fare (ovviamente in C) in
ambiente Linux.
Ho un programma (diciamo number crunching) che gira a lungo e fa uso
di un array piuttosto grande (volendo anche 2 o 3 Gb dei 6 che ho).
L'array viene creato e riempito una volta per tutte all'inizio,
poi per tutto il resto della durata del programma viene acceduto
solo in lettura.
Siccome potrei lanciare contemporaneamente
programmi uguali (ma anche diversi) che usano la stessa tabella (per
sfruttare
questi benedetti core) mi piacerebbe poterla allocare e riempire
una sola volta, magari anche proteggendola da swap e poi
poterla leggere da processi diversi.
Una specie di parallelismo dei poveri, nel senso
che non ho bisogno di reale comunicazione tra processi o thread,
quindi vorrei mantenere l'implementazione la piu' semplice possibile,
se questo e' coniugabile con la velocita'.
Scommetto che qualcosa di simile si puo' fare sotto Linux, magari
in piu' di un modo...
Avreste mica da suggerirmi verso quale libreria o set di funzioni
mi devo orientare? (O un link ad un tutorial in inglese o italiano,
se ci siete proprio inciampati ieri per caso...).
grazie,
g.

http://gcc.gnu.org/wiki/openmp
Ciao!

 
La soluzione è semplice: memoria condivisa.
Per evitare lo swap ti basta avere tanta memoria.
In caso dovessi avere problemi di prestazioni:
http://lwn.net/Articles/259710/
Ciao  Manlio

Grazie ad entrambi,
g.

 g.
A futura memoria,
volevo dire che ho visto che il mio problemino si risolve
in poche righe di codice, mediante l'uso delle funzioni
shmget(), shmat() e simili.
(poi bisogna un po' manipolare certi parametri della
memoria tipo shmmax per poter allocare grossi segmenti)
Un buon esempio dell'uso di queste funzioni si trova in
http://beej.us/guide/bgipc/
nella sezione del PDF chiamata "9. Shared Memory Segments".
ciao,
g.

 [...]
Ciao  Manlio

 
Nonché ovviamente (come già avevo suggerito) lasciar perdere i processi ed utilizzare i threads (quindi niente shared memory), che per questo tipo di problemi direi che è sicuramente la soluzione più performante e di facile implementazione.
Ciao!

 Ciao!
Vi ringrazio, ma, per il mio problema attuale, che non richiede
comunicazione
tra processi, semafori, o altre cose piu' complesse, ritengo che la
soluzione
con memoria condivisa sia performante e  semplicissima da
implementare.
Il mio problemino consiste nello scandire i numeri da 1 a 100 miliardi
(o piu')
e per ognuno, indipendentemente, fare dei conti, usando come ausilio
un array di
circa 680 Megabytes che mi permette di codificare tutti i numeri primi
fino
a 25 miliardi. Ho diversi problemetti simili, e tutti useranno la
stessa
tabella, quindi avevo interesse ad ottimizzare un po' la cosa.
Questo task si puo' dividere in modo banale, per esempio lanciando 4
processi,
completamente indipendenti,
ognuno dei quali testa solo un numero su 4, ma ovviamente in questo
modo consumo un sacco di memoria per una tabella che e' uguale
per i 4 processi.
Modificando in modo veramente minimale (in pratica aggiungendo solo
3 chiamate di funzione: una ftok, una shmget e una shmat) ho potuto
allocare una sola tabella indipendentemente da quanti processi la
usano,
lasciando tutto il resto del programma inalterato.
Per quanto riguarda la performance, ho visto che e' sostanzialmente
identica a quella
di lanciare piu' processi ognuno con la sua tabella, con il vantaggio
che posso usare tabelle piu' grandi o lanciare piu' processi in
parallelo
senza esaurire la memoria.
Ho provato con e senza hugepages ma le prestazione  erano
sostanzialmente
identiche.
ciao,
g.

On Wednesday, March 30, 2011 11:39:42 PM UTC+2, 
g.r...@iit.cnr.it
 wrote:

Se questo era il problema direi che ti conveniva direttamente scrivere la il tuo array su file e farlo aprire con un memory mapping: avresti avuto una gestione della memoria decisamente più "sensata" a livello di sistema (nonché tolto la necessità di ricreare l'array ogni volta che parte il primo programma :-) )
Ciao!

> Se questo era il problema direi che ti conveniva direttamente scrivere la il tuo array su file e farlo aprire con un memory mapping: avresti avuto una gestione della memoria decisamente più "sensata" a livello di sistema (nonché tolto la necessità di ricreare l'array ogni volta che parte il primo programma :-) )
Grazie.
All'inizio era una cosa che avevo accantonato perche' il calcolo della
tabella e' comunque veloce
(38 secondi per calcolare i numeri primi fino a 25 miliardi) mentre i
calcoli successivi durano giorni,
e perche' stavo facendo prove con array di diverse dimensioni.
Ora ho provato ad usare mmap ed effettivamente, a oltre  al fatto di
poter usare 1 sola
funzione invece di 3, ha le stesse prestazioni dell'altro approccio e
il vantaggio che non devo deallocare
manualmente la memoria utilizzata quando interrompo manualmente i
programmi
(cosa che accade quasi sempre).
ciao,
g.