Dovrei usare Python o Assembly per un programma di copia super veloce




(9)

Come già detto, non è la lingua qui a fare la differenza; l'assemblaggio potrebbe essere freddo o veloce per i calcoli, ma quando il processore deve "parlare" con le periferiche, il limite è dato da questi. In questo caso la velocità è data dalla velocità del tuo hard disk, e questo è un limite che difficilmente puoi cambiare senza cambiare il tuo hd e aspettando un hd migliore in futuro, ma anche dal modo in cui i dati sono organizzati sul disco, cioè dal filesystem . AFAIK, i filesystem più usati non sono ottimizzati per gestire velocemente tonnellate di file "piccoli", ma sono ottimizzati per contenere "pochi" file enormi.

Quindi, cambiare il filesystem che stai usando potrebbe aumentare la tua velocità di copia, nella misura in cui è più adatto al tuo caso (e naturalmente i limiti di hd sono ancora validi!). Se vuoi "assaggiare" il vero limite del tuo hd, dovresti provare una copia "settore per settore", rispondendo all'immagine esatta del tuo hd sorgente sul dest hd. (Ma questa opzione ha alcuni punti di cui essere a conoscenza)

Come problema di manutenzione, ho bisogno di eseguire regolarmente (3-5 volte all'anno) un repository che ora ha oltre 20 milioni di file e supera 1,5 terabyte nello spazio totale su disco. Attualmente sto usando RICHCOPY, ma ne ho provati altri. RICHCOPY sembra il più veloce ma non credo di avvicinarmi ai limiti delle capacità della mia macchina XP.

Sto giocando con ciò che ho letto in The Art of Assembly Language per scrivere un programma per copiare i miei file. Il mio altro pensiero è di iniziare a imparare come multi-thread in Python per fare le copie.

Sto giocando con l'idea di fare questo in Assembly perché sembra interessante, ma mentre il mio tempo non è incredibilmente prezioso è abbastanza prezioso che sto cercando di capire se vedrò o no dei guadagni abbastanza significativi in ​​velocità di copia . Presumo che lo farei, ma ho solo iniziato a imparare davvero a programmare 18 mesi ed è ancora più o meno un hobby. Quindi potrei mancare qualche concetto fondamentale di ciò che accade con i linguaggi interpretati.

Eventuali osservazioni o esperienze sarebbero apprezzate. Nota, non sto cercando alcun codice. Ho già scritto un programma di copia di base in Python 2.6 che non è più lento di RICHCOPY. Sto cercando alcune osservazioni su cui mi darà più velocità. In questo momento mi ci vogliono più di 50 ore per fare una copia da un disco a un Drobo e poi di nuovo da Drobo a un disco. Ho un LogicCube per quando sto semplicemente duplicando un disco ma a volte ho bisogno di passare da un disco a Drobo o viceversa. Sto pensando che dato che posso copiare un disco 3/4 full 2 ​​terabyte usando il LogicCube in meno di sette ore dovrei essere in grado di avvicinarmi a quello usando Assembly, ma non so abbastanza per sapere se questo è valido . (Sì, a volte l'ignoranza è beatitudine)

Il motivo per cui ho bisogno di accelerarlo è che ho avuto due o tre cicli in cui qualcosa è successo durante la copia (cinquanta ore sono lunghe per aspettare che il mondo si fermi) che mi ha costretto a buttare giù la copia e ricominciare . Ad esempio, la scorsa settimana il conduttore dell'acqua si è rotto sotto il nostro edificio e ha interrotto la corrente.

Grazie per le prime risposte ma non penso che si tratti di limitazioni I / O. Non sto andando su una rete, l'unità è collegata alla scheda madre con una connessione SATA e il mio Drobo è collegato a una porta Firewire, il mio pensiero è che entrambe le connessioni dovrebbero consentire un trasferimento più veloce.

In realtà non posso usare una copia di settore eccetto passare da un singolo disco a Drobo. Non funzionerà dall'altra parte poiché la struttura dei file Drobo è un mistero. La mia osservazione non scientifica è che la copia da un disco interno a un altro non è più veloce di una copia da o verso Drobo su un disco interno.

Sono legato all'hardware, non posso permettermi i dischi da 10K rpm da 2 terabyte (se li fanno anche loro).

Alcuni di voi suggeriscono una soluzione di sincronizzazione dei file. Ma questo non risolve il mio problema. Prima di tutto, le soluzioni di sincronizzazione dei file con cui ho giocato costruiscono una mappa (per mancanza di un termine migliore) dei dati prima, ho troppi piccoli file in modo che soffochino. Uno dei motivi per cui utilizzo RICHCOPY è che inizia a copiare immediatamente, non utilizza la memoria per costruire una mappa. Secondo, ho avuto uno dei miei tre backup Drobo fallire un paio di settimane fa. La mia regola è che se ho un errore di backup gli altri due devono rimanere fuori linea fino a quando il nuovo non viene costruito. Quindi ho bisogno di copiare da una delle tre copie di backup su disco singolo che ho che uso con LogicCube.

Alla fine della giornata devo avere una buona copia su una singola unità perché è quello che consegna ai miei clienti. Perché i miei clienti hanno sistemi diversi che consegna a loro su dischi SATA.

Affido lo spazio cloud a qualcuno in cui i miei dati vengono anche archiviati come il backup più profondo, ma è costoso estrarlo se non di lì.


1,5 TB in circa 50 ore danno un throughput di (1,5 * 1024 ^ 2) MB / (50 * 60 ^ 2) s = 8,7 MB / s. Una larghezza di banda teorica di 100 mbit / s dovrebbe darvi 12,5 MB / s. Mi sembra che la tua connessione firewire sia un problema. Si dovrebbe guardare l'aggiornamento dei driver o l'aggiornamento a una migliore interfaccia firewire / esata / usb.

Detto questo, anziché la domanda python / assembly, dovresti cercare di acquisire una soluzione di sincronizzazione dei file. Non dovrebbe essere necessario copiare questi dati più e più volte.


Ci sono 2 posti per il rallentamento:

  • La copia per file è MOLTO più lenta di una copia su disco (dove si clona letteralmente il 100% dei dati di ogni settore). Soprattutto per i file da 20 mm. Non è possibile correggere quello con l'assieme più sintonizzato, a meno che non si passi dalla clonazione dei file alla clonazione dei dati del disco non elaborato. In quest'ultimo caso, sì, Assembly è davvero il tuo biglietto (o C) .

  • La semplice memorizzazione di file da 20 mm e la loro ricerca ricorsiva potrebbero essere meno efficienti in Python. Ma è più probabile che si tratti di trovare un algoritmo migliore e probabilmente non sarà migliorato in modo significativo da Assembly. Inoltre, NON sarà il principale contributore a 50 ore

In sintesi, l'assembly sarà di aiuto se si esegue una copia del settore del disco non formattata, ma NON sarà di aiuto se si esegue una copia a livello di file system.


La copia dei file è un processo legato all'I / O. È improbabile che si verifichi un aumento della velocità di riscrittura in assembly e persino il multithreading potrebbe causare un rallentamento delle cose in quanto thread diversi che richiedono file diversi nello stesso momento comporteranno più ricerche sul disco.

Utilizzare uno strumento standard è probabilmente il modo migliore per andare qui. Se c'è qualcosa da ottimizzare, potresti prendere in considerazione la possibilità di cambiare il tuo file system o il tuo hardware.


Non c'è alcun motivo per scrivere un programma di copia in assembly. Il problema è con la quantità di IO coinvolti non nella CPU. Inoltre, la funzione di copia in python è già scritta in C da esperti e non ti verrai più a scrivere in assembler.

Infine, il threading non sarà di aiuto, specialmente in python. Vai con Twisted o usa semplicemente il nuovo modulo multiprocessing in Python 2.6 e avvia un gruppo di processi per fare le copie. Salva te stesso un sacco di tormenti mentre fai il lavoro.


Non credo che farà una differenza percepibile quale lingua usi per questo scopo. Il collo di bottiglia qui non è la tua applicazione ma le prestazioni del disco.

Solo perché un linguaggio è interpretato, non significa che ogni singola operazione in esso sia lenta. Ad esempio, è una scommessa abbastanza sicura che il codice di livello inferiore in Python chiamerà il codice assembly (o compilato) per fare copia.

Allo stesso modo, quando fai roba con collezioni e altre librerie in Java, questo è per lo più compilato C, non interpretato Java.

Ci sono un paio di cose che puoi fare per velocizzare il processo.

  • Acquista dischi rigidi più veloci (10K RPM anziché 7.5K o meno latenza, cache più grandi e così via).
  • La copia tra due dischi fisici potrebbe essere più veloce della copia su un singolo disco (a causa del movimento della testa).
  • Se stai copiando attraverso la rete, mettilo in scena. In altre parole, copialo velocemente su un altro disco locale, quindi rallenti da lì attraverso la rete.
  • Puoi anche metterlo in scena in un modo diverso. Se si esegue un processo notturno (o anche settimanale) per mantenere aggiornata la copia (solo copia dei file modificati) anziché tre volte all'anno, non ci si troverà in una situazione in cui è necessario copiare una quantità enorme.
  • Inoltre, se si utilizza la rete, eseguirla sulla casella in cui si trova il repository. Non si desidera copiare tutti i dati da un disco remoto a un altro PC e quindi tornare a un altro disco remoto.

Puoi anche fare attenzione con Python. Potrei sbagliarmi (e senza dubbio i Pythonistas mi metteranno in chiaro se mi sbaglio su questo conteggio) ma ho un vago ricordo che il suo threading potrebbe non utilizzare completamente CPU multi-core. In tal caso, staresti meglio con un'altra soluzione.

Potresti star meglio ad attaccarti con la tua attuale soluzione. Sospetto che un programma di copia specializzato sarà già ottimizzato il più possibile dal momento che è quello che fanno .


Prima di mettere in dubbio l'app per la copia, è molto probabile che dovresti mettere in discussione il percorso dei dati. Quali sono i limiti teorici e cosa stai ottenendo? Quali sono i potenziali colli di bottiglia? Se esiste un singolo percorso di dati, probabilmente non si otterrà una spinta significativa parallelizzando le attività di archiviazione. Potresti addirittura esacerbare. La maggior parte dei vantaggi che si ottengono con l'I / O asincrono avviene a livello di blocco, un livello inferiore rispetto al file system.

Una cosa che potresti fare per potenziare I / O è separare il recupero dalle parti di origine e di archiviazione in quella di destinazione. Supponendo che l'origine e la destinazione siano entità separate, potresti teoricamente dimezzare la quantità di tempo per il processo. Ma gli strumenti standard lo stanno già facendo ??

Oh - e su Python e GIL - con l'esecuzione di I / O-bound, il GIL non è poi così male di una penalità.


RICHCOPY sta già copiando file in parallelo, e mi aspetto che l'unico modo per sconfiggerlo sia quello di mettersi a letto con il filesystem in modo da ridurre al minimo l'I / O del disco , in particolare la ricerca. Ti suggerisco di provare ntfsclone per vedere se soddisfa le tue esigenze. In caso contrario, il mio prossimo suggerimento sarebbe quello di parallelizzare ntfsclone .

In ogni caso, lavorare direttamente con il layout del filesystem su disco sarà più semplice in C, non in Python e certamente non in assembly. Soprattutto dal momento che è possibile iniziare utilizzando il codice C dal progetto NTFS 3G . Questo codice è progettato per affidabilità e facilità di porting, non di prestazioni, ma è ancora probabilmente il modo più semplice per iniziare.

Il mio tempo è abbastanza prezioso che sto cercando di capire se riuscirò a vedere guadagni abbastanza significativi in ​​termini di velocità di copia.

No. O più esattamente, al livello attuale di padronanza della programmazione dei sistemi, ottenere significativi miglioramenti della velocità sarà proibitivo . Quello che chiedi richiede competenze specialistiche. Sebbene io abbia esperienza precedente nell'implementazione di filesystem (molto più semplici di NTFS, XFS o ext2), non vorrei affrontare questo lavoro; Lo assumerei fatto.

Nota a piè di pagina: se si ha accesso a una scatola Linux, scoprire quale larghezza di banda di scrittura grezza è possibile ottenere nell'unità di destinazione:

time dd if=/dev/zero of=/dev/sdc bs=1024k count=100

ti darà il tempo di scrivere 100 MB in modo sequenziale nel modo più veloce possibile. Questo ti darà un limite assoluto su ciò che è possibile con il tuo hardware. Non provarlo senza capire la pagina man di dd ! dd sta per "distruggere i dati". (In realtà sta per "copia e converti", ma cc stato preso.)

Un programmatore di Windows può probabilmente indirizzarti a un test equivalente per Windows.


Nessuno dei due. Se si desidera sfruttare le funzionalità del sistema operativo per accelerare I / O, è necessario utilizzare alcune chiamate di sistema specializzate che sono più facilmente accessibili in C (o C ++). Non è necessario conoscere molto C per scrivere un programma del genere, ma è necessario conoscere le interfacce di chiamata di sistema.

Con ogni probabilità, puoi risolvere il problema senza scrivere alcun codice usando uno strumento esistente o mettendo a punto il sistema operativo, ma se hai davvero bisogno di scrivere uno strumento, C è il modo più semplice per farlo.





assembly