2012-01-16 4 views
8

Sono di fronte a un pezzo di codice, che copia un file su un dispositivo USB. seguito parte è l'importante:Prestazioni di copia di un file con fread/fwrite su USB

while((bytesRead = fread(buf, 1, 16*1024, m_hSource)) && !bAbort) { 
    // write to target 
    long bytesWritten = fwrite(buf, 1, bytesRead, m_hTarget); 

    m_lBytesCopied += bytesWritten; 

La cosa, il cliente ha detto, è piuttosto lento rispetto alla normale pc < -> Speed ​​USB. Non l'ho codificato, quindi è il mio lavoro, da ottimizzare.

Quindi mi stavo chiedendo, se è un approccio migliore per leggere prima il file completo e quindi scrivere il file in un solo passaggio. Ma non so quanto questo possa essere soggetto a errori. Il codice controlla anche dopo ogni copystep se tutti i byte sono scritti correttamente, in modo da rallentare il processo.

Io non sono quel C++ guru dell'hardware &, quindi ti sto chiedendo ragazzi, come potrei accelerare le cose e mantenere la copia riuscita.

+2

Cerca altrove il collo di bottiglia. Potresti ottenere un piccolo miglioramento modificando la dimensione del buffer, ma il tuo problema è probabilmente qualcos'altro. –

+0

Bene, questa è l'unica parte che sta facendo qualcosa con questo particolare problema. Quindi può essere solo il codice. –

+0

Rimuovere la verifica che i byte siano stati scritti correttamente. Se non ti puoi fidare della prima scrittura, non ti puoi fidare della seguente lettura che usi per la verifica. (Presumo che stiate controllando bytesWritten per errori.) –

risposta

3
  1. Provare a leggere/scrivere nel blocco grande. 16 M, 32 M non sono male per copiare il file.
  2. Se solo desidera copiare il file si può sempre invocare system() Sarà più veloce.
  3. Il codice controlla anche dopo ogni copystep se tutti i byte sono stati scritti correttamente, in modo da rallentare il processo.

    Si può controllare con la creazione di hash di grande pezzo. Come suddividere il file in blocchi da 64M. Quindi abbina gli hash di quei pezzi. Il protocollo BitTorrent ha questa caratteristica.

  4. Se avete mmap o MapViewOfFile disponibili, mappare il file prima. Quindi scrivilo su usb. In questo modo l'operazione di lettura verrà gestita dal kernel.

  5. Kerrek ha appena commentato l'utilizzo di memcpy su mmap. memcpy con 2 mmap ed il file sembra fantastico.

Inoltre, i più recenti sistemi operativi scrivono su chiavetta USB quando vengono rimossi. Prima della rimozione, scrive solo i dati in una cache. Quindi la copia dal sistema operativo potrebbe apparire più veloce.

+1

# 4 suona bene: mappa della memoria e usa 'memcpy'. –

+0

@KerrekSB +1. 'memcpy' con 2 file' mmap'ed sembra un'ottima opzione. Aggiornata la mia domanda. –

1

Che dire di letture e scritture sovrapposte?

Nel codice corrente, il tempo totale è time(read original) + time(write copy), se si legge il primo blocco, poi mentre scrivendo iniziare a leggere il secondo blocco, ecc il vostro tempo totale sarebbe max(time(read original), time(write copy)) (più il tempo a leggere/scrivere il primo e ultimi blocchi che non saranno pipeline).

Potrebbe essere quasi la metà del tempo se la lettura e la scrittura richiedono più o meno lo stesso tempo.

È possibile farlo con due thread o con IO asincrono. Sfortunatamente, i thread e gli I/O asincroni dipendono dalla piattaforma, quindi dovrai controllare il manuale di sistema o scegliere le librerie portatili appropriate.

+0

AFAIK, anche l'I/O USB dipende principalmente dalla piattaforma, non è così? –

+0

@ AndréCaron Immagino di sì se stai costruendo un driver, ma in questo caso penso che stia semplicemente accedendo al filesystem, così puoi 'fopen' file (e quello è standard). – fortran

0

Vorrei solo andare con alcune funzioni specifiche del sistema operativo che sicuramente lo fanno più velocemente che qualsiasi cosa scritta solo con le funzioni c/C++.

Per Linux questa potrebbe essere la funzione sendfile. Per Windows CopyFile farà il lavoro.

Problemi correlati