21. Juni 2005

Ein unmoegliches Bit

Heute mal etwas fuer Experten:

Bei einem Kunden stuerzt ein Videoserver mehrmals taeglich ab. Der Code ist natuerlich fehlerfrei. Deshalb stellt sich die Frage: wieso? Die Antwort: in einem Register des Prozesors ist ein Bit zu viel gesetzt. Der Registerwert wird zum Speicherzugriff verwendet und: Boing, Zugriff auf nicht gemappten Speicher.

Die fragliche Stelle sieht in x86 Assembler so aus:

mov edx,dword ptr [ebp-0Ch] # Load bits into edx
sar edx,cl # Shift arithmetic right by value of cl
and edx,0FFh # Logical AND with 0x000000FF

Nach dem "and" ist der Wert von edx: 0x80000041 statt 0x00000041.
Frage: wie kann das sein? von einem "and" erwartet man, dass es alle Bits plattmacht, ausser der Maske.

Antwort: das kann nicht sein, aber es passiert auf Intels Hyperthreading Prozessoren unter Last etwa jedes milliardste Mal, wenn der Code ausgefuehrt wird. Laeuft der Prozess nur auf einem virtuellen Prozessor, dann passiet es nicht.

Das Problem wurde behoben, durch ein zweites "and edx,0FFh". Das klappt dann meistens. Aber das Warum bleibt. Fehler im Hyperthreading?

Nachtrag: Wir haben beschlossen, dass dieser eine Prozessor fehlerhaft ist und kein grundsaetzlicher Fehler vorliegt.

_happy_coding_

13. Juni 2005

Noch ein Vortrag über Virtuelle Präsenz

Gerade kam die Nachricht, dass mein Vortrag über Virtuelle Präsenz für Communities ins Programm des Virtual Communities Forum 2005 angenommen wurde. Die Veranstaltung findet statt in Kensington Town Hall, Central London, 9-10 November 2005. Titel des Vortrags: "Virtual Presence for Communities". Wieder ein Erfolg in der LLuna Publikationsoffensive. Zwei weitere sind schon eingereicht.

_happy_coding_

8. Juni 2005

Software mit 25 Sollbruchstellen

Angenommen ich schreibe ein Stueck Software. Ich baue wissentlich 25 Stellen ein, die mit einer gerningen Wahrscheinlichkeit schief gehen. Natuerlich will ich, dass alles funktioniert, aber ich kann ein Risiko von 5% je Codestelle nicht ausschliessen. Ich hoffe einfach, dass alle durchgehen. Dann schicke ich die Software zum Kunden. Wie gross ist die Wahrscheinlichkeit, das sie funktioniert? Man koennte jetzt raten: 0,95 ^ 25 = 0,28. Das kann man nicht gerade als zuverlaessige Software bezeichnen. Ein bisschen unprofessionell ist das schon. Wenn ich so programmieren wuerde, wie andere Leute Europaeische Verfassungen machen, dann wuerde ich bald verhungern. Ein bisschen unprofessionell war es schon.

29. Mai 2005

Twincoding Light

Twincoding ist eine der "Empfehlungen" der Xtreme Programming Methodik. Twincoding heißt, dass 2 Programmierer vieles zusammen programmieren.

Aber kann man es sich überhaupt leisten zwei Programmierer mit der gleichen Sache zu beschäftigen? Ich kann ja nicht meinem Kunden sagen: Bei uns ist alles doppelt so teuer, weil wir Twincoding machen. Twincoding muss, um überhaupt konkurrenzfähig zu sein, mindestens so produktiv sein, wie Einzelcoding. Das ist nicht einfach, aber möglich.

Die Theorie sagt, dass man Programmierfehler vermeiden kann durch das zweite Augenpaar. Die Vermeidung der Fehler wiegt den Mehraufwand wieder auf. Das kann nur stimmen, wenn man beim Twincoding keine Fehler macht und beim Einzelcoding mindestens 50 % der Zeit ineffizient mit Fehlern und Problemen verbringt, die man zu zweit nicht gehabt hätte.

Die Annahme, dass beim Twincoding keine Fehler auftreten ist sicher nicht ganz richtig. Teilen wir die Fehlerzeiten ein in Flüchtigkeitsfehler, Denkfehler und Blockaden. Flüchtigkeitsfehler kosten sehr oft wenig Zeit. Sie fallen meist schon beim Compilerlauf auf und werden schnell behoben. Dafür geht es aber um sehr viele Ereignisse. Flüchtigkeitsfehler werden bei Twincoding tatsächlich stark unterdrückt. Hier liegt Twincoding klar vorne. Die Behebung von Denk- und Architekturfehlern kostet wesentlich mehr Zeit, als die von Flüchtigkeitsfehlern. Und nicht nur die Korrektur kostet Zeit, sondern auch die Produktion des Fehlers. Erfahrungsgemäss reduziert sich die Wahrscheinlichkeit für Denkfehler deutlich, aber sie verschwindet nicht. Auch 2 Leute können sich gegenseitig von Unsinn überzeugen. Trotzdem ist sicher die Denkfehlerzeit geringer im Twincoding. Der Vorteil wird allerdings meistens mit einem höheren Kommunikationsaufwand bezahlt, das sich 2 Leute über Modelle und Architekturen verständigen müssen. Der Aufwand ist nicht unerheblich, wenn die beiden nicht sehr kompatibel sind. Die dritte Fehlerzeitquelle sind Blockaden, wenn Detailprobleme den Fluss unterbrechen. Diese können von Tools, Fremdfehlern (z.B. Libraryfehler) oder Informationsdefiziten herrühren und unheimlich viel Zeit und Motivation kosten. Oft kann eine zweite Sichtweise und ein komplementäres Wissen den Konten viel schneller lösen.

Flüchtigkeitsfehler kosten nur wenige Sekunden oder Minuten. Denkfehler kosten zig Minuten oder Stunden, selten Tage. Blockaden kosten oft Stunden oder Tage. Bei allen Fehlerarten kann Twincoding deutlich helfen. Ich schätze, dass gute Programmierer, die Dinge programmieren von denen sie etwas verstehen, aber trotzdem nicht die Hälfte Ihrer Zeit mit Fehlern verbringen, die durch Twincoding vermieden worden wären. Denn ein Teil der Programmierzeit besteht aus Routinearbeiten und Tests, die sich nicht beschleunigen lassen . Ob Twincoding wirtschaftlich gerechtfertigt ist, hängt vom Einzelfall ab. Oft müssen Routinetätigkeiten ins Einzelcoding verschoben werden mit der Gefahr von geringem Synchronisationsverlust. Selbst für den Spezialfall von zwei guten und gut abgestimmten Programmierern kann man keine klare Aussage treffen aufgrund der Reduzierung von Fehlerzeit. Die Effizienz von Twincoding ist fraglich.

Entscheidend ist der Faktor Motivation. Zwei Programmierer lassen sich weniger ablenken. Sie fangen früher an und bleiben länger bei der Sache. Mit anderen Worten: sie lesen nicht morgens Onlinezeitung und 10 mal am Tag zwischendurch Email. Sie verlagern projektunabhängige Wartungstätigkeiten auf den Abend und lassen sich weniger von Zwischenrufen anderer Kollegen ablenken, weil man den Partner nicht gerne warten lässt. Gemeinsame Motivation kann Twincoding ins Plus schieben.

Trotzdem sind 150 Euro pro Team-Programmierstunde ziemlich viel. Wenn man die Kosten reduziert, dann geht Twincoding deutlich ins Plus. Wir ersetzen deshalb gerne einen der zwei Programmierer durch einen Aufpasser. Der Aufpasser muss nicht ein erfahrener Programmierer sein, sondern z.B. ein guter Praktikant. Der Aufpasser vermeidet genauso gut Flüchtigkeitsfehler. Er hat etwas weniger Einfluss auf Denkfehler und Blockaden. Ist der Aufpasser nicht beteiligt an der Architektur, dann kann er wenig helfen Denkfehler zu vermeiden. Andererseits hat der Leadprogrammierer die Chance bei Erklärungen die Denkfehler selbst zu entdecken. Der korrigierende Einfluss des Aufpassers auf Blockaden kann genauso gut sein, wie bei einem erfahrenen Programmierer. Der Aufpasser hat eher ein komplementäres Wissen, als ein langjähriger Kollege und kann deshalb manchmal besser sein, als der zweite Programmierer. Die Motivationsfunktion wird vom Aufpasser genauso gut ausgefüllt.

Zusammenfassend verliert Twincodig-Light wenig Performance gegenüber traditionellem Twincoding während die Kosten deutlich sinken.

_happy_coding_

27. Mai 2005

Gemeinsam surfen mit Miranda Instant Messenger Plugin

Endlich mal wieder Funcoden! 3 Programmiernaechte habe ich gebraucht fuer ein Miranda Plugin. Jetzt koennen Miranda User sich mit LLuna auf Webseiten treffen. Man kann in der Kontaktliste einfach die URLs vom Buddy abfragen. Wenn der antwortet, dann Klick und auf die Seite gehopst.

Link zum download.

Miranda ist ein Multiprotokoll Open Source Instant Messenger. Als Progammierer kann ich Miranda nur empfehlen. Projekt in das Developer Studio werfen, build, fertig. Es gibt wenig Doku, aber Code ist die beste Dokumentation, wenn man durchsteppen kann. Man kann durch den Miranda-Kern und andere Plugins laufen und lernen. Es gibt viele Plugins, auch mit Source, und die Community ist aktiv im Forum und beantwortet Fragen. Super Sache.

_happy_coding_

21. Mai 2005

Die perfekt symmerische Zeit

Gestern abend war die Uhrzeit absolut symmetrisch mit mehreren Symmetrieachsen: 20.05.2005 20:05. Achsensymmetrisch und rotationssymmetrisch mit einer dreizählichen Achse. Ein denkwürdiges Datum und fast niemand hat es gemerkt (danke DF).



Die Zeit war so symmetrisch, dass der Verdacht naheliegt, dass dieser eine Moment vielleicht sogar der Mittelpunkt der Zeit war. Das würde bedeuten, dass Halbzeit ist und sich das Universum jetzt wieder zusammenzieht. Zum Glück sind es noch ein paar Milliarden Jahre.

_happy_coding_

27. April 2005

Richtige Software is fett

Beim Programmieren verwendet man ja immer mal wieder ein Code-Snippet aus dem Internet, von einem Kollegen oder aus dem Samplecode des Herstellers. Dann noch ein paar Controls, Datasets und Formulare aus dem Designer und fertig ist die schlanke Anwendung. Schoene Programmierwelt, aber leider nicht die Realitaet. Denn richtiger produktiver Code ist fett. Die kleinen Codeschnipselchen, die mit wenigen Zeilen unheimlich tolle Sachen tun, gehen unter zwischen Massen an Code, die eine richtige Anwendung braucht.

Fangen wir an mit der Fehlerbehandlung. Regel: Alles was schiefgehen kann, geht mal schief, denn wenn 1000 User eine Funktion 1 Mio. mal verwenden, dann schaffen Sie die seltsamsten Bedingungen. Das heisst, dass jeder Pfad im Programm einmal abgelaufen wird und jede Funktion die schiefgehen kann auch mal schiefgeht. Benutzt man eine Funktion, die schiefgehen kann, dann muss man einen potentiellen Fehler fangen und bearbeiten. So werden aus einer Zeile leicht 5, denn der Fehler wird geloggt, und dann recovert, und zwar nicht in einem catch fuer 10 Statements, sondern einzeln, denn jedes Statement produziert characteristische Fehler.

Spezialfaelle: Das kennt jede Programmiererin. Ein Formular zeigt Werte aus der Datenbank an. Praktisch eine 1-zu-1 Abbildung. Aber der Kunde will, dass wenn im Feld A eine 5 steht, dann soll das Feld B eine Combobox sein mit den Werten aus Tabelle C statt dem einen Wert aus Tabelle D. Und schon kommt das dicke if-Statement mit einer Seite Spezialcode. Die Welt ist eben nicht rechtwinklig.

Toleranz: Benutzer machen tatsaechlich Fehler. Manchmal dumme Fehler, manchmal verhalten sie sich einfach nur anders, als die Programmiererin sich das gedacht hat. Die Software ist natuerlich so tolerant alle Eingaben zu pruefen, denn wenn der Benutzer sich seine Daten selbst kaputt macht, dann findet er ja trotzdem das Programm bloed und nicht sich selbst und das wollen wir nicht. Dann sind da noch die Anpassungen fuer fehlerhafte Systemsoftware/Libraries oder andere Programme. Andere Programme sind nicht besser, als User. Sie machen Fehler und trotzdem sollte unser Programm weiterlaufen. Also: tolerant sein.

Programmierhilfen: Testcode, Testfeatures, Debugcode, Live-Konfiguration, Remoteinspection, vielleicht ein kleiner HTTP Server mit HTML Interface als Statusanzeige, Laufzeitparameter online aendern? Automatische Ueberwachung und Fehlervermeidung: immer wieder pruefen, wie lange die Threads schon laufen, wie voll die Queues sind, ob etwas zu fixen ist. Datenbankschema erzeugen, falls das Programm gestartet wird ohne die Datenbank einzurichten. Das faellt schon fast wieder in die Rubrik Toleranz.

usw...

Das alles will eine richtige Applikation haben. Deshalb: keine Angst vor viel Code. Richtiger Code ist fett, weil er viel kann.

_happy_coding_