Domanda

qualcuno potrebbe aiutarmi cercando di capire come funziona la ricerca del disco rigido.

Ho un piccolo file di database binario che legge le prestazioni è assolutamente essenziale. Se devo saltare qualche byte nel file è più veloce usare seek () o read () quindi scartare i dati indesiderati.

Se il tempo medio di ricerca di un disco rigido è di 10 ms e la velocità di lettura è di 300 MB / s, ho calcolato che è più veloce da leggere () rispetto a seek () con un valore inferiore a 3 MB. È vero? C'è un sovraccarico quando si esegue una nuova ricerca, che non ha la lettura di uno stream esistente?

Quale pensi sia una struttura di file più adatta per un indice.

Entry1:Value:PointerIntoToData
Entry2:Value:PointerIntoToData
Entry3:Value:PointerIntoToData
Data, Data, Data

Or

Entry1:Value:Data
Entry2:Value:Data
Entry3:Value:Data

Quando si legge una voce se il valore non è corretto, verrà ignorato. Pertanto, durante lo streaming del file è più veloce: 1. quando non è richiesta una voce, utilizzare seek () per ignorarla 2. quando una voce non è necessaria, leggila e scarta i dati 3. o utilizzare la prima struttura, quando è richiesta una voce seek () in un repository di dati alla fine.

La voce è di 4 byte, il valore è di 8 byte e amp; i dati sono 12 KB

Saluti

È stato utile?

Soluzione

Tutte le chiamate di sistema seek stanno cambiando una posizione nel file dove sarà la prossima lettura. Non sposta la testa motrice. Le testine si muovono quando i dati vengono letti o scritti e non hai il controllo diretto su ciò che farà il sistema operativo successivo.

La lettura di molti dati che non ti serviranno ha un impatto perché tutti i dati letti richiedono spazio nei buffer del sistema operativo e causano l'eliminazione dei dati più vecchi. Quindi, usando la ricerca su file di grandi dimensioni, la cache del filesystem si guasterà meno.


Tutto ciò che scrivo sotto presuppone che non si possa adattare l'intero database in memoria. Se puoi, fallo. Leggi tutto e prova ad aggiungere dati nuovi e modificati alla fine del file. Non preoccuparti dello spazio sprecato, fai solo un po 'di compattazione di tanto in tanto.


Se il tuo database è troppo grande:

I dati vengono letti e scritti sull'unità fisica in blocchi (o pagine). Allo stesso modo l'unità base di IO del disco nel tuo sistema operativo è la pagina. Se il sistema operativo memorizza nella cache i dati dal disco, è anche in intere pagine. Quindi pensare se hai bisogno di andare avanti di pochi byte usando seek o read ha poco senso. Se vuoi renderlo veloce, devi tenere conto di come funziona davvero l'IO del disco.

Primo, già citato da nobugz, località di riferimento. Se i dati utilizzati in ciascuna operazione si trovano vicini in un file, il sistema operativo dovrà leggere o scrivere meno pagine. D'altra parte, se diffondi i tuoi dati, molte pagine dovranno essere lette o scritte contemporaneamente, il che sarà sempre lento.

Per quanto riguarda la struttura dei dati per l'indice. In genere sono organizzati come B-alberi . È una struttura di dati creata appositamente per la ricerca efficace di grandi quantità di dati archiviati in memoria con letture e scritture paginate.

Entrambe le strategie per l'organizzazione dei dati sono utilizzate nella pratica. Ad esempio, MS SQL Server per impostazione predefinita archivia i dati nel primo modo: i dati vengono archiviati separatamente e gli indici contengono solo dati da colonne indicizzate e indirizzi fisici delle righe di dati nei file. Ma se si definisce un indice cluster, tutti i dati verranno archiviati all'interno di questo indice. Tutti gli altri indici punteranno ai dati tramite chiave indice cluster anziché indirizzo fisico. Il primo modo è più semplice, ma l'altro può essere molto più efficace se si eseguono scansioni di intervalli di dati in base all'indice cluster.

Altri suggerimenti

Come " assolutamente essenziale " è l'accesso alla ricerca? Hai già testato la tua applicazione con una soluzione non ottimale? Durante quel test, hai fatto un benchmark per determinare dove si trovano i colli di bottiglia reali ? In caso contrario, rimarrai sorpreso dai risultati.

Successivamente, prova diversi metodi e confronta i tempi di esecuzione. Test con carichi di sistema diversi (ad es. Quando il sistema è inattivo ad eccezione dell'applicazione e quando è occupato).

Considera che le tue ottimizzazioni basate sul tuo attuale disco rigido potrebbero non essere corrette quando un nuovo disco rigido più veloce ha diverse ottimizzazioni interne che buttano il tuo lavoro fuori dalla finestra.

Una lettura sequenziale è sempre più veloce di una che richiede una ricerca della testa (non una ricerca della posizione). La tipica perf del disco rigido per la lettura sequenziale è di 50-60 MB / sec, cercando di ridurla al peggiore dei casi ~ 0,4 MB / sec. Una volta posizionate le testate, i dati nel cilindro sono essenzialmente gratuiti. La cache del file system ne sfrutta la pre-lettura dei settori da un cilindro.

Tuttavia, non hai alcun controllo sul posizionamento dei tuoi dati sui cilindri del disco. Né puoi indovinare la geometria dell'unità. Si noti che la velocità effettiva può peggiorare significativamente nel tempo quando il volume viene frammentato. Dovrai cercare perf memorizzando i dati nella memoria cache. A quel punto ti preoccupi della località di riferimento.

Puoi sempre mappare il file in memoria e quindi accedervi tramite puntatori e simili. Ciò dovrebbe in genere rendere gli accessi e più semplici.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top