Grafische Engine
Wat met anti-aliasing?
Geen heap memory allocatie tijdens de hertekeningscyclus!
Drijvende komma representaties
Browser Uitbreiding Technologieën
Drijvende Komma's vs. Dubbels
De Jmol grafische engine is geheel geschreven in Java.
Er is geen Java3D, OpenGL of enig ander type van hardware acceleratie.
De grafische engine is een grafische engine, speciaal gebouwd voor deze applicatie,
het is geen algemene 3D grafische bibliotheek.
De rendering engine werd gebouwd speciaal voor het weergeven van moleculen,
zodus levert de software goed resultaat in het tekenen van cirkels en cylinders.
Het is een complete software implementatie van een z-buffer.
Er is een int[] pixelBuffer die ARGB waarden opslaat en een short[] zBuffer
die de pixel diepte opslaat.
Tijdens de herteken cyclus wordt de gehele scene getekend in de pixelBuffer.
Dan wordt de gehele scene getekend als één afbeelding met een enkele
Graphics.drawImage(...) bewerking.
Het gebruikt geen weergavelijst van driehoeken. Dit zou te traag zijn.
In de plaats daarvan, worden geoptimaliseerde routines voor het tekenen
van cirkels en cylinders gebruikt.
Indien je een mogelijkheid ziet om de rendering snelheid te verbeteren,
laat het ons dan weten!
Anti-aliasing is momenteel niet beschikbaar in Jmol.
De meeste mechanismen zijn aanwezig, maar het is momenteel uitgeschakeld.
Het werd uitgeschakeld, omdat er prestatieproblemen zijn bij oudere hardware.
We zijn van plan om de implementatie te vervolledigen en alles terug te
activeren bij een volgende uitgave van de software...
als we de tijd hebben om uit te vinden hoe het kan ingeschakeld worden voor oudere machines.
De Jmol Graphics3D engine is geheel in software ingewerkt.
Het kan de onderliggende 'Sun 2D graphics calls' niet gebruiken omdat deze
geen zBuffer biedt, zodat de software niet kan op een pixel-bij-pixel
basis kan beslissen of er al dan niet een pixel moet worden getekend.
De anti-aliasing techniek die wordt gebruikt in de Jmol Graphics3D engine
heet de 'full-scene-anti-aliasing'. De complete scene wordt getekend in een
buffer die tweemaal zo breed en tweemaal zo hoog is. Daarna worden 4 pixels
omgezet in 1 pixel, met toepasselijke vermenging van RGB (Rood/Groen/Blauw) waarden.
Het eindresultaat houdt in dat er meer geheugen vereist is om alles in de zBuffer
en pixelBuffer te bewaren. Het neem ook nog eens veel meer klokcycli in beslag om een
scene te tekenen. Het tekengedeelte neemt 4 keer zoveel tijd in beslag. In het geheel
neemt het ongeveer 3 keer zoveel tijd in beslag om een gehele scene te tekenen. (renderen)
Bij recente computers met veel CPU kracht vormt dit geen probleem.
Bij oudere computers zou dit onaanvaardbaar traag verlopen.
Daarom worden er opties ingebouwd.
Jmol voert geen heap memory allocatie uit tijdens de hertekeningscyclus!
Omwille van prestatieredenen is het voor ons belangrijk om deze richtlijn te blijven volgen.
[Dave heeft een schets van deze memo gelezen en gaf zijn toestemming om zijn
code te gebruiken als een voorbeeld]
Na een klein stukje van Dave's recente code te bekijken voor Ribbons/Mesh,
zag ik iets dat een discussie waard is.
Om eerlijk te zijn, Dave heeft zeer goede code geschreven. Maar met een kleine
wijzigingen kunnen we ervoor zorgen dat we optimale prestatie kunnen behouden.
Ik ga deze code dan ook gebruiken als een voorbeeld om de alertheid te verhogen
wat betreft geheugenallocatie problemen in Jmol.
Om Ribbons te tekenen had Dave 2 arrays van Point3i objecten nodig om de
schermcoördinaten te kunnen bewaren van de hoeken van de 'ribbons'.
Hij wijst de arrays toe en vult ze op met nieuwe Point3i objecten.
Daarna volgt een berekening, de dingen worden uitgetekend, en mooi ogende
ribbons verschijnen op het scherm.
Daarna worden de tijdelijke objecten weggegooid. Hier ontstaat er een klein probleem:
tijdelijke opjecten die we toewijzen en weggooien tijdens de herteken-cyclus.
Waarom vormt dit een probleem?
Herteken-cycli gebeuren vrij snel ... hopelijk 30 keer per seconde tijdens rotaties.
Als we objecten toewijzen buiten de heap [door nieuwe SomeObject(...) parameters te gebruiken],
eindigen we met een snelle toewijzing van vele objecten.
Maar het probleem doet zich niet voor bij de toewijzing. Het probleem ontstaat bij het ongedaan
maken van de toewijzing. We verwerpen onmiddellijk de objecten. Deze verwerping van objecten
plaatst een overbodige last op de 'Java garbage collector', die doorheen het geheugen moeten
zoeken naar te dumpen datastructuren.
Als deze 'garbage collector' draait kan het soms pauzes genereren, waardoor er 'schokken'
onstaan in de respons van het systeem ... geen goed idee.
Daarom moeten we dit aanpakken door zoveel mogelijk objecten in het geheugen te 'recycleren'
tijdens de hertekencyclus.
We kunnen dit bereiken door de tijdelijke objecten te koppelen met instanties
van de Renderer klassen. We kunnen de Renderer instanties vragen om de tijdelijke
objecten voor ons toe te wijzen en/of te bewaren, en we kunnen op deze manier dezelfde
tijdelijke objecten hergebruiken doorheen de hertekencyclus.
Er zijn andere delen van het susteem waar deze techniek niet van toepassing is.
Bijvoorbeeld, bij IO operaties zijn we vrij om alles toe te wijzen of weg te gooien
alsof het rommel is. Tijdens IO wordt er veel tekst ontleed. Deze ontleding creërt vele
tijdelijke strings die een zeer korte levensduur hebben. Maar dit vormt geen probleem
aangezien we geen bestanden veelvuldig lezen omdat dit een vrij trage handeling vormt.
Iemand duidde ons op de volgende situatie die wel eens interessant zou kunnen zijn.
Bij de weergave van kristalcel-parameters:
> worden de a, b, c, enz. waarden weergegeven met een 'extra' decimaal
> plaatst de 10pre8 applet a=10.436999 terwijl de
> CRYST1 record van het pdb bestand een waarde van 10.437 geeft. Dit betekent
> dat er zich een afrondingsfout bij het berekenen van de celcoördinaten voordoet.
Eigenlijk is deze situatie vrij subtiel. Het was niet echt een afrondingsprobleem,
omdat er geen berekeningen werden uitgevoerd op de nummers.
Maar toch zou dit een probleem kunnen vormen. De bron van dit probleem belangt
iedereen aan die werken met drijvende komma nummers.
We zijn het gewoon om in paren van 10 te werken ... 10 vingers. Maar van tijd tot tijd komen
we langs rationele nummers die we niet kunnen weergeven in paren van 10. De beste voorbeelden
hiervan vormen de breuken 1/3 en 2/3. We schrijven ze als 0.33 of 0.67, of breiden ze uit met
een aantal extra cijfers (0.33333, 0.66667) indien we een hogere accuraatheid verwachten in de
berekening.
We zijn op ditzelfde probleem gestoten in de computerwereld. Mensen hebben lang geworsteld om
manieren te vindne om dit in rekening te brengen, sinds het begin van de opkomst van de
digitale computer.
De meeste computers gebruiken een drijvende komma representatie, gedefinieerd door de
IEEE standaarden organisatie, omstreeks 1985:
IEEE Std 754-1985
IEEE Standard for Binary Floating-Point Arithmetic
Dit is een 'base 2' (binaire - paren van 2) representatie van drijvende komma nummers,
geen 'base 10' (paren van 10) representatie. Dit betekent dat er een verschillende set
van rationele nummers bestaat die niet precies kan worden weergegeven.
In dit geval werden er geen berekeningen uitgevoerd op het cijfer 10.437 ... het werd meteen
uit het bestand gelezen. Maar het nummer 10.437 kan echter niet correct worden weergegeven
in binair formaat ... dus eindigen we met 10.436999 (ik heb dit niet gecontroleerd, maar
ik veronderstel dat het juist is).
Andere punten:
-
COBOL ondersteunde decimale en vaste-punt nummers om deze situatie op te vangen om te
kunnen omgaan met dollars en dollarcenten in een professionele omgeving
-
een van de representaties bij IBM mainframes was base 16. (in plaats van base 2)
Terwijl dit deze situatie niet behandelde, zorgde dit wel voor een aanzienlijke
prestatieverbetering (tijdens de 'normalisatie' procedure)
-
Mensen die hoge prestaties willen volgen de IEEE standaarden niet.
-
De eerste Java Virtual Machine specificatie *vereiste* IEEE representatie
(en operationeel gedrag) voor drijvende komma nummers. Dit (zou) overdraagbaarheid
naar andere platformen garanderen ... dezelfde berekening zou hetzelfde antwoord
geven op verschillende systemen. Deze vereiste is ondertussen wat afgezwakt ...
om hogere prestatie berekeningen toe te laten ... en omdat men moest toegeven dat het
een onoplosbaar probleem was.
-
Ik denk dat de meeste mensen ermee instemmen dat de IEEE standaarden problemen hebben,
maar mensen moeten die nu eenmaal volgen
-
Systemen voor symbolische/pure mathematica (Mathematica, MATLAB, Macsyma) ondersteunen
rationele nummers (fractionele representatie van integers ... 1/3, 2/3) om te proberen
dit type van problemen voor rationle nummers te vermijden.
Ik zal proberen een korte samenvatting te geven van 4 verschillende technieken die kunnen
worden gebruikt om functionaliteit toe te voegen aan de browser. Het is belangrijk dat
de correcte terminologie wordt gebruikt om verwarring te vermijden.
In rangschikking van eenvoudigste tot meest complexe:
Helper Applicatie
Een helper applicatie is een applicatie die automatisch start wanneer de browser een bestand
ontvangt waarmee het niet weet wat ermee aan te vangen. Het bestandstype wordt geïdentificeerd
door de 'MIME-type'.
We geven een voorbeeld, waarbij we gebruik maken van een nieuwe installatie van Netscape/Mozilla.
(Netscape/Mozilla, omdat Internet Explorer 'speciale' ondersteuning heeft voor andere MS producten).
De eerste keer dat Mozilla een .doc bestand met mime-type 'application/msword' ontvangt,
weet het niet wat het ermee moet aanvangen. De browser weet dat het bestaan geen type
'text/html' of 'image/jpeg' is, dus het weet niet hoe het dit bestandstype moet behandelen.
Daarom vraagt Mozilla aan de gebruiker wat ermee moet gebeuren - opslaan naar een bestand
of opstarten vanaf een applicatie. Als de gebruiker kiest voor de applicatie dan kan de
gebruiker kiezen of dit type steeds met deze applicatie moet worden opgestart.
Elke browser heeft zo'n tabel met 'associaties' tussen mime-types en applicaties ...
hoewel Safari's tabel wel zeer goed verborgen is.
Een helper applicatie kan een applicatie zijn ... dus ook de Jmol applicatie.
Wil dit echter probleemloos werken, dan moet de webserver juist geconfigureerd zijn
zodat ze de juiste mime-type versturen. Dit vormt meestal geen probleem bij grote applicaties.
Het vormt echter wel een probleem bij minder bekende bestandstypes en bij webservers waarvan
de systeembeheerders weinig ervaring hebben ... wat meestal het geval is bij mensen die
proberen Chime webapplicaties te bouwen en beheren.
Onbetrouwbare (or niet gesigneerde) Applets
Dit is een Java Applet, ingebed in een webpagina. De meeste onbetrouwbare applets zijn vrij
klein en kunnen snel afgehaald worden. De gebruiker merkt ze vaak nooit op. Dit zijn kleine
menusystemen, spelletjes, enz.
Dit type van applet is 'onbetrouwbaar' in die zin dat het van een webserver op een
willekeurige plaats op het web vandaan kwam. Daarom vertrouwen we het niet helemaal.
Onbetrouwbare applets worden daarom in een hechte beveiligingsbox geplaatst (quarantaine).
Deze applets kunnen geen schrijf of leesbewerkingen doen naar de lokale harde schijf en ze
kunnen enkel communiceren met de webserver waarop ze zich bevinden. Indien ze toch
proberen een illegale handeling uit te voeren, wordt dit meteen geblokkeerd.
De JmolApplet is een onbetrouwbare applet ... groter en complexer dan de meeste onbetrouwbare applets.
Betrouwbare (of getekende) Applet
De beveiligingsrestricties bij een onbetroubare applet zijn verregaand. Mensen willen
webapplicaties ontwikkelen die mooie dingen kunnen doen, zoals bijvoorbeeld bestanden
opslaan op de lokale harde schijf.
Vooraleer dit type van applet uitgevoerd wordt vraagt de browser expliciet om permissie voor
het uitvoeren van de applet. Door op ja te klikken geeft de gebruiker permissie aan de software
om geïnstalleerd te worden op de lokale harde schijf.
Om alle leden te beschermen wordt een Trusted Applet *gesigneerd* met een digitale handtekening,
samen met encryptie. De encryptie verzekert dat de applet code niet werd gewijzigd door een
derde partij.
Een 'certificeringsauthoriteit' is een organisatie die je betrouwt om de verificatie uit
te voeren ... iets zoals het Better Business Bureau.
Vandaag bestaat er geen 'getekende' JmolApplet. In de toekomst stap ik naar een
'certificeringsauthoriteit' en bewijs ik aan hen dat ik een lid ben van het Jmol project.
Zij geven mij dan een digitale sleutelset. Ik gebruikt deze set dan om een
SignedJmolApplet te creëren.
Wanneer een gebruiker naar een website gaat waarop deze SignedJmolApplet staat,
zullen zij gevraagd worden of zijn deze applet kunnen vertrouwen. Zij zullen dan 'ja'
klikken en de sessie gaat verder.
De SignedJmolApplet dat wordt geïnstalleerd op de harde schijf kan nu bestanden
lezen/schrijven op de harde schijf. Het kan ook data lezen/schrijven van/naar locaties op het web.
Dit geeft de SignedJmolApplet een hoop ruimte om nieuwe dingen te doen ... zoals het lezen
van locale moleculaire model bestanden ... of zal bestanden onmiddellijk van databanken
ergens op het web kunnen inladen.
Onthoudt echter dat deze SignedJmolApplet nog steeds een applet is dat enkel
bestaat in de context van een specifieke website. Het is geen op zich staande applicatie
die op elk moment kan opgestart worden.
Een gebruiker kan het niet uitvoeren, tenzij het een onderdeel vormt van een website
waar ze toegang toe hebben. Echter, dit kan onder andere enkel via een website opgeslagen
op een CD-ROM of ergens op het lokale bestandssysteem.
In de toekomst hopen we een SignedJmolApplet te hebben. Toch willen we de ongesigneerde
JmolApplet behouden voor mensen die simpelere websites willen bouwen die geen expliciete
permissie vragen om naar de lokale harde schijf te schrijven.
Ik zou graag zien dat de ongetekende JmolApplet nog 'sluw en gemeen' blijft ...
met gelimiteerde functionaliteit ... maar goede ondersteuning om enkel de moleculen
te tonen aan beginnende studenten en bezoekers.
De SignedJmolApplet zal er voor serieuze gebruikers zijn die een serieuse functionaliteit verwachten.
Plug-in
Om een plug-in te begrijpen is het handig om terug te denken aan de helper applicatie.
Een helper application is niet geassocieerd met een specifieke website. Het is eerder
geassocieerd met een specifiek bestandstype, een specifieke mime-type. De browser start
MS-Word elke keer dat het een document ziet met de mime-type 'application/msword'.
Een plug-in functioneert in een soortgelijke manier. Maar de weergave van de data is
ingebed in het browser venster. Het is software dat de mogelijkheden van de browser
zelf uitbreidt. Het speelt geen rol waar het bestand vandaan komt. Wanneer de browser een
onbekende mime-type ziet, kan het z'n lijst van ge�nstalleerde plug-ins controleren en zien
of het dit bestand aankan.
Twee populaire voorbeelden zijn Flash en Acrobat Reader. Mensen installeren deze vaak
eenmaal en maken er zich daarna nooit meer zorgen om.
Eens een plug-in geïnstalleerd kan het doen wat het maar wil ... zoals een stuk
geïinstalleerde software.
Het ontwikkelen en onderhouden van plug-ins is zeer duur en tijdrovend. Hoewel Netscape
een plug-in API bezit, blijft het dynamisch gedrag van elke browser op elk platform verschillend.
En vele browsers 'implementeren/ondersteunen' de Netscape Plug-in API, maar er is wel een
verschil in implementaties, zodat ze allen een verschillend gedrag hebben. Het fundamenteel
probleem is dat je probeert één stuk van de ingewikkelde software (je mooie plug-in) in te
passen in een ander stuk ingewikkelde software (de browser), naast andere plug-ins.
En, in het algemeen, deel je hetzelfde geheugen en sommige datastructuren. Dit vormt de reden
waarom er iets grondig verkeerd gaat wanneer één persoon een fout maakt.
Terwijl ik dit schrijf, wordt het duidelijk dat zelfde een Jmol Plug-in nooit zal bestaan.
Dit is voorlopig genoeg.
Verschillende mensen hebben gevraagd waarom de Jmol code drijvende komma's gebruikt
in plaats van dubbels. Inderdaad, vele beginnende Java programmeurs hebben nog nooit
een programma gezien dat zoveel gebruik maakt van drijvende komma's.
Het antwoord is dat ze kleiner zijn ... drijvende komma's nemen 4 bytes in beslag,
dubbels nemen 8 bytes in beslag. Toch hebben ze een groot bereik en precisie, geschikt
voor onze doelstellingen.
Waarom is kleiner dan zo belangrijk? Velen geven het goedkope geheugen aan als reden,
en daar hebben ze gelijk in.
Echter, Jmol moet z'n applet op de 1.1 JVM draaien, waar de hoeveelheid virtueel geheugen kleiner is.
Belangrijk is dat de geheugen bandwijdte nooit goedkoop is. CPU producenten doen alles
wat ze kunnen en proberen nieuwe ontwerpen met grote hoeveelheden cache om zo de effectieve
geheugenbandwijdte te verhogen. Als we nu met 4-byte drijvende komma's werken in plaats van
8-byte dubbels, maken we effectiever gebruik van het berschikbare geheugensysteem ...
de verschillende lagen van de cache + de geheugenbandwijdte. Zo kunnen we meer data bewaren
in een cache met vaste grootte en kunnen we meer data ophalen vanuit het geheugen elke keer
we de cache aanspreken.
Het is net zo gemakkelijk om drijvende komma's te gebruiken ... en er is geen enkele reden
om te verspillen.
|