Results 1 to 6 of 6

Thread: to thread or not to trhead

  1. #1
    Registered User
    Join Date
    Nov 2021
    Location
    Noord-Hooland
    Posts
    7

    to thread or not to trhead

    Beste forumleden,

    ik ben een programma aan het schrijven waarmee ik raw-images kan tonen. De foto's zijn afkomstig van Canon, Nikon en Sony camera's. Ik open daartoe de foto, lees de offset en grootte van de embedded jpg en kopieer deze data naar
    een memorystream. Op het form "pleeg" ik dan een Image1.LoadFromStream(ms).
    Dit werkt perfect en elke nef, cr2 of arw foto wordt getoond (voor jpg gebruik ik Image1.LoadFromFile(sJpg).

    Ik lees de folder, creeer voor elke foto een Image en voeg deze toe aan een scrollbox. Op die manier zie ik als het ware een soort van filmstrip met daarin alle foto's uit die folder. Ook dit werkt perfect, echter....
    het is ontzettend traag. Ik snap dat het lezen van de offset en het maken van een image en deze toevoegen aan de scrollbox, tijd kost (ca. 2 seconden), maar bij meer dan 100 foto's in een folder, duurt dat wel erg lang.
    Nu is mijn vraag: zou een thread hier oplossing kunnen bieden? De foto's worden toegevoegd aan de scrollbox in een buttonclick.
    Ik zou natuurlijk gedurende het laden een boodschap kunnen tonen ("Ten (10) moments please") en het form verder disablen zodat de gebruikers niet gaan lopen klikken. Alternatief zou zijn dat ik steeds maar een gedeelte in de scrollbox laad, maar
    hoe pak ik dat aan? Is de scrollbox hiervoor wel het geëigende component?

    Hoe denken jullie hierover?

    Groetjes van Tinus.

  2. #2
    mov rax,marcov; push rax marcov's Avatar
    Join Date
    Apr 2004
    Location
    Ehv, Nl
    Posts
    10,357
    Ik heb een dergelijk probleem in mijn beeld verwerkende apps opgelost. In essentie je probleem bestaat uit 4 delen:
    1. Het scannen van de directory (alleen bij meer dan (tien) duizenden files in de dir en meer). Dit kan tergend traag worden, hou een aparte index bij.
    2. Het laden van de data van disk (b.v. naar tmemorystream)
    3. Het converteren van het disk-formaat naar een geheugen bitmap (o.a. de zlib decompressie die in png/jpg kan zitten)
    4. Het eigenlijke tonen en schalen van het beeld (stretchdraw en aanverwanten) kan ook tijd kosten


    Ik denk dat jouw probleem primair in 3 zit, en een beetje punt 2 (het in dezelfde core als dat je decompressie doet wachten op disk I/O is ook vertragend)

    Deze kan je in (meerdere?) aparte threads onderbrengen, dat geeft je in feite multi core decompressie.

    Vuistregel 2x zoveel threads als je fysieke cores hebt, de helft ervan laden beelden van disk, de tweede helft doen de memorystream naar timage/bitmap conversie incl decompressie en posten het resultaat naar de mainthread. Alleen deze laatsten vreten veel CPU, vandaar de aanrader meer threads dan fysieke cores op te starten.

    Is het dan nog te traag, en zit het ook in het laatste punt, dan begin je met niet ieder binnenkomend beeld te updaten, maar iedere <x> beelden.

    Nog verder gaan met het laatste punt wordt lastiger en heb ik middels Opengl opgelost, maar dat is gecompliceerd. Echter nieuwere Delphi's hebben een of andere directdraw widget, misschien kan je daar eens naar kijken.

  3. #3
    Alternatief zou zijn dat ik steeds maar een gedeelte in de scrollbox laad,
    Dat zou ik zeker doen, anders loop je na een paarhonderd foto's uit je geheugen.

    Wellicht kan je wel relatief snel de bestanden lezen en in volgorde zetten, en er al de (geschaalde) grootte van bepalen door die uit te lezen uit de meta-informatie van de afbeelding. Op die manier kan je je scrollbox al de juiste grootte geven. Scrollt iemand naar een bepaalde positie, dan kan je de afbeeldingen op die positie laten. Je kan dan ook weer afbeeldingen weggooien uit het geheugen als je gebruiker ergens anders heen scrollt, want met honderden afbeeldingen zal je sowieso wel de grenzen van je geheugen testen.

    Maar ook als je wel alle foto's laadt, dan is het nog steeds handig om dat in een thread (of meerdere) te doen, zoals marcov beschrijft. Ik zou zelf denk ik 1 thread gebruiken voor het lezen van disk, maar dat is omdat ik het gevoel heb dat het toch niet sneller maar eerder trager wordt van meerdere threads. Maar misschien stamt dat nog uit de tijd van de spinning disks.
    1+1=b

  4. #4
    mov rax,marcov; push rax marcov's Avatar
    Join Date
    Apr 2004
    Location
    Ehv, Nl
    Posts
    10,357
    Goleztrol: mijn analyse is een beetje fundamenteel om de verschillende onderdelen te onderscheiden. Het is overigens op harddisks gebaseerd icm 2 core systemen (*), maar denk eraan dat met grote files lezen waarschijnlijk vrij lineair is, en dan kan je zelfs met een HDD wel honderd+ MB laden per seconde, en meer voor striped systemen. En dat moet dan ook even gedecomprimeerd worden.

    Als je mikt op een 4 core, dan denk ik dat 3 of 4 threads on te laden+decompressie genoeg is, en het niet nodig is dat te scheiden.

    Ik gebruik dezelfde engine voor meerdere dingen, dus dingen die alle beelden verwerken, maar ook b.v. voor het laden van de beelden in de gui, typisch laad ik het aantal beelden in de view, en de volgende. (dus als er selectie is uit 8 beelden laadt ik die en de volgende 8)

    (*) de laatste jaren hebben we meer meetapparatuur dan uitstoot machines gemaakt, met minder beeldopslag dus, dus statistieken zijn wat minder up to date.

  5. #5
    Silly member NGLN's Avatar
    Join Date
    Aug 2004
    Location
    Werkendam
    Posts
    5,133
    Voor een voorbeeldje van een dergelijk control/component incl. background thread, zie Looking for a custom image grid op StackOverflow.
    (Sender as TNLDUser).Signature := 'Groeten van Albert';

  6. #6
    Registered User
    Join Date
    Nov 2021
    Location
    Noord-Hooland
    Posts
    7
    Quote Originally Posted by NGLN View Post
    Voor een voorbeeldje van een dergelijk control/component incl. background thread, zie Looking for a custom image grid op StackOverflow.
    Dank allen. Ik ga de voorbeelden/tips verder uitwerken.
    Ik heb nu een aantal zaken geregeld:

    1. Alle files (jpg, nef, cr2 en arw) in een bepaalde folder staan nu in een stringlist
    2. Al deze files hebben een TBitmap equivalent in een Imagelist (opbouw zeer "traag". Welliswaar zonder thread maar 100 files opnemen in de imagelist duurt ca. 3.5 minuut).
    3. De scroll box heb ik laten varen wegens geheugen-gebrek en toon ze nu in een TListview. Dit werkt wel, maar is ook redelijk traag.

    Wat is volgens jullie het beste component om een (lange) lijst van bitmaps te tonen, met een beetje acceptabele snelheid?
    Ik wil graag een soort van "filmstrip" tonen met daarin alle foto's (jpg en raw) uit een bepaalde folder.

    Groeten van Tinus

Thread Information

Users Browsing this Thread

There are currently 1 users browsing this thread. (0 members and 1 guests)

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •