DevConnections Konferenz in Karslruhe 2011 – Tag 2

DevConnections Konferenz in Karslruhe 2011 – Tag 2

Auch heute, am zweiten Tag, gab es einige spannende Dinge. Ein großes Highlight war der Vortrag von Scott Guthrie zum Thema Azure, daneben liefen natürlich die normalen Tracks weiter, und auch Kimberly L. Tripp, die Gerüchten zu folge an der SQL Server Engine mitgeschrieben hat, hat heute ein paar Details zur Funktionsweise des Servers gegeben.

Scott Guthrie – Cloud Computing (mit Azure)

Programmierdemos und Features fielen recht standardmäßig aus. Ich wüßte nicht wirklich, warum ich Azure den Konkurrenzprodukten von Amazon, Google, oder selbst HP (planen die nicht auch was?) vorziehen sollte. Klar, super Redundanz, Daten bleiben im selben Kontinent (2 Zentren in Europa), und die Zentren, wo die Hardware steht, sind extra 500 Meilen voneinander entfernt. Man weiß ja nie, ob eine Boeing oder ein Komet drauffällt. Skalierbar, flexibel, kostet (fast) nichts.. und natürlich produzieren die Zentren eher noch Energie, als sie sie verbrauchen. Und da, wo sie doch (ein wenig) Energie verbrauchen, ist es erneuerbare Energie. Da schläg das Herz höher.

Was für mich das Spannendste war, war, wie Microsoft die Zentren geplant und eingerichtet hat. Es sind nämlich jeweils zahlreiche Server in Racks in einem Container untergebracht (mit Netzwerkanschlüssen, Stromanschlüssen, usw.). Dadurch können die Zentren extrem schnell aufgebaut werden. Noch besser: defekte HW wird einfach abgeschaltet, nicht ausgetauscht. Sind irgendwann einmal zu viele Fehler in einem Container, wird der komplette Container ausgetauscht und geht zur Reparatur an den Hersteller (der Microsoft bei der Abnahme von 100000+ Servern auf einmal nette Rabatte gewährt hat) zurück. Ein sehr interessantes Konzept. Das erklärt dann auch, warum in den Zentren nur ca. eine Person pro 15000 Servern arbeitet. Bei einem gewöhnlichen Ansatz würde so jemand wohl nicht einmal damit nachkommen, die Festplatten auszutauschen.

Auch der Rest läuft natürlich automatisch. Schön für Microsoft, aber auch für den Kunden, der innerhalb weniger Minuten ein lauffähiges System hat. Sicher interessant für viele Anwendungen. Noch interessanter wird es wohl, wenn man dann auch Webseiten unter einer eigenen URL hosten kann, das geht aktuell wohl nicht.

Sollte doch einmal Hardware ausfallen, so kümmert sich eine Service Queue darum, daß Nachrichten zwischen Servern nicht verlorengehen, ein zusätzliches Zuverlässigkeitsfeature. Noch angesprochen hat Scott das Thema Storage mit den großen Trends Blob Filesystem (mit bis zu über 100 Petabyte), SQL Azure sowie NoSql.

SQL Server Covering: Concepts, Concerns and Costs

Irgendwie habe ich den Titel nicht ganz genau gelesen und war davon ausgegangen, daß es sich um eine schöne, allgemeine Einführung zum Thema SQL Server handelt, angereichert mit ein paar interessanten Fakten. Statt dessen ging es um das Thema SQL Server Covering, wo es um Indices, sequentielle sowie randomisierte Zugriffe geht, sowie darum, wann SQL Server welche Zugriffsmethode bemüht.

Sehr interessant, für mein SQL Server Wissen dann jedoch doch etwas.. ambitioniert.

Auf alle Fälle war es eine Erfahrung, Kimberly L. Tripp sprechen zu sehen. Jetzt weiß ich auch, daß SQL Server nach wie vor agnostisch bezüglich der verwendeten Plattentechnologie ist – also z. B. nicht bei SSD Platten eher auf randomisierte/verteilte Zugriffe schaltet, weil hier der Geschwindigkeitsverlust viel geringer ist.

Warum Web-Performance wichtig ist

Richard Campbell von .net rocks sowie RunAs Radio sowie StrangeLoops hat ein paar Takte zum Thema Webseitenoptimierung bzw. noch eher über die Notwendigkeit hierzu erzählt. So beschrieb er kurz den Prozess, über den Besucher auf eine Webseite kommen (Werbung, Suche, …), wie der Besuch kategorisiert werden kann, ob er neu ist, ob es ein Bounce ist, über die Anzahl der Page Visits, die Zeit auf der Seite, bis hin zu dem Ergebnis des Besuches für beide Seiten, seien es Werbeklicks, Anwenderproduktivität und -zufriedenheit, oder auch Konversion sowie Bestellwert.

Daß die Geschwindigkeit einer Webseite eine direkte Auswirkung auf die finanziellen Ergebnisse, die mit dieser Seite erzielbar sind, hat, hat Richard an mehreren Beispielen demonstriert. Wobei die Ergebnisse deutlich sichtbar waren, es jedoch keine 1:1 Korrelation gab. So bringt z. B. eine Verdopplung der Geschwindigkeit vielleicht 10% mehr Umsatz. Nicht die Welt, aber immerhin etwas, zumal sich ein gewisser Geschwindigkeitszuwachs mit minimalem Aufwand, nur durch Ändern von ein paar Konfigurationseinstellungen, erzielen läßt. So läßt sich z. B. die Kompression für die Übertragung anschalten, Grafiken können neu komprimiert werden (z. B. als .png), der Server Cache sollte aktiviert werden, Aufrufe an andere Server minimiert werden usw. Vorher ist oft schwer absehbar, welche Optimierungen möglich sind, und auch, welchen Effekt diese haben werden.

Gut läßt sich übrigens die Auswirkung von Geschwindigkeit zeigen, wenn man umgekehrt herangeht: verlangsamt man seine Seite bewußt (das ist einfacher) erhält man direkt Zahlen, welchen Einfluß die Geschwindigkeit haben kann. Das kann natürlich nur der Ausgangspunkt sein, dann zu sagen, daß die Geschwindigkeit der Seite optimiert werden sollte. Irgendwo zwischen 2s und 8s liegen die optimalen und realistisch machbaren Ladezeiten (bis das letzte Element gerendert ist) einer schnellen Webseite.

Welche Weisheit gab es noch? Wie schön es ist, Entwickler zu sein. Bei den vielen IT-Projekten, die scheitern, sollte mal folgender Schluß gezogen werden: die erfolgreichen IT_Projekte sind so erfolgreich, daß sie die Verluste durch all die gescheiterten Projekte wieder mehr als wett machen. Das sagt doch etwas über den Nutzen des Programmierers in jeder Firma aus! (Und ein Scheitern hängt oft genug vom Management/der Projektleitung ab.)

Parallel Programmieren mit C# 4

Bernd Marquardt hat ein paar grundlegende Dinge zur Parallelprogrammierung vorgestellt. (Das Thema ist wohl kein Einfaches. Hat man bereits Erfahrungen, so findet sich schwer interessantes Neues, um den Zuhörer zu begeistern. Hat man jedoch noch nie parallel programmiert, so ist man plötzlich mit einer neuen Welt konfrontiert. So muß man z. B. grobe Ahnung von der Abarbeitung von Messages haben, wissen, welche Controls und Container multithreading-fähig sind (oder immer voraussetzen, daß sie es nicht sind) usw. Zumindest hat sich einiges vereinfacht, so muß man sich z. B. keine Gedanken mehr machen, welche Daten auf dem Stack oder Heap sind (der Stack wird nämlich abgeräumt und taugt somit nur bedingt zur Datenübertragung an einen anderen Thread) usw. Doch auch wenn man „nur” managed mit Threads arbeitet, wird ein nicht allzu kleines Grundwissen vorausgesetzt, denn der erste Fehler kommt oft relativ früh, und dann sind die Fragen zahlreich.)

Zunächst gab es einen kurzen Überblick über die Entwicklung von Computerarchitekturen in den letzten Jahren, sowie dazu, warum man jetzt überhaupt programmieren muß – wo es doch viel schwieriger sowie ineffizienter ist, als sequentiell zu programmieren (man programmiert standardmäßig sequentiell, ohne sich viele Gedanken dazu zu machen). Den Grund sieht man, wenn man in einen PC-Laden geht (oder online schaut): die schnellsten Rechner sind (grob) mit 3GHz getaktet. Ging man vor 5 Jahren in einen PC-Laden, sah es ähnlich aus: die schnellsten Rechner waren mit 3GHz getaktet. Nochmal 5 Jahre davor lagen die schnellsten Rechner bei 2GHz. Davor gab es einen recht regelmäßigen, exponentiellen Anstieg (ja, ein exponentieller Anstieg ist in dem Fall sehr gut). Genaueres hierzu sollte man sich mal in The free lunch is over anschaun, auf der Seite findet sich auch ein sehr aussagekräftige Graph. Die Quintessenz: Prozessoren (bzw. deren Kerne) werden nur noch (minimal) schneller, im Bereich weniger Prozent pro Jahr, durch Architekturverbesserungen sowie eine (leichte) Erhöhung der Taktfrequenz. Die eigentliche Mehrleistung kommt aus der vergrößerten Anzahl der Kerne, also der Möglichkeit, Instruktionen parallel auszuführen, und so doch schneller am Ziel anzulangen.

Dies ist jedenfalls die Motivation, warum auch Otto Normalprogrammierer parallel programmieren sollte (sowie einige andere Dinge, wie z. B. die Responsiveness der Benutzeroberfläche).

Nachdem dies bereits seit vielen Jahren klar ist, und dennoch kaum jemand seine Anwendung parallelisiert, hat Microsoft nun im Framework 4 die Parallelprogrammierung noch einmal vereinfacht. So gibt es nunmehr ein Parallel.For, ein Parallel.Foreach sowie ein paralleles Linq (mit .AsParallel()). Der Fokus liegt hier also, wie bei mathematischen und ähnlichen Anwendungen oft gebraucht, auf der Schleifenparallelisierung. Hier sollte man jedoch aufpassen, daß eine möglichst ausgewogene Aufteilung der Iterationen durch eine nicht-deterministische Aufteilung der Arbeitslast und somit auch der Schleifenteile auf verschiedene Threads erfolgt. Heißt: mal wird ein Teil von Thread 1 berechnet, mal von Thread 2, und auch die Teile an sich ändern sich. Problematisch kann dies werden, wenn man z. B. mit Gleitkommazahlen arbeitet, und hier an die Grenze der Genauigkeit stößt. Das Ergebnis einer mathematischen Operation ist dann nämlich abhängig von der Reihenfolge, und so mag es überraschende Ergebnisse für den einen oder anderen geben (spielt sich aber typischerweise nur auf den hintersten Stellen ab). Apropos, sobald man z. B. in einer Schleife akkumulieren/aggregieren möchte oder eine ähnliche Operation durchführen möchte, wird die Syntax auch direkt viel schwieriger, hier muß man sich mit dem Threadlocalstate beschäftigen, um Teilergebnisse später zusammenführen zu können. Um ein gewisses Verständnis des Vorgangs kommt man hier also nicht herum.

Ein Problem ergibt sich hier durch die Parallelisierung: es können mehrere Exceptions parallel auftreten. Zwar werden alle Threads abgebrohen, wenn eine Exception in einem der Threads auftaucht, aber in diesem Zeitraum können durchaus noch weitere Exceptions auftreten. Daher gibt es jetzt eine Klasse, die mehrere Exceptions beinhalten kann, die AggregateException.

Immer macht eine Parallelisierung natürlich keinen Sinn. Wobei Bernd Marquardt vorgeführt hat, daß bereits bei einer Abarbeitungsdauer von deutlich unter 1ms ein großer Vorteil bei paralleler Abarbeitung besteht (so denn mehr als 1 Core auf dem Zielrechner zur Verfügung steht).

Fazit: Parallelprogrammierung lohnt sich (fast) immer. Besonders im Fall von Schleifen ist sie nun noch leichter durchführbar (damit hat C# nach vielen Jahren in einem weiteren Bereich zu C++ aufgeschlossen). Bei anderen Konstrukten, wo man selbst Threads startet, muß man sich insbesondere auch um die Synchronisierung kümmern (wobei es auch hierfür Hilfsmittel gibt im Framework, so daß Threads direkt asynchron gestartet werden, jedoch auf die Beendigung aller Threads gewartet wird, was einer Synchronisierung gleichkommt). Sehr schnell sieht man hier auch Probleme, so darf man z. B. aus einem parallel gestarteten Thread nicht (direkt) auf die Controls einer WinForms Applikation zugreifen. (Schöne Lösung auf Stackoverflow per Invoke, sehr ausführliche Erklärung mit Lösungen, offizielle Lösung mit einem Backgroundworkerthread. Der Grund für den verbotenen Zugriff sind mögliche Probleme bei einem gleichzeitigen Zugriff. Um dem vorzubeugen werden im Debug Modus direkt Exceptions geworfen, wenn man einen solchen Zugriff probiert – auch, wenn er in 99% der Fälle korrekt funktionieren würde.)

UI-Skill

Billy Hollis hatte eine der letzten Sessions des Tages. Und.. es ging um Design-Skills für Programmierer. Leider war der Talk anfangs eher der Motivation gedacht als daß er wirklich Fakten gebracht hätte. Ja, die rechte Seite des Gehirns (wenn diese Aufteilung überhaupt korrekt ist!) sollte der Programmierer auch nicht ausschalten oder gar bewußt benutzen. Aber genau, weil man das machen möchte, sitzt man ja in seinem Talk.

Dann gibt es ein paar interessante Dinge: ein paar Fehlschläge des Designs. So zeigt er z. B. das Bild einer Aufzugsschaltleiste (mit den Knöpfen, um Etagen zu wählen) mit Schildern und Knöpfen daneben. Allein.. man weiß nicht, was die Knöpfe sind, was sich gut daran abzeichnet, daß einige Schilder von (fälschlichen Drückversuchen) bereits ganz abgenutzt sind. Über dieses Beispiel kommt er dazu, daß wir es auch bei unseren UIs in der Hand haben, wie einfach wir es unseren Anwendern machen. 100 Buttons in einer Oberflächen sind eben nicht immer (oder fast nie) Trumpf. Über Größe (=wichtig, oft benutzt) und Anordnung (Zugehörigkeit, über Abstand und Freiraum) läßt sich bereits viel vereinfachen. Am besten ordnet man dann seine Controls noch einem erwarteten Workflow an. Ungefähr so, wie ein Wizard einen bestimmten Workflow vorausahnt und auch erzwingt sollte die UI die häufigsten Workflows vereinfachen sowie unterstützen.

Seine Tips sind ferner:
„Going to Natural”

  • Vermeide scharfe Kanten und Rechtecke
  • Gradientenverläufe benutzen (z. B. für Hintergründe: oben hell, unten dunkel, ähnlich wie Horizont)
  • Animationen (für sanfte Übergänge, z. B. Vergrößerung)
  • 3D (Controls treten hervor, wenn sie aktiviert werden)
  • Desire Lines (dazu kenne ich keine Übersetzung – es ist eine Art natürliche Abkürzung, wenn der offizielle Weg umständlich ist. So sollte sich das Design an tatsächlich benutzten Arbeitsabläufen orientieren.)

Auch noch sehr interessant: oft geht die Erstellung einer GUI mit einer Untersuchung der Arbeitsabläufe einher. Manchmal steht sogar eine Beratung zum Thema Veränderung der Abläufe auf dem Programm. Damit (veränderte Abläufe, neue Software) wurden in Einzelfällen schon Produktivitätssteigerungen von 100% erreicht.

Und: Anwender halten schöne Software für eher benutzbar als unschöne.

Eine Buchempfehlung gibt es auch für den Programmierer mit Ambitionen (Benutzbarkeit ist ja auch ein Qualitätsmerkmal): Universal Principles of Design.

Fazit

Ein weiterer interessanter Tag und danach eine halbwegs angenehme Heimfahrt. Ich freue mich jedenfalls bereits auf die nächste Konferenz.

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.