Autore Topic: Accessi paralleli o sequenziali al disco  (Letto 1689 volte)

serzio

  • Amministratore
  • Utente storico
  • *****
  • Post: 1706
Accessi paralleli o sequenziali al disco
« il: 15 Settembre, 2011, 12:36:05 »
 
Citazione
Se i 2 processi hanno queste tempistiche:
 
 1 lettura, 3 elaborazione, 1 scrittura
 2 lettura, 1 elaborazione, 2 scrittura
 
 Nel caso di elaborazione seriale i due processi impiegheranno 10 in caso di parallelo i due processi impiegheranno 7.
 Spero di essere stato esauriente. Potete trovare maggiori informazioni in questo articolo: http://en.wikipedia.org/wiki/Parallel_programming (è in inglese ma ha un corrispettivo italiano)



Premettendo che stiamo parlando di lettura/scrittura su disco e non su ram, se tu analizzi il caso del tuo esempio e metti le due sequenze sull'asse dei tempi, hai che il primo thread esegue una lettura contemporaneamente al secondo nel primo intervallo temporale, nel secondo hai elaborazione pura e nel terzo ha due scritture contmporanee.Il secondo intervallo viene correttamente eseguito in multithread. Il primo ed il terzo hanno le stesse caratteristiche ed ora le vediamo in dettaglio.
Il disco è organizzato in piatti (mediamente da due a quattro), tracce (cerchi concentrici) e  settori (area dell'intersezione tra la traccia ed uno spicchio di piatto, A, B, C e D nella figura), per trovare il settore su cui scrivere è necessario spostare il carrello delle testine sulla traccia ed aspettare che il settore corrispondente passi sotto la testina.

http://it.wikipedia.org/wiki/File:Disk-structure.svg
Ogni settore contiene 512 bytes ma siccome il carrello delle testine e un oggetto rigido e le testine sono montate staticamente sui braccetti, conviene eseguire le letture/scritture su gruppi di settori.
Tutte le tracce sono numerate così come i settori ed i piatti, allora prendiamo tutte le tracce zero, ovvero traccia zero del piatto zero lato superiore, traccia zero piatto zero lato inferiore, traccia zero piatto uno lato superiore, traccia zero piatto uno lato inferiore e così via ..... otteniamo il cilindro zero .... andiamo avanti con la traccia 1, la traccia 2 e così via ed otteniamo una suddivisione di tutto il disco in cilindri.
Con questa nuova rappresentazione la singola lettura coinvolge un intero gruppo di testine in un colpo solo e parliamo di qualcosa che si avvicina ad un cluster, ma non è un cluster, ma il concetto è simile, e interessa 1, 2 o 4kb di dati, a seconda della geometria del disco, piuttosto che 512bytes.
Quindi l'operazione di lettura/scrittura prevede il posizionamento del gruppo testine sul cilindro in cui si trovano i dati e poi bisogna aspettare che i piatti, girando, capitino sul settore di riferimento.
Se abbiamo due scritture simultanee o due letture simultanee che non interessano l'intero file ma solo una piccola porzione che dipende da tanti fattori tra cui la dimensione del buffer, il gruppo testine è sempre uno, e quindi le operazioni devono essere eseguite in sequenza e non in parallelo, ma c'e' un problema e cerco di spiegartelo con un'esempio.
Immaginiamo che il file interessato dal primo thread sia costituito da blocchi di dati che indico con lettere minuscole "abcdefg" ed il secondo con lettere maiuscole "ABCDE" (il secondo è più corto, ma è solo un esempio) ed i singoli blocchi di dati non sono vicini ma abbastanza sparpagliati sul disco (frammentazione esterna) come sempre.
Nel caso monothread abbiamo che i blocchi verranno interessati in questa sequenza, più o meno,  "abcdefgABCDE", mentre nel caso multithread "aAbBcCdDeEfg" e fin qui non c'e' nulla di discutere, è così e basta.
Allora dobbiamo considerare che se il disco e deframmentato la sequenza abcdefg è memorizzata con i blocchi uno vicino al successivo e così per la seconda sequenza e quindi la lettura della sequenza abcdefg, da sola, viene fatta di volata perchè i dati sono vicini e la stessa cosa per la seconda sequenza. Mentre non è affatto detto che le sequenze siano vicine ed è rarissimo che lo siano perchè gli algoritmi di gestione dei filesystem lavorano sempre in maniera ordinata.
Il tempo di spostamento del gruppo testine da una traccia all'altra è dell'ordine di 7-12 millisecondi .... se le tracce sono 2 i tempi sono 14-24 millisecondi e così via, quindi è evidente che se io riduco gli spostamenti traccia-traccia ottengo prestazioni migliori.
Se i file sono lontani e devo simultanemente cercare i settori del primo ed i settori del secondo, poi il secondo settore del primo ed secondo el secondo e così via .... ho il risultato che ste benedette testine saranno costrette a fare avanti e dietro continuamente sprecando tempo prezioso.
Esercizio per casa: prendi due file grandi, molto grandi per poter apprezzare le differenze in maniera molto eclatante e li copi da qualche altra parte prima in sequenza e misuri il tempo e poi contemporaneamente e misuri nuovamente il tempo. Confrontare il tempo necessario per eseguire le due operazioni e scrivere le proprie impressioni.
PS. Utilizzando dischi SCSI o SAS viene fatto, dal controller e dall'elettronica del disco (per questo sono molto più costosi), un riordinamento/ottimizzazione degli accessi al disco per migliorare o meglio ridurre al minimo il tempo perso per il traccia-traccia.
Ho scritto di getto e non ho troppa voglia di rileggere tutto il papiro, quindi perdonami gli errori ortografici e/o grammaticali (spero che almeno questi ultimi non ci siano). PS. L'articolo da te postato parla di accessi alla RAM e non al disco, quindi due casi moooolto diversi. C'e' la meccanica del disco a fare la differenza.
Leggi qui:
http://it.wikipedia.org/wiki/Disco_rigido
E tieni presente che l'NCQ, nella pratica,  pur migliorando notevolmente le prestazioni rispetto agli IDE, è ben lontana dall'equivalente di mamma SCSI.