Forum: Mikrocontroller und Digitale Elektronik Warum SD Karte so langsam?


von Stefan Frings (Gast)


Lesenswert?

Hallo,
ich verwendet die avrfat32 Library in meinem Webserver, um von der SD 
Karte zu lesen. Insgesamt komme ich auf eine Download-Geschwindigkeit 
von etwa 50 Kilobytes pro Sekunde.

Obwohl ich in diversen Foren ähnliche Werte gefunden habe, wundert es 
mich dennoch.

Der AVR Webserver kann bei einer direkten Netzwerverbindung zum PC etwa 
500 Ethernet Pakete pro Seklunde senden. Der begrenzende Faktor ist nach 
meinem Kenntnisstand nicht die Rechenleistung des AVR, sondern die 
Laufzeit eines Paketes im Netz (von ca 1ms) da der Webserver aufgrund 
seiner einfachen Logik nach jeden Paket auf ein ACK wartet.

Für das Laden eines 512 Bytes Sektors schätze ich 0,3ms, da die SPI 
Taktfrequenz 16Mhz beträgt (der AVR hat 32Mhz CPU Takt). Dazu kommt 1ms 
zum Senden und nochmal 1ms zum Empfangen des ACK, macht also 2,3ms pro 
512 Byte. Das müsste dann 434 Pakete pro Sekunde ergeben, also 
220KB/sec.

In Wirklichkeit erreiche ich aber nur 50KB/sec.

Wo ist mein Denkfehler?

von Mw E. (Firma: fritzler-avr.de) (fritzler)


Lesenswert?

Der Prozessor brauch ja noch zeit zum sektor suchen auf der SD karte, 
ins Dateisystem gucken etc.
FRisst alles mächtig zweit bei ner Blockgröße von 512byte die jedesmal 
von der sd karte gelesen und im prozessor verarbeitet werden.

von (prx) A. K. (prx)


Lesenswert?

Stefan Frings schrieb:

> meinem Kenntnisstand nicht die Rechenleistung des AVR, sondern die
> Laufzeit eines Paketes im Netz (von ca 1ms) da der Webserver aufgrund
> seiner einfachen Logik nach jeden Paket auf ein ACK wartet.

... und normale TCP-Stacks bestenfalls nach jedem zweiten Frame, einem 
Timeout oder Fehlern ein Ack senden. Bei einfachst implementiertem TCP 
wird also jedesmal auf den Timeout gewartet.

Abhilfe: Jeden (TCP) Ethernet-Frame zweimal direkt hintereinander 
senden. Das klingt zwar als Beschleunigungsmassnahme etwas merkwürdig, 
führt aber zur sofortigen Bestätigung durch den Empfänger und vermeidet 
so den Timeout.

von Sascha W. (sascha-w)


Lesenswert?

@Stefan Frings

was hindert dich daran 2 Blöcke von der SD-Karte in ein TCP-Paket zu 
stecken?

Sascha

von Stefan Frings (Gast)


Lesenswert?

Zwei Blöcke in einem Paket habe ich versucht. Ich dachte, dann müsste es 
doppelt so schnell werden, weil die Anzahl der Pakete sich dadurch 
halbiert. Aber das hat im verkabelten Netz nur minimalen Vorteil 
gebracht und im WLAN sogar zu beinahe halbierter Performance. Bei mir 
sind die Frequenzen hoch ausgelastet (alle mindestens 5 fach durch 
konkurrierende Netze), in diesem Fall sind kleine Pakete scheinbar 
vorteilhafter.

Ich habe noch ein paar Zeiten gemessen. Dieses mal habe ich nicht mit 
Firefox downgeloaded, sondern mit wget. Der sendet die ACK's wohl 
schneller, denn damit konnte ich 69 Kilobytes/sec erreichen.

Ich hab dann mal den Zugriff auf die SD Karte einfach auskomemntiert, so 
daß der Webserver Zufällige Daten senden in der größe der angefragten 
10MB MP3 Datei. Da hatte ich dann eine Download Geschwindigkeit von 80 
Kilobytes/sec. Also ist mein Nadelöhr wohl der Webserver, nicht die SD 
Karte. Das hätte ich nicht erwartet.

Ohne SD Zugriff wurde es also um 1/7 schneller. Dass heist, wenn ich nur 
von der SD Karte lesen würde, ohne die Daten zu verarbeiten, wäre sie 7 
mal schneller, also 490 Kilobytes pro Sekunde. Das klingt doch schon 
sehr viel besser. Das wären ja effektiv rund 4 Megabit - für die 10 
Jahre alte Speicherkarte ist das sicher Ok.

Ich habe außerdem auch mal Wireshark laufen lassen, um die Antwortzeiten 
des Webservers zu messen. Auf einer Telnet Verbindung sende ich 5 Bytes 
und Empfange als Antwort 5 Bytes (ich frage einen I/O Pin ab). Die 
Antwort dauert immer 1-1,5ms.

Der andere Extremfall ist der HTTP Webserver. Beim Abruf einer Datei, 
die im Programmspeicher liegt (als char-array codiert) braucht der 
Server für die 1400 Pakete großen Pakete jeweils rund 15ms. Ganz schön 
viel.

Kann es sein, dass die Berechnung der Checksummen für das TCP Protokoll 
so teuer sind?

PS: Ich benutze uIP

von (prx) A. K. (prx)


Lesenswert?

Stefan Frings schrieb:
> Kann es sein, dass die Berechnung der Checksummen für das TCP Protokoll
> so teuer sind?

Nein.

> Ich benutze uIP

Das zu Grunde liegende Problem ist dort beschrieben. Eine Art Hack zu 
Lösung ist auch drin, hat bei mir aber nicht funktioniert.

Wdh: Beitrag "Re: Warum SD Karte so langsam?"
Der Ansatz ist übrigens nicht von mir. Wiznet verwendet diesen Trick, 
wenn die Pufferkonfiguration nicht für 2 Frames reicht.

von Falk B. (falk)


Lesenswert?

@Stefan Frings (Gast)

>Kann es sein, dass die Berechnung der Checksummen für das TCP Protokoll
>so teuer sind?

Kann man einfach messen. Vor der Berechnung ein IO-Pin auf high, danach 
auf LOW setzen, Oszi dran, fertig.

von Stefan Frings (Gast)


Lesenswert?

Hab ich inzwischen gemacht. Die LED leuchtet für knapp weniger als 15ms 
bei 1400 Byte Paketen und etwa 5ms bei 512 Byte Paketen.

Jedenfalls liegt's nicht an der Übertragunsgrate zur SD Karte, die hat 
nach der LED Messung fast 500 Kilobyte pro Sekunde - womit meine 
Ursprüngliche Frage ja auch geklärt ist.

von Sascha W. (sascha-w)


Lesenswert?

Stefan Frings schrieb:
> Hab ich inzwischen gemacht. Die LED leuchtet für knapp weniger als 15ms
> bei 1400 Byte Paketen und etwa 5ms bei 512 Byte Paketen.
hmm...
dann scheint die Umsetzung der 32-Bit Berechnungen durch den Compiler in 
dem Fall wirklich schlecht zu sein.
Ich hab gerade mal mit meiner Checksum-Berechnung aus meinem Webserver 
(ASM) simuliert, die nur mit Registern arbeitet.
für 700Byte, @16MHz > 374µs
1
checksum:
2
;  X -> Datenpointer
3
;  Y -> Anzahl Bytes zur Checksumme
4
;  long... -> bisherige Summe
5
;  Y <- Checksumme
6
7
checks_lo0:  ld  param1,X+
8
    ld  param2,X+
9
    sbiw  YL,1
10
    brne  checks_m00
11
    clr  param2
12
checks_m00:  add  longLL,param2
13
    adc  longLH,param1
14
    adc  longUL,isnull
15
    adc  longUH,isnull
16
    sbiw  YL,1
17
    brcs  checks_m01
18
    brne  checks_lo0
19
checks_m01:  mov  XL,longUL
20
    mov  XH,longUH
21
    mov  longUL,isnull
22
    mov  longUH,isnull
23
    add  longLL,XL
24
    adc  longLH,XH
25
    adc  longUL,isnull
26
    adc  longUH,isnull
27
28
    mov  XL,longUL
29
    mov  XH,longUH
30
    mov  longUL,isnull
31
    mov  longUH,isnull
32
    add  longLL,XL
33
    adc  longLH,XH
34
    adc  longUL,isnull
35
    adc  longUH,isnull
36
37
    ldiw  Y,-1
38
    sub  YL,longLL
39
    sbc  YH,longLH
40
    ret

Sascha

von P. M. (o-o)


Lesenswert?

Stefan Frings schrieb:
> Aber das hat im verkabelten Netz nur minimalen Vorteil
> gebracht und im WLAN sogar zu beinahe halbierter Performance. Bei mir
> sind die Frequenzen hoch ausgelastet (alle mindestens 5 fach durch
> konkurrierende Netze), in diesem Fall sind kleine Pakete scheinbar
> vorteilhafter.

Das halte ich für Unsinn. Dein WLAN "weiss" gar nichts von TCP, da es 
lediglich Pakete auf Ethernet-Ebene versendet. Der Server zerlegt die 
TCP-Pakete in IP-Pakete und diese wiederum in Ethernet-Pakete. Switches 
und WLAN-APs senden direkt die Ethernet-Pakete weiter. Router bauen die 
Ethernet-Pakete zu IP-Paketen zusammen, schauen sich die Ziel IP an, 
zerlegen die Pakete wieder und senden sie über den für die Ziel-IP 
passenden Anschluss. Erst das Ziel-Gerät baut sich die TCP-Pakete wieder 
zusammen.

Die Ursache liegt dann wohl woanders.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.