[VB.NET] Multithreading met GDI+

Pagina: 1
Acties:

Acties:
  • 0 Henk 'm!

  • Gimmeabrake
  • Registratie: December 2008
  • Laatst online: 21-09 16:52
Ik ben op dit moment mijn grafische rekenmachine aan het herschrijven. Nu ik de parser af heb, ben ik weer begonnen aan het plot-gedeelte. Aangezien ik vaak met meerdere (wiskundige)functies werk, kan ik dit prima multithreaded doen, dit zou als het goed is voor een aardige performance winst kunnen zorgen. Nu is de vraag alleen, wat is de meeste efficiente manier?

Het idee is dat ik een object/thread maak per functie. Nu is een voor de hand liggende aanpak om dit object een bitmap-object te laten vullen met een transparente achtergrond, om deze vervolgens te returnen naar de hoofdthread, die dan alle bitmaps over elkaar heen plakt. Ik weet echter uit ervaring dat juist dit overelkaar heen plakken veel resources vergt.

Een andere optie is om de threads de tekencoordinaten door te laten geven naar de hoofdthread. Dit zou per lijnstuk kunnen (500+ per functie) of in zijn geheel achteraf. Als ik ze een voor een doorgeef vraag ik me af of het firen van al die events niet ontzettend veel performance opeist. Als ik ze achteraf in een hap doorgeeft, vraag ik me af of er nog een performancewinst is aangezien de hoofdthread nu alsnog nog een keer door al die coordinaten heen moet gaan loopen.

Ik heb eigenlijk geen flauw idee welke aanpak het snelste is. Misschien dat een tweaker al eens met een soortgelijk probleem gekampt heeft en de oplossing kent? Of zal ik toch echt alledrie de versies moeten schrijven en benchmarken? 8)7

Acties:
  • 0 Henk 'm!

  • H!GHGuY
  • Registratie: December 2002
  • Niet online

H!GHGuY

Try and take over the world...

In veel gevallen zal het tekenen van de lijnstukken/punten langer duren dan het uitrekenen ervan. Door die laatste op te splitsen zal je dus weinig winst boeken.

Ik heb om een algoritme te demonstreren voor mijn thesis ook een eenvoudige applicatie geschreven die punten tekende. Ik heb het aantal punten dat getekend werd moeten cappen of anders duurde dat gewoon te lang. Mijn algoritme daarentegen draaide uiterst snel in vergelijking.
Het was trouwens een O(n) benadering voor het zoeken van de 2 punten uit een set die het verst uiteen liggen. Ik kan enkele miljoenen punten in een zeer betrekkelijke tijd verwerken, maar het tekenen was uiterst traag.

Ik weet niet welke aanpak je nu volgt, maar ik zou ervoor zorgen dat je uit de grootte/resolutie van je canvas bepaalt welke x-coordinaten getekend moeten worden en zodoende enkel die tekenen. Aangezien je een rekenmachine emuleert (ik vermoed een TI-83 of equivalent) zal je helemaal niet moeten optimaliseren om een veel sneller iets te hebben. (Besides: microsoft heeft zelf een gratis tool waarmee je functies kan tekenen)

[ Voor 24% gewijzigd door H!GHGuY op 13-04-2009 07:47 ]

ASSUME makes an ASS out of U and ME


Acties:
  • 0 Henk 'm!

  • Gimmeabrake
  • Registratie: December 2008
  • Laatst online: 21-09 16:52
Ik emuleer geen enkel rekenmachine, hoewel ik qua features wel de TI-83/84 in mijn achterhoofd heb. De vorige versie van dit programma die single-threaded werkte kon een grote hoeveelheid functies al in een fractie van een seconde plotten, het is dus geen must om het multi-threaded te doen, meer een soort drang van mezelf om ten eerste elk klein beetje performance eruit te halen, en ten tweede om eens met threading aan de slag gegaan(ik heb het nog nooit in de praktijk gebruikt). Overigens zal zelfs een kleine performancewinst goed merkbaar zijn in mijn programma.

Mijn programma kijkt sowieso al naar de breedte van de bitmap die het moet uitvoeren en tekent/berekent inderdaad alleen de hoeveelheid lijnen die nodig zijn om het in dat formaat mooi uit te laten zien.
H!GHGuY schreef op maandag 13 april 2009 @ 07:44:
In veel gevallen zal het tekenen van de lijnstukken/punten langer duren dan het uitrekenen ervan. Door die laatste op te splitsen zal je dus weinig winst boeken.
Jij denkt dus dat ik ook het tekenen beter kan laten doen door de threads. Ik ga nu even een code schrijven om het eens te testen.

Acties:
  • 0 Henk 'm!

  • H!GHGuY
  • Registratie: December 2002
  • Niet online

H!GHGuY

Try and take over the world...

gerrymeistah schreef op maandag 13 april 2009 @ 10:22:
Jij denkt dus dat ik ook het tekenen beter kan laten doen door de threads. Ik ga nu even een code schrijven om het eens te testen.
Mocht ik jou zijn, ik zou eerst eens kijken of het aansturen vanuit meerdere threads kan. Voor zover ik weet gaat dit niet. Zelfs al moest het kunnen, zal je waarschijnlijk door lock contention weinig winst boeken.

ASSUME makes an ASS out of U and ME


Acties:
  • 0 Henk 'm!

  • Gimmeabrake
  • Registratie: December 2008
  • Laatst online: 21-09 16:52
H!GHGuY schreef op maandag 13 april 2009 @ 16:22:
[...]


Mocht ik jou zijn, ik zou eerst eens kijken of het aansturen vanuit meerdere threads kan. Voor zover ik weet gaat dit niet. Zelfs al moest het kunnen, zal je waarschijnlijk door lock contention weinig winst boeken.
Ik heb het op dit moment al bijna werkend. De threads genereren bitmaps met transparante achtergrond, de hoofd-thread plakt die op elkaar. Bij enkele functies zal deze methode eventueel iets(niet hinderlijk) langzamer zijn, bij een grote hoeveelheid functies zal het als het goed is daarentegen een grote performancewinst opleveren. Ik denk dat ik vanavond nog een benchmark kan maken tussen de single en multi-threaded versie, dat zal ik dan natuurlijk ook hier even posten.

Acties:
  • 0 Henk 'm!

  • _js_
  • Registratie: Oktober 2002
  • Laatst online: 18-08 21:31
Als het bitmap plakken langzaam is zou je er over na kunnen denken om dat zelf te doen. Je zult waarschijnlijk geen alpha levels gebruiken e.d., dus dat kan redelijk simpel. Als je tekent op een zwarte achtergrond doe je voor elke pixel van het ene plaatje een binaire or met de corresponderende pixel van het andere plaatje, als je op een witte achtergrond tekent, dan beide pixels eerst met not behandelen, dan or, dan het resultaat weer not.
Pagina: 1