![Das deutsche QBasic- und FreeBASIC-Forum Foren-Übersicht](misc/logos/logo.png) |
Das deutsche QBasic- und FreeBASIC-Forum Für euch erreichbar unter qb-forum.de, fb-forum.de und freebasic-forum.de!
|
Vorheriges Thema anzeigen :: Nächstes Thema anzeigen |
Autor |
Nachricht |
charly013
Anmeldungsdatum: 21.02.2023 Beiträge: 12 Wohnort: deutschland
|
Verfasst am: 08.03.2023, 11:31 Titel: bmp laden sehr langsam, was tun? |
|
|
moinmoin,
ich lade eine bmp datei in einer schleife mit:
Get #v_datei, tmp1ui, v_bild001(v_x, v_y)
in ein array, v_x & v_y sind die aufloesung hoehe * breite
die schleife zaehlt nur v_x und v_y hoch (aufloesung des bildes)
tmp1ui, die position in der datei, wird aus der aufloesung berechnet
lade ich ein 3600 * 1800 bmp dauert das fast 30 sekunden auf einem
i7-10700 mit ssd
wenn i die zeile zum laden entferne (auskommentiere) brauch die schleife
0.015 sekunden
gibts eine moeglichkeit das zu beschleunigen, i denke da nicht an ein
paar sekunden sondern mind. faktor 5, besser 10 oder mehr
vG _________________ Fliegen Fliegen hinter Fliegen dann fliegen Fliegen Fliegen nach |
|
Nach oben |
|
![](templates/subSilver/images/spacer.gif) |
ThePuppetMaster
![](images/avatars/15203237124744b0302dc46.gif)
Anmeldungsdatum: 18.02.2007 Beiträge: 1837 Wohnort: [JN58JR]
|
Verfasst am: 08.03.2023, 14:13 Titel: |
|
|
Hallo charly013,
dein Zeitliches-Problem beruht darauf, das du eine Funktion aufrufst, welche sehr langsam aber auch sehr schnell sein kann, je nachdem, wie es diese verwendet.
Zum Hintergrund von GET folgendes: GET reserviert speicher, sucht in der Datei nach einer entsprechenden Adresse im File, kopiert den von dir gewählten datei-bereich in einen speicherbereich und gibt dir das dann zurück.
Daraus kann man ableiten, das viele kleine dateibereiche mehr zeit in Anspruch nehmen, als größere Bereiche. Daher wäre es für dich sinvoll, wenn du sehr große Bereiche auf einmal in den RAM lädst (Variable) und später daraus deine einzelnen Elemente in einen anderen Speicher kopierst.
Bedenke, das Daten einer Datei nicht aus dem RAM kommen, sondern normalerweise von einer Festplatte, welche VIEL langsamer ist als der Hauptspeicher. Kleine Bläcke von der Festplatte zu lesen dauert damit einfach länger, als wenn man dem System sagt, "Kopiere mir gleich 4MB ins Ram" als "Kopier mir nur 4 Byte" und das ganze dann 1.000.000x wiederholst.
MfG
TPM _________________ [ WebFBC ][ OPS ][ ToOFlo ][ Wiemann.TV ] |
|
Nach oben |
|
![](templates/subSilver/images/spacer.gif) |
charly013
Anmeldungsdatum: 21.02.2023 Beiträge: 12 Wohnort: deutschland
|
Verfasst am: 08.03.2023, 15:09 Titel: |
|
|
danke f. die Antw.,
wie waehre da die vorgehnsweise?
ein string mit filelaenge dimensionieren und dann mit Get #file, 1, string
"alles" einlesen?
vG _________________ Fliegen Fliegen hinter Fliegen dann fliegen Fliegen Fliegen nach |
|
Nach oben |
|
![](templates/subSilver/images/spacer.gif) |
ThePuppetMaster
![](images/avatars/15203237124744b0302dc46.gif)
Anmeldungsdatum: 18.02.2007 Beiträge: 1837 Wohnort: [JN58JR]
|
Verfasst am: 08.03.2023, 15:27 Titel: |
|
|
Prinzipiel, ja, aber die blockgröße sollte nicht zu groß ausfallen. Also, 100MB auf einmal wäre schon heftig. Ich würde es in der tat auf maximal 10MB pro block beschränken.
Also quasi in der Art ...
Code: |
'(UNGETESTET)
Dim TFN as Integer = FreeFile
'OPEN FILE
Dim TFilesize as Integer = LOF(TFN)
Dim TBlocksize = 1000000
Dim T as String = Space(TBlocksize)
FOR X as Integer = 1 to LOF(...) STEP TBlocksize
If X + TBlocksize > TFilesize Then T = Space(TFilesize - X + 1)
GET #TFN, X, T
Next
|
MfG
TPM _________________ [ WebFBC ][ OPS ][ ToOFlo ][ Wiemann.TV ] |
|
Nach oben |
|
![](templates/subSilver/images/spacer.gif) |
charly013
Anmeldungsdatum: 21.02.2023 Beiträge: 12 Wohnort: deutschland
|
Verfasst am: 09.03.2023, 19:53 Titel: |
|
|
danke f. den "anstubser" TPM
datei = 3200x1800x8 = gut 6320 kB
laden dauert jetzt unter 0,02 s, das "transferieren" in das
zweidimensionale array ca. 0.6 s
kein vergleich zu den ca 30 s von vorher
(was i nicht verstanden habe ist das der alte code auf einem i7-4790k mit
HDD, keine SSD, doppelt so schnell laeuft)
hier der geaenderte code (nach TPM)
Code: |
tmp1db = Timer
v_datei = FreeFile()
Open v_dateiname For Binary As #v_datei
Dim v_filesize as UInteger = LOF(v_datei)
Dim v_fileinhalt as String = Space(v_filesize)
Print " lade "; v_filesize/1024 ;" kb "
Get #v_datei, 1, v_fileinhalt
tmp2db = Timer
for v_y.... ' ins 2 dimensinale array v_bild001 schreiben
for v_x....
v_bild001(v_x, v_y) = Asc(Mid(v_fileinhalt,(v_x + v_y2),1))
next
next
|
_________________ Fliegen Fliegen hinter Fliegen dann fliegen Fliegen Fliegen nach |
|
Nach oben |
|
![](templates/subSilver/images/spacer.gif) |
ThePuppetMaster
![](images/avatars/15203237124744b0302dc46.gif)
Anmeldungsdatum: 18.02.2007 Beiträge: 1837 Wohnort: [JN58JR]
|
Verfasst am: 09.03.2023, 22:58 Titel: |
|
|
HDD und SSD sind zwei völlig unterschiedliche Speichertechnologien. Daher kann es durchaus auch mal sein, das SSD's langsamer als HDD's sind. Klingt komisch, aber in bestimmten fällen durchaus merklich.
Eine HDD basiert auf einer sich drehenden Scheibe, über die ein Lesekopf die Daten aus einer kontinuierlichen Spur ausliest.
Hast du jetzt den Fall, das deine Datei nicht fragmentiert ist, und damit genau in einer linie, hintereinander auf der spur liegt, dann kann die HDD den lesekopf an dieser stelle belassen, und deine kleinen einzelanfragen sehr schnell hintereinander abrufen.
Die SSD hingegen nutzt hier ein anderes Verfahren. Die Speicherbereiche sind hier zwar alle direkt, elektrisch ansprechbar, allerdings dauert es einen kleinen augenblick, diesen Speicherbereich zu adressieren. Ein Speicherbereich in einer SSD ist nämlich nicht direkt einzelen (Byteweise) adresierbar, sondern wird in der SSD interen in einem sehr großen Block hinterlegt. Das kann man sich wie eine Tabelle mit X und Y vorstellen, hinter der nicht ein Byte, sondern gleich ein ganzes MB liegt (nur zur veranschaulichung). Wenn dieser MB Block jetzt adressiert ist, muss aus diesem quasi nur ein einziges Byte herausgelesen werden. Damit SSD's aber schnell große datenmengen schreiben können, ist sie darauf ausgelegt, viele daten in "blöcke" schnell zu schreiben und zu lesen.
Daraus folgert sich, das kleine brocken, immer wieder durch große kopieraktionen ... 1MB in Cache, daraus 1 Byte zum RAM ... nächste adresse, gleiches 1 MB in cache, daraus wieder 1 Byte zum RAM, ... usw.
Bei der sich drehenden Platte "fliegt" der "block" quasi immer wieder am lesekopf vorbei. Hier ist quasi nur ein kurzes waren auf den richtigen Anfang nötig.
Aber, das betrifft wieder nur das Lesen .. beim Schreiben wirds wieder anders ...
usw. usf. ...........
Aber, wie gesagt, das ist jetzt nur ein quasi-günstiges Beispiel. Wie schnell das schlussendlich wird, hängt von vielen weiteren Faktoren ab. Aber, so grob kann man es hierauf runter brechen.
MfG
TPM _________________ [ WebFBC ][ OPS ][ ToOFlo ][ Wiemann.TV ] |
|
Nach oben |
|
![](templates/subSilver/images/spacer.gif) |
ThePuppetMaster
![](images/avatars/15203237124744b0302dc46.gif)
Anmeldungsdatum: 18.02.2007 Beiträge: 1837 Wohnort: [JN58JR]
|
Verfasst am: 09.03.2023, 23:06 Titel: |
|
|
Ach, und was dir auch noch massiv zeit klaut ist das "MID" in deinem Code.
Du überträgst einen sehr großen Speicherbereich (zwar als referenz) an eine Funktion, diese muss aber erst einen teil daraus heraus schneiden, zwischenkopieren, umwandeln, und dir dann zurück geben, bevor du ihn in deinen speicher paken kannst.
sinvoller wäre hier direkt den speicherbereich zu adressieren und den inhalt aus einem anderen speicherbereich direkt zu kopieren.
deine variante
Code: |
for v_y.... ' ins 2 dimensinale array v_bild001 schreiben
for v_x....
v_bild001(v_x, v_y) = Asc(Mid(v_fileinhalt,(v_x + v_y2),1))
next
next
|
optimierte variante
Code: |
for v_y.... ' ins 2 dimensinale array v_bild001 schreiben
for v_x....
v_bild001(v_x, v_y) = v_fileinhalt[v_x + v_y2]
next
next
|
ich weis jetzt nicht genau, warum du v_y2 geschrieben hast, aber wenn das ein fehler war, dann könntest du sogar noch trickreicher vorgehen, und die datei gleich direkt in dein array rein lesen:
Code: |
Dim v_bild001(1 to breite, 1 to höhe) as ubyte
Get #v_datei, 1, v_bild001(0, 0), breite * höhe
|
MfG
TPM _________________ [ WebFBC ][ OPS ][ ToOFlo ][ Wiemann.TV ] |
|
Nach oben |
|
![](templates/subSilver/images/spacer.gif) |
charly013
Anmeldungsdatum: 21.02.2023 Beiträge: 12 Wohnort: deutschland
|
Verfasst am: 10.03.2023, 08:41 Titel: |
|
|
danke f. die tips, werd i nachher mal testen
hier die erklaerung warum v_y2
Code: |
Print " shift 2 array ";
tmp1db = Timer
For v_y = 0 To v_hoehe-1
v_y2 = (v_y * v_breite) + startpos2 ' startpos2 = laenge bmp header
For v_x = 0 To v_breite-1
v_bild001(v_x, v_y) = Asc(Mid(v_fileinhalt,(v_x + v_y2),1))
Next
Next
|
vG _________________ Fliegen Fliegen hinter Fliegen dann fliegen Fliegen Fliegen nach |
|
Nach oben |
|
![](templates/subSilver/images/spacer.gif) |
ThePuppetMaster
![](images/avatars/15203237124744b0302dc46.gif)
Anmeldungsdatum: 18.02.2007 Beiträge: 1837 Wohnort: [JN58JR]
|
Verfasst am: 10.03.2023, 09:54 Titel: |
|
|
achsoooo ... na dann ...
Code: | Get #v_datei, 1, BMP_Header
Get #v_datei, Len(BMP_Header), v_bild001(0, 0), breite * höhe |
MfG
TPM _________________ [ WebFBC ][ OPS ][ ToOFlo ][ Wiemann.TV ] |
|
Nach oben |
|
![](templates/subSilver/images/spacer.gif) |
charly013
Anmeldungsdatum: 21.02.2023 Beiträge: 12 Wohnort: deutschland
|
Verfasst am: 12.03.2023, 09:21 Titel: |
|
|
kurze rueckinfo:
bildgroesse = 3600 X 1800 x 8
meine Version:
v_bild001(v_x, v_y) = Asc(Mid(v_fileinhalt,(v_x + v_y2),1))
braucht ca. 0.65 Sekunden
optimierte variante
v_bild001(v_x, v_y) = v_fileinhalt[v_x + v_y2]
braucht ca. 0.045 Sekunden
danke!
hab noch eine Frage, wieso kann ich das Windows Fenster nicht oben rechts ueber das X schliessen?,
bzw. was muss ich dem programm hinzufuegen damit es "erlaubt" ist?
vG _________________ Fliegen Fliegen hinter Fliegen dann fliegen Fliegen Fliegen nach |
|
Nach oben |
|
![](templates/subSilver/images/spacer.gif) |
nemored
![](images/avatars/18585278245ddb8b9d8710.png)
Anmeldungsdatum: 22.02.2007 Beiträge: 4604 Wohnort: ~/
|
Verfasst am: 12.03.2023, 11:39 Titel: |
|
|
charly013 hat Folgendes geschrieben: | hab noch eine Frage, wieso kann ich das Windows Fenster nicht oben rechts ueber das X schliessen?,
bzw. was muss ich dem programm hinzufuegen damit es "erlaubt" ist?
|
Der X-Button sendet denselben Code an das Programm wie die Tastenkombination Alt+F4; dein Programm kann das dann auswerten und entsprechend reagieren (z. B. vorher Daten sichern, Bestätigung des Programmendes anfordern o. ä.). Um solche Aufräumarbeiten zu ermöglichen, wird das Programm nicht automatisch beendet.
Für die Umsetzung: Du kannst z. B. über INKEY die gedrückte Taste abfragen - hierzu der Beispielcode. Eine andere Möglichkeit wäre die Auswertung eines SCREENEVENTs. _________________ Deine Chance beträgt 1:1000. Also musst du folgendes tun: Vergiss die 1000 und konzentriere dich auf die 1. |
|
Nach oben |
|
![](templates/subSilver/images/spacer.gif) |
ThePuppetMaster
![](images/avatars/15203237124744b0302dc46.gif)
Anmeldungsdatum: 18.02.2007 Beiträge: 1837 Wohnort: [JN58JR]
|
Verfasst am: 12.03.2023, 11:44 Titel: |
|
|
Das "X" wird in Freebasic über ein InKey() gesendet. Das fängst du ganz einfach ab, und reagierst darauf. Idealerweise so hier:
Code: | Open Cons for Output as #1
Screen 1
Dim TKey as String
Dim TKey1 as UByte
Dim TKey2 as UByte
Do
TKey1 = 0
TKey2 = 0
TKey = InKey()
If Len(TKey) >= 1 Then TKey1 = TKey[0]
If Len(TKey) >= 2 Then TKey2 = TKey[1]
Select Case TKey1
Case 0 'Wenn keine Taste gedrückt ist / wurde (Default, quasi ein "Nix zu tun")
Case 27 'ESC
Print #1, "ESC Gedrückt!"
Exit Do
Case 255 'Spezialtasten
Select Case TKey2
Case 107 'X-Knopf am Fenster
Print #1, "X-Knopf Gedrückt!"
Exit Do
Case Else 'Sonstige Spezialtasten
Print #1, "Tastencode: " & Str(TKey1) & " " & Str(TKey2)
End Select
Case Else 'Sonstige tasten
Print #1, "Tastencode: " & Str(TKey1) & " " & Str(TKey2)
End Select
Loop
|
MfG
TPM _________________ [ WebFBC ][ OPS ][ ToOFlo ][ Wiemann.TV ]
Zuletzt bearbeitet von ThePuppetMaster am 15.03.2023, 14:14, insgesamt einmal bearbeitet |
|
Nach oben |
|
![](templates/subSilver/images/spacer.gif) |
charly013
Anmeldungsdatum: 21.02.2023 Beiträge: 12 Wohnort: deutschland
|
Verfasst am: 12.03.2023, 15:21 Titel: |
|
|
danke f. die info / hilfe
mir ging es darum das i nicht immer den taskmanager 'bemuehen' muss wenn mein 'programm' in einem LoopVorEver haengt
vG & einen schoenen Sonntag
@TPM vy73 aus JN39KK (grad erst gesehn ) _________________ Fliegen Fliegen hinter Fliegen dann fliegen Fliegen Fliegen nach |
|
Nach oben |
|
![](templates/subSilver/images/spacer.gif) |
charly013
Anmeldungsdatum: 21.02.2023 Beiträge: 12 Wohnort: deutschland
|
Verfasst am: 15.03.2023, 11:17 Titel: |
|
|
moinmoin,
gibt es eigentlich sowas wie eine ISR? (interrupt) der zb. alle 100ms eine sub
ausfuehrt egal was das prg grand macht?
vG _________________ Fliegen Fliegen hinter Fliegen dann fliegen Fliegen Fliegen nach |
|
Nach oben |
|
![](templates/subSilver/images/spacer.gif) |
ThePuppetMaster
![](images/avatars/15203237124744b0302dc46.gif)
Anmeldungsdatum: 18.02.2007 Beiträge: 1837 Wohnort: [JN58JR]
|
Verfasst am: 15.03.2023, 11:57 Titel: |
|
|
In Freebasic kannst du soetwas mit Thread's realisieren.
Dazu empfehle ich Dir DRINGEND die folgenden Grundlagen-Tutorials:
Mutexe
Threading
und weiterführend:
Threading Optimierung - Teil 1 (Fehlerquellen)
Threading Optimierung - Teil 2 (Mutexabhängigkeiten)
Als Einstiegspunkt für dein ISR-Problem hierfür das folgende:
Code: |
Sub Quasi_ISR_Thread(V_Data as Any Ptr)
Dim TInterval as Integer = 1000 '1sec interval
Dim TTimeout as Double
Do
If TTimeout <= Timer() Then
'HIER KANN MAN ETWAS AUFRUFEN
TTimeout = Timer() + (TInterval / 1000)
End If
Sleep 10, 1
Loop
End Sub
|
MfG
TPM
55 & 73 _________________ [ WebFBC ][ OPS ][ ToOFlo ][ Wiemann.TV ]
Zuletzt bearbeitet von ThePuppetMaster am 21.03.2023, 00:02, insgesamt einmal bearbeitet |
|
Nach oben |
|
![](templates/subSilver/images/spacer.gif) |
charly013
Anmeldungsdatum: 21.02.2023 Beiträge: 12 Wohnort: deutschland
|
Verfasst am: 20.03.2023, 12:02 Titel: |
|
|
moinmoin nochmal
habe noch etwas weiter gemacht, habe mittlerweile eine Karte von
36000 * 18000 *8 dh. 0.01° / pixel so dass ich "gut" reimzoomen kann
hatt auch alles gut funktioniert, geladen in ca. 6s, nach einem rechner
neustart stuerzt das prg in folgender zeile ab:
Code: | v_bild001(v_x, (v_hoehe-v_y)) = v_fileinhalt[v_x + v_y2] |
lade ich eine bilddatei mit 18000 * 9000 * 8 funktioniert es
der Rechner ist ein i7-4790k mit 32Gb (12Gb sind frei)
was i nicht verstehehe das es vor dem "neustart" funktioniert hat
mit einer testausgabe hab ich festgestellt das der absturz am anfang
passiert und nicht nach dem er viele male durch die schleife ist,
kommentiere ich die zeile aus rennt er durch (verschiebt natuerlich
nix)
die kleine datei = 154 MB (162.001.078 Bytes)
die grosse datei = 617 MB (648.001.078 Bytes)
vG
nachtrag: i meine das array v_bild001 ist schuld denn ersetze ich die
obige zeile durch Code: | tmp2ui = v_fileinhalt[v_x + v_y2] |
funktioniert die schleife (tmp2ui = uinteger)
v_bild001 wird vor der scheife:
Code: | ReDim v_bild001(v_breite+1, v_hoehe+1) As UByte
|
nachtrag2: i vermute nach einigem testen das es eine grenze bei ca 640 Mb arbeitsspeicher gibt, kann das sein? _________________ Fliegen Fliegen hinter Fliegen dann fliegen Fliegen Fliegen nach |
|
Nach oben |
|
![](templates/subSilver/images/spacer.gif) |
nemored
![](images/avatars/18585278245ddb8b9d8710.png)
Anmeldungsdatum: 22.02.2007 Beiträge: 4604 Wohnort: ~/
|
Verfasst am: 20.03.2023, 15:42 Titel: |
|
|
Wenn du mit Arrays arbeitest und diese klaglos deklarieren konntest, steht dir der reservierte Speicher auch zur Verfügung - da kommt es dann nicht wegen Speicherproblemen zum Absturz. Allerdings darf auch nur innerhalb des reservierten Speicherbereichs zugegriffen werden. Erster Ansatzpunkt bei einem Absturz wäre, nachzurechnen, ob du dich wirklich innerhalb der Array-Grenzen bewegst. Das wäre mein erster Kandidat als potentieller Übeltäter.
Kompiliere doch vielleicht sicherheitlshalber mal mit der Compiler-Option -exx zur Kontrolle, ob es beim Ausführen zur Überschreitung der Speichergrenzen kommt. _________________ Deine Chance beträgt 1:1000. Also musst du folgendes tun: Vergiss die 1000 und konzentriere dich auf die 1. |
|
Nach oben |
|
![](templates/subSilver/images/spacer.gif) |
charly013
Anmeldungsdatum: 21.02.2023 Beiträge: 12 Wohnort: deutschland
|
Verfasst am: 20.03.2023, 19:50 Titel: |
|
|
beim 32bit compiler scheint es eine ~ 1Gb grenze zu geben.
hab mal eine "demo" prg erstellt:
Code: |
Screen 18
Color 14
Dim As UByte i
begin:
Print "start "
Dim As String k,kk
Dim ar1() As UInteger
If i = 1 Then
ReDim ar1(10000000,12) As UInteger
Else
ReDim ar1(10,12) As UInteger
EndIf
Dim st1 as String = Space(1024*1024*1024)
Dim st2 as String = Space(1024*1024*512)
Dim st3 as String = Space(1024*1024*256)
Dim st4 as String = Space(1024*1024*128)
Print "laenge ar1: ";Len(ar1)
Print "laenge st1: ";Len(st1)
Print "laenge st2: ";Len(st2)
Print "laenge st3: ";Len(st3)
Print "laenge st4: ";Len(st4)
Print" taste, .= end "
Do
k = InKey
Sleep 10
If k = "." Or k = Chr$(3) then
System 'End
End
EndIf
Loop Until k <> ""
If i > 0 Then i = 0: Else i = 1
GoTo begin
End
|
_________________ Fliegen Fliegen hinter Fliegen dann fliegen Fliegen Fliegen nach |
|
Nach oben |
|
![](templates/subSilver/images/spacer.gif) |
nemored
![](images/avatars/18585278245ddb8b9d8710.png)
Anmeldungsdatum: 22.02.2007 Beiträge: 4604 Wohnort: ~/
|
Verfasst am: 20.03.2023, 20:48 Titel: |
|
|
Zitat: | beim 32bit compiler scheint es eine ~ 1Gb grenze zu geben. |
Ich bin im Bereich der Speicherverwaltung kein Experte; meine Aussagen sind daher mit Vorsicht zu genießen. In einem 32-Bit-System sind jedoch alle Speicheradressen 32 Bit groß, was bedeutet, dass allein aus diesem Grund bereits eine Beschränkung von knapp über 4 GB besteht. Von diesen Adressen stehen natürlich nicht alle für das eigene Programm zur Verfügung, weshalb deine Grenze durchaus realistisch erscheint.
Was allerdings an meinem vorherigen Post nicht ganz richtig war: Ich bin von statischen Arrays ausgegangen, du verwendest jedoch dynamische. Bei einem statischen Array meckert der Compiler, wenn der reservierte Platz nicht reicht. Dynamische Arrays werden dagegen erst zur Laufzeit reserviert, und wenn du dann mehr reservieren willst, als zur Verfügung steht, wird (zur Laufzeit) abgebrochen.
Um meine Aussage daher nochmal zu konkretisieren: Wenn das DIM oder REDIM funktioniert, ohne dass das Programm abbricht, dann steht dir der reservierte Speicher auch zur Verfügung, und ein Array-Zugriff innerhalb der definierten Grenzen führt auch nicht zu einem Programmabbruch. Ein REDIM, das mehr Speicher belegt als verfügbar, wird aber zu einem Programmabbruch führen (runtime error 1: illegal function call). _________________ Deine Chance beträgt 1:1000. Also musst du folgendes tun: Vergiss die 1000 und konzentriere dich auf die 1. |
|
Nach oben |
|
![](templates/subSilver/images/spacer.gif) |
ThePuppetMaster
![](images/avatars/15203237124744b0302dc46.gif)
Anmeldungsdatum: 18.02.2007 Beiträge: 1837 Wohnort: [JN58JR]
|
Verfasst am: 20.03.2023, 23:55 Titel: |
|
|
@charly013
wenn ich dich richtig verstanden habe, dann schreibst du gerade ein Programm, das eine Karte mit Zoomfunktion umsetzt. Die Karte basiert auf einer recht großen Bild-Datei im BMP Format?!
Wenn dem so ist, dann könntest du (um Speicher zu spaaren) und ... eventuell ... das ganze auch beschleunigen, wenn du vieleicht mit der Datei selbst als "RAM" arbeitest.
Ich hoffe, dass das was ich jetzt schreibe, verständlich ist, aber ist leider nicht ganz easy zu erklären.
Also, Du nutzt zur Darstellung (höchstwarscheinlich) eine Funktion welche skalieren kann. Skalieren bedeutet, das man entweder Informationen Duppliziert, oder Informationen Ignoriert. Sprich, z.B. Pixel verdoppeln.
Dein aktuelles Verfahren wird wohl daraus beruhen, das du eine sehr großes Bild in einen einzelnen sehr großen Speicher laden möchtest und auf diesen Speicher heraus einen Skalierung und Darstellung ausführst.
Mein Vorschlag zur Optimierung wäre jetzt, das du entweder mit Speicherblöcke Arbeitest. Du erzeugst dazu am besten einen Linked-List mit z.B. 1000x1000Pixel Blöcke (und optional noch ein kleinen Array mit Meta-Informationen zur Linkedlist) und setzt diese anschliesend mit PUT #GFX zu deinem Bild zusammen (So wie das die Online-Kartendienste machen) .. Stichwort: Tiles.
Die Andere Option zur Optimierung wäre dann das Arbeiten mit der Datei selbst. Hier könntest du, Dank des BMP Dateiformates noch einige Andere Tricks anwenden, um massiv RAM zu spaaren. Das geht allerdings sehr zu lasten der >Darstellungs< Geschwindigkeit.
Ein erster Optimierungsschritt wäre, nicht die gesamte Datei in das RAM zu laden, sondern nur Teile davon. Welche Teile geladen werden, muss dynamisch berechnet werden. Und, wird jetzt auch etwas kompliziert. Hat aber den Vorteil, das es jetzt keine Größenbeschränkungen mehr gibt, was die Dateigröße des Bildes, bzw. auch des Bildes selbst, geben wird.
Punkt eins der Berechnung sieht vor, Tiles aus der Datei (oder mehreren Dateien) zu laden. Dazu berechnest du, welchen Abschnitt des Bildes du darstellen musst und welche Skalierung dieses Bild besitzen wird. Dank des BMP Formates, kannst du direkt aus der Datei den entsprechenden Ausschnitt saugen, ohne die Datei komplett lesen zu müssen. Es reicht der Header, um die Pixelpositionen in der Datei zu errechnen.
Punkt zwei sieht vor, das du auch die Skalierung beim laden berücksichtigst, indem du z.B. Pixel beim lesen schon überspringen kannst. Da diese später sowieso nicht dargestellt werden, kann man das Laden entsprechend einsparen.
Die beiden Punkte führen natürlich dazu, das die Frühere Optimierung der Ladegeschwindidkeit wieder verloren geht, wird aber gleich wieder Optimiert.
Der Letzte Punkt der Optimierung wäre die massive Verwendung von Thread's und Speicherblöcke.
Du erzeugst einen oder mehrere Threads, welche aus der Datei oder den Dateien die entsprechenden Blöcke ausliest und in Blöcke in das RAM bzw. die LL (Linked-List) schreibst. Wichtig, ist, das du noch vor der ersten Darstellung die LL Grundlegend inizialisierst, damit Sie quasi ein Schwarzes Bild darstellt. Diese Schwarzen Blöcke werden im Hintergrund, abhängig der Größe und Spakierung, vom Thread gefüllt, und beim nächsten Darstellungs-Durchlauf, gezeigt werden.
Was jetzt passiert ist, das du z.B. eine Ansicht in den RAM lädt, welche z.B. die gesamte Welt darstellt, jedoch ohne die Pixel, die eh nie dargestellt werden.
Zoomst du jetzt in die Karte herein, dann nutzt du die skalierungsfunktion der Grafikdarstellung und "verpixelst" die aktuelle Tile etwas. Es sieht quasi so aus, als wenn da Bild unscharf wäre. Im hintergrund gibst du jedoch den Threads den Befehl, eine andere Skalierung aus der Datei oder den Dateien heraus zu laden und die aktuelle Tile damit zu ersetzen. Das führt dazu, das du mit der Karte aktiv und schnell arbeiten kannst, ohne das du auf das Laden warten musst. Für den Nutzer ist es normalerweise auch garnicht so schlimm, wenn die Schärfe etwas verzögert dargestellt wird.
Ich hoffe, ich konnte es halbwegs verständlich erklären.
MfG
TPM
55 & 73 _________________ [ WebFBC ][ OPS ][ ToOFlo ][ Wiemann.TV ] |
|
Nach oben |
|
![](templates/subSilver/images/spacer.gif) |
|
|
Du kannst keine Beiträge in dieses Forum schreiben. Du kannst auf Beiträge in diesem Forum nicht antworten. Du kannst deine Beiträge in diesem Forum nicht bearbeiten. Du kannst deine Beiträge in diesem Forum nicht löschen. Du kannst an Umfragen in diesem Forum nicht mitmachen.
|
|