Seite 2 von 2

Re: Fehler 1450 bei fread()

Verfasst: Mo, 05. Nov 2012 10:41
von brandelh
das ist das Programm, dass die große Datei erzeugt (falls es jemand probieren möchte).
Mein betagter XP Rechner (200 GB SATA Platten) kommt auf etwa 55 MB / Sekunde (Schreiben auf lokale Festplatte).
Auf dem Neuen (1TB SATA Platte) sogar 125 MByte / Sekunde (Schreiben auf lokale Festplatte).
Möglich, dass auf einem neuen Rechner auch größere Blocks eine Beschleunigung bringen, im Netzwerk auf keinen Fall.

Code: Alles auswählen

#include "fileio.ch"
procedure main
   local cFileName := "verybig.txt"
   local nSizeExPl := 4154687701
   local cSizeExPl := "  4.154.687.701"
   local nZiel, nBytes, x, nBytesToWrite, nWrittenBytes
   local nDauer

   cls

   delete file (cFileName)  // sicher ist sicher

   nBytes  := 4096
   cBuffer := replicate("A",nBytes)
   nBytesToWrite := nSizeExPl
   nWrittenBytes  := 0

   ?
   ? "Make VeryBig.TXT"
   ? cFileName
   ? "Gewünschte Größe:    ", transform(nSizeExPl,"999,999,999,999"), " (numerisch)"
   ? "Gewünschte Größe:    ", cSizeExPl, " (string)"
   ? "Startzeit:           ", time()
   ?

   nDauer  := seconds()
   nZiel   := FCreate( cFileName, FC_NORMAL )

   IF nZiel == -1
      ? "Fehler beim Erzeugen der Datei:", FError()
   ELSE
      x             := 1
      do while nBytesToWrite > 0
         if x > 100
            @ row(), 0 say "Geschriebene Bytes:   "+transform(nWrittenBytes, "999,999,999,999")
            x := 1
         else
            x++
         endif
         if nBytesToWrite < nBytes  // nicht mehr schreiben als gewünscht
            nBytes := nBytesToWrite
         endif
         nBytes := FWrite(nZiel, @cBuffer, nBytes)
         nBytesToWrite -= nBytes
         nWrittenBytes += nBytes
         if FError() > 0
            ? "SCHREIBEN - FError() = ",FError()
            exit
         endif
      enddo
   ENDIF

   FClose( nZiel )

   nDauer  := seconds() - nDauer

   ? "Ende mit Close:      ", time()

   ? "Ergebnis:"
   ? "Gewünschte Größe:    ", transform(nSizeExPl,"999,999,999,999"), " (numerisch)"
   ? "Gewünschte Größe:    ", cSizeExPl, " (string)"
   ? "Geschriebene Bytes:  ", transform(nWrittenBytes,"999,999,999,999"), " (gezählt)"
   ? "Tatsächliche Größe:  ", transform(FSize(cFileName),"999,999,999,999"), " (FSize())"
   ? "Dauer:   ", ntrim(int(nDauer/60)) , "Minuten", ntrim(nDauer % 60) , "Sekunden.   Geschwindigkeit: ",alltrim(transform(nWrittenBytes/1024/nDauer,"999,999")),"MByte/Sekunde"

   wait
return
*----------------------------------------------------
function ntrim(n)
return alltrim(str(n))

Re: Fehler 1450 bei fread()

Verfasst: Mo, 05. Nov 2012 10:44
von brandelh
ganz wichtig, bei Dateien über 2 GB hat FSEEK() einen Fehler, keinesfalls einsetzen !

Re: Fehler 1450 bei fread()

Verfasst: Mo, 05. Nov 2012 11:12
von Werner_Bayern
Servus Hubert,

dazu muss man aber erst eine Datei namens verybig.txt erzeugen?
Den Sinn der beiden Zeilen

Code: Alles auswählen

   ? "Größe laut Explorer: ", transform(nSizeExPl,"999,999,999,999"), " (numerisch)"
   ? "Größe laut Explorer: ", cSizeExPl, " (string)"
verstehe ich nicht, hat wohl mit dem 2-GB-Test nichts zu tun?

Re: Fehler 1450 bei fread()

Verfasst: Mo, 05. Nov 2012 11:15
von Werner_Bayern
Ok, hat sich überschnitten, während meines Tests hast Du das Upload schon gemacht. Danke.

Re: Fehler 1450 bei fread()

Verfasst: Mo, 05. Nov 2012 11:41
von brandelh
Werner_Bayern hat geschrieben: Den Sinn der beiden Zeilen

Code: Alles auswählen

   ? "Größe laut Explorer: ", transform(nSizeExPl,"999,999,999,999"), " (numerisch)"
   ? "Größe laut Explorer: ", cSizeExPl, " (string)"
verstehe ich nicht, hat wohl mit dem 2-GB-Test nichts zu tun?
genau deswegen habe ich im Explorer nachgesehen was richtig ist ;-)

PS: das ist also der 'richtige' Vergleichswert.

Re: Fehler 1450 bei fread()

Verfasst: Mo, 05. Nov 2012 11:51
von Werner_Bayern
brandelh hat geschrieben:genau deswegen habe ich im Explorer nachgesehen was richtig ist ;-)

PS: das ist also der 'richtige' Vergleichswert.
??? Du gibst da einfach einmal eine Zahl als String aus und einmal eine "Konstante".

Hab mir erlaubt, dein Beispiel etwas anzupassen:

Code: Alles auswählen

procedure main
   local cFileName := "verybig.txt"
   local nSizeExPl := 4154687701
   local cSizeExPl := "  4.154.687.701"
   local nZiel, nBytes, x, nBytesToWrite, nWrittenBytes
   local nDauer, cBuffer

   cls

   delete file (cFileName)  // sicher ist sicher

//   nBytes  := 4096
   nBytes  := 1024 * 1024 * 40   // 40 MB
   cBuffer := replicate("A",nBytes)
   nBytesToWrite := nSizeExPl
   nWrittenBytes  := 0

   ?
   ? "Testdatei", cFileName, "wird erzeugt..."
   ? "Blockgröße:          ", transform(nBytes, "999,999,999,999"), "=", ltrim(str(nBytes / 1024 / 1024)), "MB"
   ? "Gewünschte Größe:    ", cSizeExPl
   ? "Startzeit:           ", time()
   ?

   nDauer  := seconds()
   nZiel   := FCreate( cFileName, FC_NORMAL )

   IF nZiel == -1
      ? "Fehler beim Erzeugen der Datei:", FError()
   ELSE
      x             := 1
      do while nBytesToWrite > 0
         if x > 0
            @ row(), 0 say "Geschriebene Bytes:   "+transform(nWrittenBytes, "999,999,999,999")
            x := 1
         else
            x++
         endif
         if nBytesToWrite < nBytes  // nicht mehr schreiben als gewünscht
            nBytes := nBytesToWrite
         endif
         nBytes := FWrite(nZiel, @cBuffer, nBytes)
         nBytesToWrite -= nBytes
         nWrittenBytes += nBytes
         if FError() > 0
            ? "SCHREIBEN - FError() = ",FError()
            exit
         endif
      enddo
   ENDIF

   FClose( nZiel )

   nDauer  := seconds() - nDauer

   ? "Ende mit Close:      ", time()

   ? "Ergebnis:"
   ? "Gewünschte Größe:    ", transform(nSizeExPl,"999,999,999,999"), " (numerisch)"
   ? "Gewünschte Größe:    ", cSizeExPl, " (string)"
   ? "Geschriebene Bytes:  ", transform(nWrittenBytes,"999,999,999,999"), " (gezählt)"
   ? "Tatsächliche Größe:  ", transform(FSize(cFileName),"999,999,999,999"), " (FSize())"
   ? "Dauer:   ", ntrim(int(nDauer/60)) , "Minuten", ntrim(nDauer % 60) , "Sekunden.   Geschwindigkeit: ",;
   alltrim(transform(nWrittenBytes/1024/nDauer,"999,999")),"MByte/Sekunde"

   wait
return
*----------------------------------------------------
function ntrim(n)
return alltrim(str(n))
Es werden hier also 40 MB-Blöcke geschrieben. Lokal läuft das durch, auf ein Netzlaufwerk (einfach cFileName ändern!) knallt es nach einigen Durchläufen mit dem 1450 bei fwrite().

Übrigens fast genau wie Dein Beispiel ist mein o. g. GUI, das permanent schreibt und liest, um die Zuverlässigkeit des Lesens und Schreibens lokal oder im Netz zu testen mit permanenter Angabe der Schreib- und Leserate, alles als eigenständiger Thread.

Re: Fehler 1450 bei fread()

Verfasst: Mo, 05. Nov 2012 13:14
von brandelh
ein TCP/IP Paket ist relative klein, meist nur 1500 Byte (im Internet auch weniger):
an Ethernet LAN has an MTU size of 1500 bytes,
wenn du nun 4 KByte Blöcke sendest, ist die Wahrscheinlichkeit groß, dass es reibungslos durch geht (wenn nicht, restart).
Bei 40 MB Blöcken scheint wohl irgendwo ein Buffer an seine Grenzen zu kommen.
Auch die Festplatte muss den auf der einen Seite lesen und auf der anderen schreiben ...

Nimm 4 KB Block lokal und z.B. 1 KB Blocks im Netzwerk und alles müsste optimal sein.

Zu erwähnen ist noch oben diese Zeile:
nBytes := FWrite(nZiel, @cBuffer, nBytes)
da hier FWrite() die Variable als REFERENZ übergeben wird, spart man viele Tausend interne Variablen-Kopien,
die angelegt, verworfen und vom GC aufgeräumt werden müssen.

Re: Fehler 1450 bei fread()

Verfasst: Mo, 05. Nov 2012 13:26
von Werner_Bayern
Tja, das scheint dann so zu sein, viele kleine Häppchen schreiben, nicht wenige große.

Re: Fehler 1450 bei fread()

Verfasst: Mo, 05. Nov 2012 22:06
von AUGE_OHR
du könntest, wenn du Fread()/Fwrite() verwendest, ja einen Progressbar anzeigen. Demo in der DXE Lib vorhanden.

Re: Fehler 1450 bei fread()

Verfasst: Mo, 05. Nov 2012 22:35
von Werner_Bayern
AUGE_OHR hat geschrieben:du könntest, wenn du Fread()/Fwrite() verwendest, ja einen Progressbar anzeigen. Demo in der DXE Lib vorhanden.
Mach ich sowieso. Zumindest lokal ist aber die Schreib- und Leserate höher, wenn große Blöcke verwendet werden. Und es wird weniger CPU-Zeit verbraucht, vom Xbase++-Programm und vom Betriebssystem, da zumindest lokale Schreib- und Lesevorgänge wesentlich weniger verbrauchen als Schleifendurchläufe mit Berechnungen.

Re: Fehler 1450 bei fread()

Verfasst: Di, 06. Nov 2012 8:44
von brandelh
Werner_Bayern hat geschrieben:Zumindest lokal ist aber die Schreib- und Leserate höher, wenn große Blöcke verwendet werden. Und es wird weniger CPU-Zeit verbraucht, vom Xbase++-Programm und vom Betriebssystem
ich habe es mal auf dem betagten X2 ausprobiert:
4 KB: 55 MB/Sekunde mit 25 % (also 50% auf dem verwendeten Kern)
40 KB: 63 MB/Sekunde mit 12-16 % (also 25% auf dem verwendeten Kern)
400 KB: 36 MB/Sekunde mit 12-16 % (also 25% auf dem verwendeten Kern)
4000 KB: 57 MB/Sekunde mit 8-18 % (starke Schwankungen, unschöne Anzeige )

Je nach Rechner und Festplatte sind die Werte natürlich unterschiedlich, aber ...
Werner_Bayern hat geschrieben: ... wesentlich weniger ...
wesentlich wäre bei mit wenn es mindestens doppelt so schnell abläuft.
Werner_Bayern hat geschrieben:da zumindest lokale Schreib- und Lesevorgänge wesentlich weniger verbrauchen als Schleifendurchläufe mit Berechnungen.
Das stimmt grundsätzlich nicht, sowohl Festplattenzugriffe als auch Anzeigen von XbpSle oder @ SAY / ? sind deutlich langsamer als die Berechnung um nur jeden 100. Durchgang anzuzeigen.
Normale Festplatten haben 512 Byte Blöcke (neuere 4 KB) und NTFS nutzt 4 KB als Standardwert, daher habe ich 4096 Byte Buffer und eine schnelle Anzeige.

Re: Fehler 1450 bei fread()

Verfasst: Mi, 07. Nov 2012 8:22
von AUGE_OHR
hi,

warum redet ihr "lokal" von "lächerlichen" 99MB/sec ... nimm doch eine SSD ;)

Re: Fehler 1450 bei fread()

Verfasst: Mi, 07. Nov 2012 8:25
von brandelh
Lieber Kunde,

"Wenn du willst, das mein Programm keine Fehler mehr macht, musst du IMMER die teuerste und neueste Hardware kaufen, MONATLICH" :!:
... und der Kunde kaufe ...
"Die Fehler sind immer noch da ..." :banghead:
...
"Probiere es nächsten Monat mit der neuen Hardware nochmal ... " :^o

Re: Fehler 1450 bei fread()

Verfasst: Mi, 07. Nov 2012 8:42
von AUGE_OHR
brandelh hat geschrieben:... Hardware
du kannst deine Xbase++ Application ja als VHD Image ausliefern dann bekommt der Kunden gleich deine "virtuelle" Hardware mit ;)

jetzt im Ernst, wer SATA III hat "sollte" eine SSD verwenden mit > 500MB/sec denn die HDD ist "lokal" der Flaschenhals.
auch mit SATA II ist man immer noch viel schneller als jede HDD.

und für die Extremen : 3 SDD im RAID Verbund ... ;)

p.s. von den "billigen" SDD "Cache" Zwischenlösungen halte ich nichts [-X

Re: Fehler 1450 bei fread()

Verfasst: Mi, 07. Nov 2012 14:20
von Wolfgang Ciriack
Wenn man SSD einsetzt, sollte man aber unbedingt immer ordentlich sichern, denn teilweise sollen diese schon nach Laufzeiten unter einem Jahr ausfallen ! Ich glaube, so ganz ausgereift ist die Technik noch nicht.

Re: Fehler 1450 bei fread()

Verfasst: Do, 08. Nov 2012 23:17
von Werner_Bayern
brandelh hat geschrieben:ich habe es mal auf dem betagten X2 ausprobiert:
Hubert,

ich habe nichts von GRA-Ausgaben geschrieben. Es geht um die rohe Schreib- und Leserate und da ist es bei mir so, wie geschrieben.
Intel E8400, SataII-Festplatte, Vista 32bit, 4 GB Ram.
Aber wer nutzt schon die lokale Festplatte, ich gehe davon aus, dass 99% der Anwendungen im Netz laufen.

Test 2 und 4 zeigen bei Dir ja auch, dass es mit größeren Blöcken schneller geht.

Re: Fehler 1450 bei fread()

Verfasst: Fr, 09. Nov 2012 2:03
von AUGE_OHR
Werner_Bayern hat geschrieben:Aber wer nutzt schon die lokale Festplatte,
stimmt ... RAM ist "schneller" als jede SSD
Werner_Bayern hat geschrieben:ich gehe davon aus, dass 99% der Anwendungen im Netz laufen.
und das heisst mehr als 1 User womit es zu "Kollisionen" kommen "könnte"
Werner_Bayern hat geschrieben:Test 2 und 4 zeigen bei Dir ja auch, dass es mit größeren Blöcken schneller geht.
"irgendwann" macht jedes Netzwerk "zu".

was noch was bringt sind "Jumbo-Frames" aber das kann nicht jede Netzwerkkarte / Switch / Router
man sollte sich auch dabei die LEDs "ansehen" und im Server Logfile Netzwerk die Einträge kontrollieren ob "Übertragungsfehler" auftauchen bei zu grossen Blöcken.

Re: Fehler 1450 bei fread()

Verfasst: Fr, 09. Nov 2012 17:47
von Rolf Ramacher
was tritt auf, wenn du memoread() machst ??

Re: Fehler 1450 bei fread()

Verfasst: Fr, 09. Nov 2012 23:34
von Werner_Bayern
Wolfgang Ciriack hat geschrieben:Wenn man SSD einsetzt, sollte man aber unbedingt immer ordentlich sichern, denn teilweise sollen diese schon nach Laufzeiten unter einem Jahr ausfallen ! Ich glaube, so ganz ausgereift ist die Technik noch nicht.
Nicht bei aktueller Firmware und aktueller Hardware von entsprechenden Herstellern. Das war mal vor Jahren und billigstem Fernost-Zeugs.

Re: Fehler 1450 bei fread()

Verfasst: Fr, 09. Nov 2012 23:36
von Werner_Bayern
Rolf Ramacher hat geschrieben:was tritt auf, wenn du memoread() machst ??
Wir diskutieren hier vom Lesen und Schreiben von großen Datenmengen in unterschiedlichen Blockgrößen. Das alles ist mit memoread nicht möglich.

Re: Fehler 1450 bei fread()

Verfasst: Di, 30. Sep 2014 8:55
von brandelh
brandelh hat geschrieben:ganz wichtig, bei Dateien über 2 GB hat FSEEK() einen Fehler, keinesfalls einsetzen !
Der Fehler von FSEEK() wurde mit 2.00.547 (RC1) behoben.