2016-11-17 22 views
5

Ich schreibe ein Programm, das Hochgeschwindigkeitsdatenerfassung durchführen wird. Die Erfassungskarte kann mit bis zu 6,8 GB/s laufen (auf PCIe3 x8). Im Moment versuche ich auf eine RAM-Disk zu streamen, um die maximale Schreibgeschwindigkeit zu sehen, die ich mit Python erreichen kann.Wie erreicht man maximale Schreibgeschwindigkeit mit Python?

Die Karte wird mir 5-10 MB Blöcke geben, die ich dann irgendwo schreiben kann.

Ich schrieb dieses Stück Code, der einen 10MB Block 500 Mal in eine Binärdatei schreibt. Ich benutze Anaconda2 unter Windows 7 64-Bit, und ich habe den Profiler von Anacondas Beschleunigung verwendet.

block = 'A'*10*1024*1024 
filename = "R:\\test" 
f = os.open(filename, os.O_CREAT| os.O_BINARY|os.O_TRUNC|os.O_WRONLY|os.O_SEQUENTIAL) 

p = profiler.Profile(signatures=False) 
p.enable() 
start = time.clock() 
for x in range(500): 
    os.write(f,block) 
transferTime_sec = time.clock() - start 
p.disable() 
p.print_stats() 

print('\nwrote %f MB' % (os.stat(filename).st_size/(1024*1024))) 

Getestet habe ich diese auf einer RAM-Disk (R: \) und ich bekam die folgende Ausgabe:

enter image description here

Also dachte ich, ich bin immer etwas rund 2,5 GB/s auf RAM. Das ist zwar nicht schlecht aber weit vom maximalen RAM Durchsatz, aber die Zahlen sind konsistent. Der geringe Durchsatz ist also ein Problem.

Das zweite Problem ist, wenn ich diesen Code mit einer PCIe SSD (die ich mit einer anderen Software mit 1090 MB/s sequentiellem Schreiben Benchmarking) getestet hat, gibt es vergleichbare Zahlen.

enter image description here

Das macht ich denke, dass es Caching und/oder Pufferung (?) Und so bin ich nur nicht unbedingt IO messen. Ich bin mir nicht sicher, was wirklich passiert, da ich mit Python ziemlich neu bin.

Also meine Hauptfrage ist, wie man maximale Schreibgeschwindigkeiten erreicht, und eine Nebenfrage ist, warum bekomme ich diese Zahlen?

+0

Ich frage mich, warum Sie 'os.open()' anstelle von 'open()' ?? –

+0

Male sicher keine Prozesse abfangen schreibt, ja ich sehe dich Windows Defender. –

+0

@ShadyAtef Mehr Kontrolle über Dateiattribute, möglicherweise direkte IO –

Antwort

0

Ich weiß nicht, ob Sie immer noch nach diesem Problem suchen, aber ich fand Ihre Frage interessant, also habe ich es auf einem Linux-Laptop versucht.

Ich habe Ihren Code auf Python 3.5 ausgeführt und festgestellt, dass Sie os.O_SYNC Flag auch haben müssen, um die Pufferung Problem zu vermeiden (im Grunde die os.write Funktion wird nicht zurückgegeben, bevor alle Daten auf der Festplatte geschrieben wurden). Ich ersetze auch time.clock() durch time.time(), die mir bessere Ergebnisse geben.

import os 
import time 
import cProfile 

def ioTest(): 
    block = bytes('A'*10*1024*1024, 'utf-8') 
    filename = 'test.bin' 
    f = os.open(filename, os.O_WRONLY | os.O_CREAT | os.O_TRUNC | 
       os.O_SYNC) 
    start = time.time() 
    for x in range(500): 
     os.write(f,block) 
    os.close(f) 
    transferTime_sec = time.time() - start 
    msg = 'Wrote {:0f}MB in {:0.03f}s' 
    print(msg.format(os.stat(filename).st_size/1024/1024, 
        transferTime_sec)) 
cProfile.run('ioTest()') 

Auch dieser post Vortrag über die os.O_DIRECT Flags verwendet, die DMA und Engpässe vermeiden verwenden. Ich hatte das Mmap Modul verwenden, um es auf meinem Rechner funktioniert:

import os 
import time 
import cProfile 
import mmap 

def ioTest(): 
    m = mmap.mmap(-1, 10*1024*1024) 
    block = bytes('A'*10*1024*1024, 'utf-8') 
    m.write(block) filename = 'test.bin' 
    f = os.open(filename, os.O_WRONLY | os.O_CREAT | os.O_TRUNC | 
       os.O_SYNC, os.O_DIRECT) 
    start = time.time() 
    for x in range(500): 
     os.write(f,m) 
    os.close(f) 
    transferTime_sec = time.time() - start 
    msg = 'Wrote {:0f}MB in {:0.03f}s.' 
    print(msg.format(os.stat(filename).st_size/1024/1024, 
        transferTime_sec)) 
cProfile.run('ioTest()') 

Diese um 40%, um die Schreibzeit auf meiner Maschine reduziert ... nicht schlecht. Ich habe os.O_SEQUENTIAL und os.O_BINARY nicht verwendet, die auf meinem Computer nicht verfügbar sind.

[Bearbeiten]: Ich habe gefunden, wie man das os.O_DIRECT Flag von diesem site verwendet, das es sehr gut und in der Tiefe erklärt. Ich empfehle dringend, dies zu lesen, wenn Sie in Python an Leistung und direkter IO interessiert sind.

Verwandte Themen