Das deutsche QBasic- und FreeBASIC-Forum Foren-Übersicht Das deutsche QBasic- und FreeBASIC-Forum
Für euch erreichbar unter qb-forum.de, fb-forum.de und freebasic-forum.de!
 
FAQFAQ   SuchenSuchen   MitgliederlisteMitgliederliste   BenutzergruppenBenutzergruppen  RegistrierenRegistrieren
ProfilProfil   Einloggen, um private Nachrichten zu lesenEinloggen, um private Nachrichten zu lesen   LoginLogin
Zur Begleitseite des Forums / Chat / Impressum
Aktueller Forenpartner:

bmp laden sehr langsam, was tun?
Gehe zu Seite 1, 2  Weiter
 
Neues Thema eröffnen   Neue Antwort erstellen    Das deutsche QBasic- und FreeBASIC-Forum Foren-Übersicht -> Allgemeine Fragen zu FreeBASIC.
Vorheriges Thema anzeigen :: Nächstes Thema anzeigen  
Autor Nachricht
charly013



Anmeldungsdatum: 21.02.2023
Beiträge: 12
Wohnort: deutschland

BeitragVerfasst am: 08.03.2023, 10:31    Titel: bmp laden sehr langsam, was tun? Antworten mit Zitat

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
Benutzer-Profile anzeigen Private Nachricht senden
ThePuppetMaster



Anmeldungsdatum: 18.02.2007
Beiträge: 1837
Wohnort: [JN58JR]

BeitragVerfasst am: 08.03.2023, 13:13    Titel: Antworten mit Zitat

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
Benutzer-Profile anzeigen Private Nachricht senden
charly013



Anmeldungsdatum: 21.02.2023
Beiträge: 12
Wohnort: deutschland

BeitragVerfasst am: 08.03.2023, 14:09    Titel: Antworten mit Zitat

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
Benutzer-Profile anzeigen Private Nachricht senden
ThePuppetMaster



Anmeldungsdatum: 18.02.2007
Beiträge: 1837
Wohnort: [JN58JR]

BeitragVerfasst am: 08.03.2023, 14:27    Titel: Antworten mit Zitat

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
Benutzer-Profile anzeigen Private Nachricht senden
charly013



Anmeldungsdatum: 21.02.2023
Beiträge: 12
Wohnort: deutschland

BeitragVerfasst am: 09.03.2023, 18:53    Titel: Antworten mit Zitat

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
Benutzer-Profile anzeigen Private Nachricht senden
ThePuppetMaster



Anmeldungsdatum: 18.02.2007
Beiträge: 1837
Wohnort: [JN58JR]

BeitragVerfasst am: 09.03.2023, 21:58    Titel: Antworten mit Zitat

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
Benutzer-Profile anzeigen Private Nachricht senden
ThePuppetMaster



Anmeldungsdatum: 18.02.2007
Beiträge: 1837
Wohnort: [JN58JR]

BeitragVerfasst am: 09.03.2023, 22:06    Titel: Antworten mit Zitat

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
Benutzer-Profile anzeigen Private Nachricht senden
charly013



Anmeldungsdatum: 21.02.2023
Beiträge: 12
Wohnort: deutschland

BeitragVerfasst am: 10.03.2023, 07:41    Titel: Antworten mit Zitat

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
Benutzer-Profile anzeigen Private Nachricht senden
ThePuppetMaster



Anmeldungsdatum: 18.02.2007
Beiträge: 1837
Wohnort: [JN58JR]

BeitragVerfasst am: 10.03.2023, 08:54    Titel: Antworten mit Zitat

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
Benutzer-Profile anzeigen Private Nachricht senden
charly013



Anmeldungsdatum: 21.02.2023
Beiträge: 12
Wohnort: deutschland

BeitragVerfasst am: 12.03.2023, 08:21    Titel: Antworten mit Zitat

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
Benutzer-Profile anzeigen Private Nachricht senden
nemored



Anmeldungsdatum: 22.02.2007
Beiträge: 4594
Wohnort: ~/

BeitragVerfasst am: 12.03.2023, 10:39    Titel: Antworten mit Zitat

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
Benutzer-Profile anzeigen Private Nachricht senden
ThePuppetMaster



Anmeldungsdatum: 18.02.2007
Beiträge: 1837
Wohnort: [JN58JR]

BeitragVerfasst am: 12.03.2023, 10:44    Titel: Antworten mit Zitat

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, 13:14, insgesamt einmal bearbeitet
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
charly013



Anmeldungsdatum: 21.02.2023
Beiträge: 12
Wohnort: deutschland

BeitragVerfasst am: 12.03.2023, 14:21    Titel: Antworten mit Zitat

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 lachen )
_________________
Fliegen Fliegen hinter Fliegen dann fliegen Fliegen Fliegen nach
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
charly013



Anmeldungsdatum: 21.02.2023
Beiträge: 12
Wohnort: deutschland

BeitragVerfasst am: 15.03.2023, 10:17    Titel: Antworten mit Zitat

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
Benutzer-Profile anzeigen Private Nachricht senden
ThePuppetMaster



Anmeldungsdatum: 18.02.2007
Beiträge: 1837
Wohnort: [JN58JR]

BeitragVerfasst am: 15.03.2023, 10:57    Titel: Antworten mit Zitat

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 20.03.2023, 23:02, insgesamt einmal bearbeitet
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
charly013



Anmeldungsdatum: 21.02.2023
Beiträge: 12
Wohnort: deutschland

BeitragVerfasst am: 20.03.2023, 11:02    Titel: Antworten mit Zitat

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
Benutzer-Profile anzeigen Private Nachricht senden
nemored



Anmeldungsdatum: 22.02.2007
Beiträge: 4594
Wohnort: ~/

BeitragVerfasst am: 20.03.2023, 14:42    Titel: Antworten mit Zitat

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
Benutzer-Profile anzeigen Private Nachricht senden
charly013



Anmeldungsdatum: 21.02.2023
Beiträge: 12
Wohnort: deutschland

BeitragVerfasst am: 20.03.2023, 18:50    Titel: Antworten mit Zitat

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
Benutzer-Profile anzeigen Private Nachricht senden
nemored



Anmeldungsdatum: 22.02.2007
Beiträge: 4594
Wohnort: ~/

BeitragVerfasst am: 20.03.2023, 19:48    Titel: Antworten mit Zitat

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
Benutzer-Profile anzeigen Private Nachricht senden
ThePuppetMaster



Anmeldungsdatum: 18.02.2007
Beiträge: 1837
Wohnort: [JN58JR]

BeitragVerfasst am: 20.03.2023, 22:55    Titel: Antworten mit Zitat

@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
Benutzer-Profile anzeigen Private Nachricht senden
Beiträge der letzten Zeit anzeigen:   
Neues Thema eröffnen   Neue Antwort erstellen    Das deutsche QBasic- und FreeBASIC-Forum Foren-Übersicht -> Allgemeine Fragen zu FreeBASIC. Alle Zeiten sind GMT + 1 Stunde
Gehe zu Seite 1, 2  Weiter
Seite 1 von 2

 
Gehe zu:  
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.

 Impressum :: Datenschutz