View Full Version : [C] Letture concorrenti
Ciao,
che voi sappiate, se faccio due fread() contemporanee sullo stesso file, tali letture vengono sequenzializzate o vengono fatte in contemporanea?
Siccome la lettura non comporta criticità, suppongo di si, ma vorrei conferma.
Ciao,
che voi sappiate, se faccio due fread() contemporanee sullo stesso file, tali letture vengono sequenzializzate o vengono fatte in contemporanea?
Siccome la lettura non comporta criticità, suppongo di si, ma vorrei conferma.
La testina dell'hard disk e' una sola, e anche il cavo restituisce un flusso seriale.
Non possono che essere due letture sequenziali, prima una e poi l'altra.
forse non ho capito la domanda.
La testina dell'hard disk e' una sola, e anche il cavo restituisce un flusso seriale.
Non possono che essere due letture sequenziali, prima una e poi l'altra.
forse non ho capito la domanda.
No dunque, la lettura fisica è una sola per forza, ma una volta che il file è caricato in memoria intendo, come si comportano le letture?
DanieleC88
25-06-2008, 18:14
Non ne sono certo e non ho provato, ma siccome vengono aperti due diversi descrittori, credo che leggano a partire dalle proprie posizioni, indipendentemente dall'altro file aperto. Per rendere sequenziali le due letture credo debbano far riferimento allo stesso descrittore, o aggiornare la posizione nel file a seconda della necessità.
banryu79
26-06-2008, 09:03
Quoto DanieleC88,
se le due letture sono il prodotto dell'azione di due distinti file descriptor che puntano allo stesso file, sono indipendenti tra loro.
In passato mi è capitato di dover parserizzare un file di codice ISO per macchine CN per editare alcuni punti del file a certe condizioni (dovevo cambiare il tipo e la sequenza di alcune operazioni) e ricordo di aver usato appunto due descrittori allo stesso file in lettura che mi fornivano le informazioni che usavo per scrivere il nuovo file con un altro descrittore (altro file, in scrittura).
Quoto DanieleC88,
se le due letture sono il prodotto dell'azione di due distinti file descriptor che puntano allo stesso file, sono indipendenti tra loro.
In passato mi è capitato di dover parserizzare un file di codice ISO per macchine CN per editare alcuni punti del file a certe condizioni (dovevo cambiare il tipo e la sequenza di alcune operazioni) e ricordo di aver usato appunto due descrittori allo stesso file in lettura che mi fornivano le informazioni che usavo per scrivere il nuovo file con un altro descrittore (altro file, in scrittura).
Però ad esempio, siccome devo leggere un file molto grande, non so se leggerlo una volta sola o fare letture in contemporanea. Quanti sono i canali massimi di input da file? C'è modo di saperlo? Intendo dire che sicuramente vi è un numero massimo di letture concorrenti dopo il quale le prestazioni decadono. Sicuramente dipende dal file system che c'è sotto.
Il flusso di esecuzione sotto Windows funziona grossomodo cosi'.
Il processo A fa richiesta in lettura al sistema operativo di una porzione (o tutto) del file Pippo, mediante una system call.
Il processo A viene messo in attesa, e la system call provvede a cercare il file in System Cache. Se lo trova prepara e comanda il coprocessore DMA per il trasferimento memoria-memoria per riempire il buffer utente.
Nell'attesa e' molto probabile che ci sia un context switch, e il processore passi a fare altro, perche' il DMA potrebbe dover trasferire parecchi KByte, e intanto il sistema passa a fare altro. (Se la lettura richiesta e' piccola, cosa che accade spesso, allora si procede immediatamente con un normale trasferimento comandato dal processore, perche' l'overhead del DMA e' tale per cui conviene solo da una certa dimensione in poi).
Una volta che il DMA ha finito e il buffer utente e' riempito, il processo A viene liberato, pronto a ritornare in esecuzione quando capitera' di nuovo il suo context switch.
Altrimenti, se la porzione di file richiesta non si trova in system cache, il flusso della system call di lettura passa alla lettura fisica. il sistema operativo accoda la richiesta di lettura della porzione del file pippo richiesto, durante la quale verra' comandato l'hard disk e preparato un altro tipo di DMA per il trasferimento controller->System cache: La porzione del file A richiesta viene letta, mediante DMA (o di nuovo a mano dal processore, se il controller e' configurato in PIO mode), dalla periferica alla system cache (fra l'altro, i controller HD oggi sono in memory mapping oppure si fa sempre un DMA da porta a memoria?). Context switch, perche' tanto la lettura e' lentissima.
Una volta che questo trasferimento DMA e' terminato, allora la system call di lettura prosegue, con il trasferire la porzione del file dalla system cache alla memoria utente. Eventuale Context Switch nel frattempo che si trasferisce memoria->memoria se si e' nel caso DMA, esattamente come nel caso fortunato.
Un processo B che arrivasse a chiedere quelle porzioni dello stesso file, le troverebbe gia' in system cache, e ci sarebbe solo il trasferimento memoria-memoria (diretto da processore o di nuovo DMA se grosso).
Quindi in entrambi i casi il file viene letto da disco fisicamente al piu' una volta.
Anche qualora il file venisse cambiato tra la lettura di A e quella di B (magari da un processo C), non si passerebbe alla lettura fisica, in quanto anche la scrittura di C agisce sulla system cache.
La system cache sotto XP e' in write back, ovvero e' il sistema operativo che decide quando ha voglia di andare a scrivere permanentemente le modifiche su disco (tipicamente quando non ha null'altro da fare), che non avvengono quasi mai nel momento in cui C l'ha richiesto.
Ecco uno dei motivi per cui non e' bene spegnere violentemente un computer.
Alcuni file potrebbero non essere aggiornati in scrittura. O essere a meta'...
DanieleC88
27-06-2008, 03:05
:eekk:
Complimenti per la spiegazione!
DanieleC88
27-06-2008, 03:06
[EDIT]
Ho cercato molto velocemente dettagli sul trasferimento systemcache -> memoria, ma non ho trovato granche'.
Dai chipest del (almeno) 386 il DMA puo' effettuare trasferimenti memoria -> memoria, mentre prima era possibile solo periferica -> memoria (e viceversa).
Non sono pero' riuscito a trovare da nessuna parte se Windows usa questa feature durante il trasferimento dalla system cache alla memoria utente, mentre mi sembra di avere capito che viene molto probabilmente usato sotto Linux, almeno per questo motivo.
Qualcuno ha dei dettagli in piu'? Giusto per chiudere il cerchio...
banryu79
27-06-2008, 08:32
Però ad esempio, siccome devo leggere un file molto grande, non so se leggerlo una volta sola o fare letture in contemporanea. Quanti sono i canali massimi di input da file? C'è modo di saperlo? Intendo dire che sicuramente vi è un numero massimo di letture concorrenti dopo il quale le prestazioni decadono. Sicuramente dipende dal file system che c'è sotto.
La precisa spiegazione di gugoXX evidenzia il fatto che di lettura fisica ce ne sarebbe solo una, quindi, a meno di dimensioni colossali del file (quanto è grande?) non dovrebbero esserci troppi problemi.
Una volta che il file viene letto e trasferito nella cache system, procedere con un'unica lettura sequenziale piuttosto che con due o più file descriptor che fanno le loro fseek-ftell-fread non dovrebbe comportare decadimenti prestazionali sensibili (dovuti alla dimensione del file intendo).
Questa almeno è la sensazione che ho io, però potresti facilmente fare una prova con un caso limite e una decina di file descriptor che accedono in lettura ripetendo X operazioni di fread/fseek in un ciclo.
Ecco uno dei motivi per cui non e' bene spegnere violentemente un computer.
Alcuni file potrebbero non essere aggiornati in scrittura. O essere a meta'...
Spiegazione ineccepibile, ma purtroppo lavoro sotto sistemi Linux :D :D :D :D
La precisa spiegazione di gugoXX evidenzia il fatto che di lettura fisica ce ne sarebbe solo una, quindi, a meno di dimensioni colossali del file (quanto è grande?) non dovrebbero esserci troppi problemi.
Il file di ingresso è enorme, si parla di 16 GB. Credo che non sia neanche possibile leggerlotutto di un botto. fare una malloc di 16 GB penso sia improponibile :D
Una volta che il file viene letto e trasferito nella cache system, procedere con un'unica lettura sequenziale piuttosto che con due o più file descriptor che fanno le loro fseek-ftell-fread non dovrebbe comportare decadimenti prestazionali sensibili (dovuti alla dimensione del file intendo).
Il problema è che questo è un programma parallelo in MPI, quindi le letture contemporanee sono fatte da più processori. Quindi o faccio leggere ad ognuno la sua parte, o incarico un solo processore di sobbarcarsi la lettura e poi distribuire agli altri le proprie parti di competenza.
Io volevo usare un pool di processi lettori, il cui numero varia in base alle caratteristiche del file system sottostante, magari analizzando i canali di input su file che mette a disposizione. Ma non so se è possibile farlo.
Mi raccomando, una sola riga per volta eh...
E poi qui non sembrava che il file fosse immenso.
No dunque, la lettura fisica è una sola per forza, ma una volta che il file è caricato in memoria intendo, come si comportano le letture?
Comunque quando leggi un pezzo di file, anche sotto Linux, va a finire nella cache. Ulteriori letture dello stesso pezzo verranno fatte in RAM.
Ogni volta che un processo lettore qualsiasi chiede un pezzo che non e' in cache, necessariamente andra' a pescarlo da disco. Nel frattempo il processore andra' a fare altro.
Piu' letture contemporanee fisiche dello stesso file fatte da processi diversi, ad offset del file diverso, faranno saltare la testina avanti e indietro, con la conseguenza che le prestazioni saranno inferiori di una normale lettura e processamento sequenziale fatti da un processo solo (a meno che a processare ogni singolo pezzo ci si impieghi un tempo superiore al tempo di lettura).
Secondo me una soluzione con thread principale che legge, ed ogni volta che ha letto un workitem fa partire un thread che lo processa, e' la soluzione migliore.
Ma cosa devi fare?
banryu79
28-06-2008, 09:43
Il file di ingresso è enorme, si parla di 16 GB
Ah! :eek:
Il problema è che questo è un programma parallelo in MPI, quindi le letture contemporanee sono fatte da più processori. Quindi o faccio leggere ad ognuno la sua parte, o incarico un solo processore di sobbarcarsi la lettura e poi distribuire agli altri le proprie parti di competenza.
Voto per un'unica lettura sequenziale di una porzione del file da parte di un processore che poi incarica altri processori dell'elaborazione della sua parte.
Chissà in quante "porzioni" devi spezzettare la lettura per un file di queste dimensioni...
Io volevo usare un pool di processi lettori, il cui numero varia in base alle caratteristiche del file system sottostante, magari analizzando i canali di input su file che mette a disposizione. Ma non so se è possibile farlo.
Non ho idea di cosa tu stia parlando, spiacente :stordita:
Mi raccomando, una sola riga per volta eh...
Non c'è problema, il file è binario .. :D
Ma cosa devi fare?
Devo parallelizzare un codice che calcola le pendenze dei terreni. la parallelizzazione per adesso è solo sull' I/O. Usare un solo processo che legge credoche alla fine sia la soluzione migliore, ma ovviamente dovrà leggerlo un pò per volta, perché 16 GB tutto di un colpo mi scoppia :D Ad esempio, se ho 4 Gb di RAM a disposizione, leggo il file a colpi di 4 GB, anzi un pò meno in quanto ovviamente non gira solo il mio processo sul processore, dunque la RAM disponibile sarà minore. E poi distribuisco via via i pezzi agli altri.
Che ne pensate? Ma sopratutto, è possibile fare una malloc da 4GB ?
Il discorso che hai esposto tu sulal cache purtroppo non vale, in quanto ho un sistema a memoria distribuita, dunque i processi, o meglio, i processori, vedono solo la cache locale. Scusate se non l'ho specificato prima.
Chissà in quante "porzioni" devi spezzettare la lettura per un file di queste dimensioni...
In realtà il numero di pezzi è pari al numero di processori.
Non ho idea di cosa tu stia parlando, spiacente :stordita:
Questa cosa l'ho capito poco anche io. Mi hanno parlato di ipotetici canali di input su file, che via via possono esaurirsi. Probabilmente si riferiscono al fatto che vi è un sistema GPFS sotto, un file system parallelo. Solo che questo codice deve essere portabile, dunque devo prevedere casi anche con file system meno performanti. :)
vBulletin® v3.6.4, Copyright ©2000-2025, Jelsoft Enterprises Ltd.