Wer unter Ubuntu und Kubuntu schnell mal direkt etwas die Adressleiste eingeben will muss einfach nur [STRG]+[L] drücken.
Autor: Raptor 2101
Tomcat und Eclipse unter Ubuntu zum laufen bekommen.
Unter Ubuntu wird die Tomcat (wie unter Linux üblich) verteilt über mehrere Verzeichnisse installiert. Leider kommt damit das Eclipse-Plugin nicht so klar. Es bringt beim konfigurieren immer folgende Fehlermeldung.
The Tomcat installation directory is not valid. It is missing expected file or folder conf.
Um diesen Fehler zu beheben einfach folgende Befehle ausführen:
cd /usr/share/tomcat6 sudo ln -s /var/lib/tomcat6/conf conf sudo touch /usr/share/tomcat6/conf/catalina.policy sudo chown o+r /usr/share/tomcat6/conf/tomcat-users.xml
Lucid Lynx und Dinovo Edge
Wer unter der neuen Ubuntu Version (aktuell als Beta erhältlich) seine Dinovo Edge anschließt sollte erstmal eine zweite USB-Tastatur parat haben. Die Dongle wird nun nicht mehr als USB-Dev missbraucht, sondern dient als vollwertiger BT-Receiver. Das blöde an der Sache ist, dass die Tastatur erst genutzt werden kann, nachdem sie gepairt wurde. Zum pairen muss man sicher aber einloggen, was ohne funktionierende Tastatur nicht funktioniert.
Um also Ärger aus dem weg zu gehen, entweder während des Setup-Prozesses auf „autologin“ stellen, sich eine weite Login-möglichkeit schaffen oder einfach eine zweite simple Tastatur zur hand haben.
Um zu pairen einfach auf der Rückseite die Taste zum connecten drücken. Anschließend im Bluetooth-Verwalter der wahl ein Pairing herstellen. Als pin gibt man eine beliebige vierstellig Zahl ein. Anschließend (nachdem man bestätigt hat) gibt man an der DinovoEdge die gleiche Zahl ein und bestätigt mit Enter.
Ab da kann man die Tastatur ohne Probleme nutzen.
Mass Effect 2
Einleitung
Ich hab Mass Effect 2 jetzt zweimal durchgespielt. Glaube also mir eine Meinung bilden zu dürfen. In diesem Text wird so wenig gespoilert wie möglich. Bilder hab ich keine eigenen, da es im Spiel kaum „Screenshotwürdiges“ gibt, dass nicht sogleich auch spoilert.
Objektive Betrachtung
Eins gleich vorweg: objektiv betrachtet sollte Mass Effect 2 das bessere Spiel sein. Es hat von fast allen Inhalten mehr:
- 10 Mitstreiter,mit jeweils einer eigenen Mission.
- drei „große“ Städte.
- Mehrere Nebenschauplätze.
- mehrere Nebenmissionen, die alle so designt sind, dass sie den Namen auch verdient haben
Dafür wurden einige Sachen reduziert oder komplett weggelassen, dazu gehören:
- Das Inventar fehlt völlig.
- Upgrades an Waffen muss man nun global erforschen und gelten immer.
- Munitionsarten sind nun Spezialfertigkeiten.
- Die Menge an Spezialfertigkeiten wurde reduziert.
War Mass Effect 1 schon ein seichtes Rollenspiel verkommt Mass Effect 2 nun zu einem ausgewachsenen Shooter. Um dem Rechnung zu tragen wurde das Kampfsystem überarbeitet. Es geht nun flotter von der Hand, das Deckung suchen ist wichtiger und alles wirkt irgendwie „schneller“.
Besonders in den kleinen Details ist Mass Effect 2 stark. Das fängt bei der neuen Normandy an. Diese ist wesentlich „nachvollziehbarer“ gebaut. Es gibt Toiletten, Duschen, Aufenthaltsräume usw. Alles in allem wirkt sie nun wie ein Schiff auf dem man leben könnte. Diese Detailliebe wird über fast alle Hauptschauplätze fortgesetzt. Wenn man seinen Charakter aus ME1 importiert, wird man alle Nase lang mit Anspielungen bombardiert und sei es nur über die Nachrichten. Das ganze gipfelt in einem spontanen Gespräch zweier ehemaliger Normandy Crewmember, das den „Fahrstuhlgesprächen“ angelehnt ist. Jedoch zaubert es ein erheblich breiteres Grinsen aufs Gesicht. All diese kleinen Details lassen das SciFi-Herz höher schlagen.
Weniger ist manchmal mehr
Leider ist ME2 dennoch nicht das bessere Spiel. Die ganze Zeit hatte ich das drängende Gefühl, dass Weniger bei diesem Spiel mehr gewesen wäre. Das fängt bei der Story an. Der Reaperangriff wurde abgewehrt. Kurz darauf taucht ein neuer noch „gefährlicherer“ Gegner auf, nur um (das sei mal vor weg gespoilert) am Ende doch wieder zu verschwinden. Im Laufe des Storymissionen besucht man fast ausschließlich (Raum) Stationen und Schiffe vom Kaliber der Citadel. So groß diese Pötter aber auch in den Einspielungen dargestellt werden, so wenig Inhalt bieten sie. Sowohl die Räumlichkeiten der Citadel als auch ihr Pendant die Omega – Station wirken winzig, im Vergleich zur alten Citadel. Aber auch die feindlichen Kriegsschiffe/Stationen wirken vergleichsweise lächerlich. Richtig sauer aufstoßen tut aber das Feindaufkommen. Da begibt man sich am laufenden Band in Mission deren „Überlebenschance“ nahe Null sein sollen, nur um dann immer und immer wieder von Wellen von Gegner attackiert zu werden. Nicht das man mich falsch versteht. ME1 war nie ein Quell der Gegnervielfallt aber in ME2 gegen einige Türen nur auf um dahinter 5 Gegnerwellen zu spawnen und anschließend ist die Tür wieder auf ewig versiegelt. Husk kriechen immer wieder aus den Gleichen löchern, nur um nach der dritten Welle damit aufzuhören. Das ganze gipfelt in der letzten Mission. In den Einspielungen wird man immer von Gegnermassen gejagt und bedroht, im Spiel selber rücken die Gegner immer in handlichen Trüppchen an. So lieblos und gestellt wirkte ME1 nie. Das ist Schade, denn dass Missionsdesign selbst ist immer motivierend. Gerade durch die Einspielungen, Musikuntermalung und Aufgabenverteilung kommt ein sehr eindringliches Gefühl auf, was besonders dem angelegtem Tempo geschuldet ist. Ignoriert man das Gegneraufkommen, kann man wirklich glauben, dass man auf einer „Selbstmordmission“ ist.
Aber spätestens beim Abspann merkt man, irgendwas passt nicht. Der Endgegner ist einfach.. wie soll man es beschreiben. Ist den Story-Schreiberlingen nichts besseres eingefallen? Ohne viel zu verraten: man bekämpft einen gigantischen Boss-Gegner auf einer starr schwebenden Plattform. Die von diesem genüsslich Stückchenweise zerrissen wird. Was an sich lächerlich ist, da das Vieh die Möglichkeit hätte Shepard samt Plattform mit einem Hauch in Stücke zu reißen. Dennoch lässt sich der Kampf zur Not mit einer Handpistole gewinnen… Leider lässt der folgende Abspann nichts gutes für ME3 erwarten.
Auf in die Tiefe des Raumes…
Geht man von der Handlung zu den Charakteren gestaltet sich das Bild ähnlich. Es gibt jetzt zwar 10 Charaktere (9 in der Verkaufsversion, 1 als Zusatz im Cerberus Netzwerk) aber wirklich Tiefgang haben nur drei Charaktere. Gerade die „neuen“ groß angekündigten Charaktere bleiben eher blass und Farblos oder wirken gar aufgesetzt. Da helfen auch die für ein Crewmitglied bestimmten „Nebenmissionen“ nichts. Damit lassen sich die jeweiligen Charaktere zwar loyal stimmen, aber das hat nur bei einigen Charakteren gesprächsrelevante Auswirkungen. Machen sollte man diese Missionen sowieso, da sie alle Spaß machen und ordentlich Erfahrung bringen. Zudem überleben nur Loyale Mitglieder der Crew die „letzte Mission“. Wie in ME1 kann man aus seinen 10 Recken immer nur zwei aktiv in der Mission mitführen. Aber selbst auf den höchsten Schwierigkeitsgrad macht es kaum einen unterschied wen man mitführt. Alle Fähigkeiten und Fertigkeiten sind gleich Stark/Schwach. Das fehlende Upgrade/Waffensystem tut sein Übriges. Im Vergleich zu ME1 gibt es nun 5 statt 4 Waffenarten. (Sturmgewehr, Maschinenpistole, Schrotflinte, Schafschützengewehr, Pistole, schwere Waffen). Nein ich hab mich nicht verzählt. Das Sturmgewehr ersetzt die Maschinenpistole. Ein Charakter der eine MP mit sich führt kann keine Sturmgewehr tragen. KI Begleiter können immer nur 2 Gattungen mit sich führen und die schweren Waffen ist dem Spieler vorbehalten. Granaten gibt es gar nicht mehr. (nur noch Zaaed hat so etwas in der Art als Spezialfähigkeit). Im Spiel wird das Kampfsystem schnell langweilig. Zum einen kann man keine Waffen mehr vom Gegner „looten“ oder „kaufen“. An definierten Stellen (und nur an diesen) im Spiel findet man eine neue Waffe. Leider ohne jegliche Info was diese Waffe anders/besser macht. Im Beschreibungstext steht lediglich was von „Eignung“ al’a: „Effektiv gegen Schilde und Panzerung“. Auf Fragen wie „Erhöhte Feuerrate vs mehr Schaden“ findet man keine Antwort. Das darf man empirisch ermitteln. Aufrüstbare Upgrades fehlen völlig. Auf der Normandy darf man dauerhafte Verbesserungen erforschen.
Rüstungen gibt nun auch nicht mehr. Shepard trägt von Anfang bis Ende die gleiche Rüstung. Diese kann in Teilen aufgerüstet und individualisiert werden. Man hat dabei freie Wahl zwischen Farbe, Muster, usw. Die Idee an sich ist ja super, bloß muss sich bei EA/Bioware jemand gedacht haben: „Wie zum Geier verkaufen wir dann diese tollen Zusatzeditionen“. Als Besitzer der ME2-CE bekommt man die Collectoren-Rüstung, als Besitzer der DragonAge-CE die Blutdrachen Rüstung und als Cerberus-Netzwerk-Mitglied nun ja eine Cerberus Rüstung. Auf die Frage von oben antwortete wohl jemand mit „gar nicht“. Wählt man eine der drei Rüstungen, kann man nichts mehr individualisieren. Was wenig stört, aber leider sieht man nicht mal mehr den Schädel von Shepard. Da es keine Möglichkeit gibt den Helm abzunehmen. Da es aber in einigen Szenen auf Mimik ankommt sieht das einfach Scheiße aus.
Fazit
Ich habe MassEffect1 wie im Rausch durchgespielt. Der erste kurze Hänger stellte sich erst nach dem 4 Durchgang ein. Das lag aber eher an meiner Müdigkeit, denn an Mass Effect. Bei ME2 wollte dieser Sog nie so richtig losgehen. Ja ich wollte wissen wie es ausgeht. Ja ich wollte meine Crew retten. Aber der Drang, es nochmal anders durchzuspielen ebte nach dem zweiten Durchgang doch massiv ab. Insgesamt ein Gutes aber nicht Herausragendes Spiel.
Alte Linux Kernels löschen
Weil es ab und zu mal nötig ist (und ich mich nicht jedes mal durch die blogosphäre suchen will) hier der einzeiler
dpkg -l 'linux-*' | sed '/^ii/!d;/'"$(uname -r | sed "s/\(.*\)-\([^0-9]\+\)/\1/")"'/d;s/^[^ ]* [^ ]* \([^ ]*\).*/\1/;/[0-9]/!d' | xargs sudo apt-get -y purge
Quelle: Linux und ich
WPF Performant viele Controls darstellen.
Wer unter WPF eigene Controls erzeugt wird sich früher oder später mit der Frage der Performance auseinander setzten müssen. Besonders wenn das eigene UserControl mehr als 100 mal auf die Oberfläche darstellt. Spätestens dann muss man sich gut überlegen, wo man in den WPF-ToolKit Baum einsteigt.
Zuerst muss man als alter DirectDraw oder WindowsForms Entwickler umdenken. Anders als früher zeichnet man nicht mehr „immidiate“. Früher wurde man vom Betriebssystem informiert, wenn sich was am Zeichenbereich geändert hat und man musste „mit der Hand am arm“ neuzeichnen. Bei WPF wird der Spieß umgedreht. Man übergibt dem WPF Subsystem eine Reihe von zu zeichnenden Objekten und wird dann nicht weiter belästigt. Das Subsystem kümmert sich um alles, was das Neuzeichnen, Überzeichnen und das Transformieren betrifft.
Die leichteste Komponente die man zeichnen kann ist eine irgendwie geartete Geometrie. Leicht im Sinne von Overhead, der vom WPF-Subsystem erzeugt wird. Will man „schnell“ viele ObjeKte Zeichnen ist es die einfachste Methode alles in einen DrawingContext/DrawingVisual zu zeichnen. Mittels ein oder mehrerer Geometries kann man die komplexesten Objekte zeichnen. Leider hat dieses Verfahren das Problem, dass man sich um alles selber kümmern muss. Es gitb keine „MouseEvents“ oder ähnliches für die Geometries. Desweiteren kann man ein DrawingVisual nur im ganzen neu zeichnen. Will man einzelne Bereiche aktualisieren muss das ganze Bild neu gezeichnet. Das kann bei vielen Objekten zu einem Problem werden.
Der bessere Weg ist da einen DrawingContainer zu nutzen. Dabei wird stellt jede darzustellende Objekt ein Geometrie dar, die in ihr eigenes DrawingVisual gezeichnet wird. Dieses wird dann in einen DrawingContainer eingebettet. Das erhöht den Overhead ein wenig, bietet dafür aber den Vorteil, dass einzelne Bereiche des Bildes neu gezeichnet werden können, ohne dass andere DrawingVisuals davon betroffen sind. Um HitTesting und „MouseEvents“ muss man sich erneut selber kümmern.
Kommt es auf Performance nicht an, kann man auch von einem UserControl oder ähnlichem ableiten und diesem ein DrawingVisual als Child verpassen. Hier hat man alle Vorzüge die das WPF so an EventHandling Bereit hält, leider geht damit auch ein erheblicher Performanceverlusst ein her.
Logitech DinovoEdge unter (K)Ubuntu „zum laufen bringen“
Eine kurze Anleitung, wie man die Medientasten der DinovoEdge unter Linux/X11 und KDE/XFCE und Gnome zum laufen bringt.
Wenn man eine DinovoEdge an einen mit (K)Ubuntu betrieben wird feststellen, dass die Tastatur und das TouchPad zwar funktionieren aber die netten Zusatztasten nicht. Das hat zwei Gründe:
- Der aktuelle Linux-Kernel-Treiber ist noch buggy
- Ubuntu mappt die KeyCodes standartmäßig nicht korrekt.
Bei ersterem muss man abwarten, bei letzerem kann man Abhilfe schaffen. Dazu braucht man einen „KeyLogger“ wie xev. Führt man diesen auf der Konsole aus, kann mich sich anschauen, welche Tasten welche KeyCodes auslösen.
Hat man erstmal dadurch eine Liste von KeyCodes zusammengestellt muss man diese auf die „Medientasten“ mappen. Dazu gibt es zwei Möglichkeiten.
- Eine eigenes Tastaturlayout erstellen und dem X11 über die xorg.conf zuweisen. Diese Variante ist die „sauberste“ aber auch die mit dem meisten „bloat“. Wer es dennoch durchziehen will, sollte hier mal nachlesen.
- Oder man kann mittels Xmodmap das aktuelle Tastaturlayout erweitern. Das ist unter Ubuntu besonders einfach, da dies automatisch vom System durchgeführt werden kann.
Um letzteres umzusetzen muss man einfach in seinem Home-Verzeichniss eine Datei mit dem namen .Xmodmap anlegen. Diese wird automatisch nach dem Login geladen und „bearbeitet“ das aktuelle Tastaturlayout. Für die DinovoEdge reicht diese Datei.
keycode 225 = XF86Search keycode 163 = XF86Mail keycode 180 = XF86HomePage keycode 173 = XF86AudioPrev keycode 174 = XF86AudioStop keycode 172 = XF86AudioPlay keycode 171 = XF86AudioNext keycode 121 = XF86AudioMute keycode 179 = XF86AudioRecord keycode 150 = XF86PowerDown
Die Syntax sollte selbst erklärend sein. Wenn man andere Tasten zuordnen möchte, kann man die datei /usr/share/X11/XKeysymDB konsultieren, dort sind alle „möglichen“ Zuordnung hinterlegt.Hat man die Datei angelegt, kann man mittels folgendem Befehl, die Änderungen „im System Bekannt machen“
xmodmap .Xmodmap
Danach kann man diese Tasten in Fenstermanager seiner Wahl funktionen zuweisen. Nach einem Neustart/Login wird diese Änderung automatisch angewendet.
SQL Execution Plan Caching
Bei einem TSQL-Server kann es von Zeit zu Zeit zu „seltsamen“ Performance-Einbrüchen kommen. Dieser Posting beschäftige sich mit einem der Gründe: SQL – Execution Plan Caching.
Bei modernen Datenbanken wird die Schicht der Datenabfrage von der Schicht der Datenbeschaffung getrennt. Hatte früher die Formulierung eines SQL-Befehls Einfluss auf die Art wie das DBMS die Daten beschafft, ist der gleicher Befehl heute eher als „Wunsch“ welche Daten zu selektieren sind. Wie diese schlussendlich beschafft werden, bleibt dem DBMS überlassen. Der Sprung von SQL-Statement auf tatsächliche I/O-Operationen wird gemeinhin als „Execution Plan“ bezeichnet.
Ein solcher ExecutionPlan wird für jede Abfrage erzeugt die an das DBMS gestellt wird. Bei der Erstellungen eines solchen Plans werden alle Informationen die dem DBMS zur Verfügung stehen (Statistiken, Datenbankstruktur, etc) für die Optimierung der Datenabfrage genutzt. Es werden Suchalgorithmen und Daten-Aggregations–Funktionen ausgewählt. Anschließend wird der ExecutionPlan ausgeführt und die Abfrage beantwortet. Um bei Wiederholung einer Abfrage Zeit zu sparen, wird ein einmal erzeugter ExecutionPlan gecached und später wiederverwendet.
Um zu sehen welche ExecutionPlans gerade im Cache vorgehalten werden, kann folgender Befehl genutzt werden.
SELECT [cp].[refcounts] , [cp].[usecounts] , [cp].[objtype] , [st].[dbid] , [st].[objectid] , [st].[text] , [qp].[query_plan] FROM sys.dm_exec_cached_plans cp CROSS APPLY sys.dm_exec_sql_text ( cp.plan_handle ) st CROSS APPLY sys.dm_exec_query_plan ( cp.plan_handle ) qp ;
Wie bei allen Cache und Statistik-Funktionen, gibt es eine Kehrseite der Medaille. Es kann passieren, dass all die schöne Optimierung ins Lehre läuft oder ein Plan verwendet wird, der für die aktuelle Abfrage völlig ungeeignet ist. Wie schon bei dem TOP-Problem dreht sich auch hier alles darum, dass das DBMS den „falschen“ ExecutionPlan benutzt.
„Falsch“ bedeutet in diesem Zusammenhang, dass I/O – Operatoren benutzt werden, die für die anfallenden Datenmengen nicht optimal sind. Dafür gibt es normalerweise nur drei Gründe:
- Man weißt das DBMS dazu an: Es gibt mehrere Möglichkeiten das DBMS auf die falsche Fährte zu schicken. Entweder zwingt man es mittels QueryHints dazu oder gibt gleiche ganze ExecutionPlans vor.
- Die Statistik ist falsch: der unwahrscheinlichste Fall, sei aber dennoch Aufgeführt. Ändert sich bei einer Tabelle mehr als 20%+500 Datensätze (Update, Delete, Insert) wird die Statistik der Tabelle neu erzeugt. Bei 10000 Datensätzen müssten sich also 2500 Datensätze ändern, bis es zu einem Update in der Statistik gibt. Im schlimmsten Fall muss sich nur ein Datensatz ändern um bei einem Folge-Join zu einer explodierenden Datenmenge zu sorgen. In-the-Wild ist mir ein solches „Szenario“ aber noch nie unter gekommen.
- Parameter Sniffing/Spoofing + ExecutionPlan Caching: Für sich alleine genommen ist jede der beiden Technologien sinnvoll und hilfreich. In Kombination kann es jedoch zu erheblichen „Verklemmungen“ kommen. „Parameter Sniffing“ bezeichnet den Versuch des Query-Optimizers einen Execution Plan auf einen bestimmten Parameter-Tupel zu optimieren. Wird die Abfrage immer nur mit den gleichen Parametern ausgeführt oder nur einmal, beschleunigt das die Abfrage. Sorgt einer der Parameter z.B. dafür das eine große Tabelle auf wenige Datensätze reduziert wird, kann sich so die Lead-Tabelle ändern. Nachteilig wird das ganze wenn dieser Plan gecached wird. Bei der zweiten Ausführung der Abfrage wird der alte Execution Plan genutzt. Im schlimmsten Fall ist dieser falsch optimiert und führt zu unnötigen I/O – Operationen.
Gegen falsche Statistiken lässt sich recht einfach vorgehen. Man veranlasst einen Rebuild der entsprechenden Statistik oder erzeugt gleich alle Statistiken neu.
UPDATE STATISTICS-- erneuert nur die Statistik der angegeben Tabelle exec sp_updatestats -- baut alle Statistiken neu
Mit einem Statistik-Rebuild werden auch alle gecachten Execution-Pläne verworfen die von der Statistik abhängen.
Gegen Parameter-Sniffing hilft das leider nur temporär. Abfragen die mehrere „optimale“ Execution Pläne haben, sollten gesondert behandelt werden. Es gibt prinzipiell fünf Möglichkeiten das Problem endgültig zu beheben.
- der „sicherste“ weg: Wenn eine Abfrage in unterschiedlichen Kontexten genutzt wird, dupliziert man die Abfrage und ändert die Signatur ein wenig. Somit werden mehrere Abfragen gestellt, die getrennt optimiert werden.
- Kann man das Problem in eine StoredProcedure auslagern, kann man dort ein „ConditionalTree“ aufbauen. Also die Übergabeparameter analysieren und entsprechende Sub-StoredProcedures aufrufen. Die wiederum auf den speziellen Fall optimiert werden.
- Man kann auch das Parameter Sniffing unterdrücken. Dazu muss man aber ebenfalls auf Stored Procedures zurückgreifen.
CREATE PROCEDURE SelectSomething @parameter1 int, @parameter2 char DECLARE @parameter1_save int, @parameter2_save char AS SET @parameter1_save = @parameter1 SET @parameter2_save = @parameter2 SELECT * FROM tabelle1 t1 JOIN tabelle2 t2 WHERE t1.s1 = @parameter1_save AND t2.s1 = @parameter2_save
Die Parameterzuweisung kann vom Optimizer nicht vorhergesehen werden, deswegen wird der anschließende Select auf den allgemeinen Anwendungsfall optimiert.
- Kann man den Anwendungsbereich eines SELECTs von vornherein einschränken oder eingrenzen, kann man QueryOptimizer anweisen auf diesen Bereich hin zu optimieren.
SELECT * FROM tabelle1 t1 JOIN tabelle2 t2 WHERE t1.s1 = @parameter1 AND t2.s1 = @parameter2 OPTION (OPTIMIZE FOR(@parameter1 = ‘somevalue’,@parameter2 = ‘somevalue’ ));
-
Es gibt fälle wo alle bisher genannten Lösungsvarianten nicht greifen, da die Abfragen nicht getrennt werden können und die einzelnen Abfrage-Ziele so unterschiedlich sind, dass eine allgemeine Optimierung keinen Vorteil bringt. In diesem Fall kann man das DBMS anweisen, den ExecutionPlan nicht zu cachen bzw keine gecachten Plane zu nutzen.
SELECT * FROM tabelle1 t1 JOIN tabelle2 t2 WHERE t1.s1 = @parameter1 AND t2.s1 = @parameter2 OPTION (RECOMPILE)
In diesem Fall wird für diesen SELECT immer ein neuer ExecutionPlan erzeugt und nach der Ausführung sofort verworfen. So wird immer der „optimale“ ExecutionPlan genutzt. Dafür geht jetzt immer Zeit für das Erzeugen des Plans drauf.
Stromverbrauch der Seashell unter Karmic Koala
Wenn man Ubuntu 9.10 auf einem Netbook installiert, ist die Ausbeute des Akkus nicht optimal. Standardmäßig ist zwar der gnome-powersave-daemon aktiviert, dieser nutzt jedoch nicht das volle Potential. Ein Verbrauch von ca. 9 Watt und 4 Stunden Akkulaufzeit (ohne WLAN) ist nicht berauschend. Mit ein paar Handgriffen bekommt man aber den Verbrauch unter 6 Watt gedrückt und erreicht so die 6 Stunden Akkulaufzeit. Mein Rekord liegt bei knapp 7 Stunden, dabei war der Laptop jedoch nicht wirklich in Benutzung…
Erster Einstiegspunkt zum Stromsparen ist der „laptop_mode“-Tools. Diese sind standardmäßig installiert, jedoch deaktiviert. Dabei bieten sie wesentlich granularere Möglichkeiten das System auf „Sparsamkeit“ zu trimmen. Die wichtigen/benötigten Möglichkeiten kurz zusammen gefasst:
- Starten und Stoppen von Diensten: Im Batteriebetrieb ist der betrieb einiger Diensten unter Umständen nicht nötig oder nicht so wichtig, dass sie kritisch für das System sind. zb: der NTP dienst.
- das Abschalten von ungenutzten Video-Outs
- das Einschränken der verfügbaren Bandbreite bei Ethernet interfaces. 1000MBit sind selten wirklich nötig und kostet das ein oder andere Watt
Um den Dienst scharf zu schalten, muss man die Datei /etc/default/acpi-support bearbeiten.
# Switch to laptop-mode on battery power - off by default as it causes odd # hangs on some machines ENABLE_LAPTOP_MODE=true
Kleinere Änderungen müssen auch unter /etc/laptop-mode/conf.d/lcd-brightness.conf gemacht werden, da sich unter dem 1008HA das Interface für das LCD Display wo anders befindet.
BRIGHTNESS_OUTPUT="/proc/acpi/video/VGA/LCDD/brightness"
Die Werte für die Helligkeit können dabei zwischen 0 und 15 skalieren.
Weitere Änderungen können nach Wunsch in den Dateien unter /etc/laptop-mode/conf.d/ gamacht werden. Hier kann man nach belieben sämtliche Veränderungen vornehmen. Das meiste ist selbsterklärend. Dabei gilt immer, alles was man im Normalbetrieb nicht braucht, sollte man abschalten und bei bedarf zuschalten.
Neben diesen „banalen“ Änderungen gibt es noch andere Optimierungen.
Einen „großen“ Vorteil bringt es RamDisk einzusetzten. Solange man mechanische Festplatten einsetzt, ist einer der größten „Stromfresser“ eben diese Festplatte. Entweder leistet man sich bei Gelegenheit eine (sündhaft) teure SSD oder man sieht zu, dass man Mechanische Zugriffe auf die Festplatte so lange unterdrückt wie irgend möglich.
Eine RamDisk ist dabei die UltimaRatio. Mittels tempfs kann man im RAM einen Bereich reservieren, der anschließend in das FileSystem gemountet wird. So kann man zb. den Cache des Browsers oder „/var/log“ direkt in den RAM legen. Auf der haben Seite verbucht man damit, dass die Fesplatte über „lange“ Zeiträume nicht angetastet werden muss. Negativ ist halt, dass alle abgelegten Daten den Kaltstart nicht überleben werden.
Alle bisherigen Optimierungen nutzten nur vorhandene Techniken besser aus, ohne das System in die Instabilität zu treiben. Die weiteren Eingriffe gehen Tiefer und können das System komplett zerschießen. Anwendung auf eigene Gefahr.
Unter Jaunty gab es eine reihe von Traytools die die „Super Hybrid Engine“. Leider fühlten sich einige dieser Entwickler von der Ubuntu-Entwicklungs-Politik so angepisst, dass sie die Entwicklung eingestellt haben. So muss man sich inoffizieller Pakete bedienen die zu alle dem keiner Paketverwaltung unterliegen. Im Internet kann man eine brauchbare Tray-Control finden. Leider startet die auf Anhieb nicht. Da der Pyhton-Script das falsche interface für die Helligkeitssteuerung voraussetzt. Als erstes braucht man die korrekte Schnittstelle. Mittels folgendem befehl das Interface identifizieren:
find /sys/ | grep brightness
Anschließend in der Datei /usr/bin/eee-control-daemon diesen Wert in Zeile 85 und 86 einsetzten. Nun kann man den Dienst starten. Während die Steuerung der RF-KillSwitches nur leidlich funktioniert, kann man über dieses Tool die FSB-Tacktung reduzieren, Was nochmals ordentlich Stromersparnis bringt.
Etwas heickler ist das Abschalten des des AppArmor-Systems. Hier sollte man jedoch kurz inne halten! AppArmor dient zur Sicherung des Systems und stellt eine aktive Sicherheitsebene dar. Jedoch lässt sich für die Praxis eines Netbook-Einsatzes dessen Sinn vernachlässigen bzw in Frage stellen. Die Abschaltung von AppArmor brachte bei meinem System ca 0.5 Watt.
Hat man diesen Schritt einmal getan, ist es mit dem Selberbauen des Kernel auch nicht mehr weit. Der Karmic-Koala setzt auf den Standard-Kernel, dieser ist „leider“ ein generic-Kernel. Also ein Kernel der das größtmögliche Spektrum an Hardware und Spezialanwendungen unterstützt was sich der Jungs bei Chanonical vorstellen können.
Beim konfigurieren des Kernels kann man extrem viel ein und verstellen. Meiner Meinung nach gibt es kann man sich aber auf folgende Punkte beschränken:
- Zielarchitektur: Der Kernel sollte auf Core2Duo/Xeon optimiert werden, laut mehrere Internetquellen wird damit auch der Atom abgedeckt. Alle weiteren Optionen die andere X86 Architekturen unterstützen kann man abschalten.
- LargeMemory: Standardmäßig ist der Ubuntu-Kernel auf 4GB eingestellt. In der Seashell sind fest 1GB verbaut. Es braucht den Overhead also nicht.
- Virtualisierung: Wer will auf einem Atom mehrere virtuelle Gast-Systeme einrichten? Wer auch immer das macht, macht braucht sich um Stromverbrauch keine Gedanken machen 😉
- AppArmor: will man die Fehlermeldung beim Booten wegbekommen, schaltet man hier auch das Kernel-Interface für AppArmor ab.
Man kann auch Treiber „entfernen“ von denen man weiß das man sie nie brauchen wird. Jedoch bringt das außer einer kleineren InitRamDisk kaum Performance. Mehr bringt da schon das feste einkompilieren von Treibern. Wenn man viel Zeit hat, kann man einen Kernel bauen, der ohne InitRamDisk auskommt. Leider funktioniert dann dann UReadAhead nicht. Dieser dienst speichert alle Dateien die für einen Systemstart gebraucht werden sequenziell optimiert ab. So können sie besser von der Festplatte geladen werden. Leider scheint dieser ohne InitRD nicht klar zu kommen. Der Kernel bootet dann zwar schneller, da er keine RamDisk laden muss, das restliche System braucht dafür merklich länger.
Eine Beispiel Konfiguration hab ich hier bereitgestellt: EEE-Kernel.config
Alles in allem haben mir diese eingriffe rund 3 Watt Leistungsersparniss gebracht. Mit Durchschnittlich 35 WakeUps pro Sekunde ist das Ende aber noch nicht erreicht.
Wie man mit TOP den SQL Server lahmlegt
Eine „häufig“ genutzte Funktionalität des TSQL Befehlssatzes ist das TOP Statement. Es schränkt das Ergebnis Resultset auf eine vorgegebene Anzahl an Zeilen ein. Sinnvoll ist das ganze wenn man mehre gleichwertige Treffer in einer Ergebnissmenge hat, und nur einen Teil davon braucht.
Beispiel: von 1000 Läufern werden nur die selektiert, die die Strecke in einer vorgegebene Zeit zurück gelegt haben, sortiert nach der benötigten zeit aufsteigend. Aufs Treppchen kommen jedoch nur drei Läufer.
Der TSQL – Select dazu:
SELECT TOP 3 t.nachname,t.vorname,t.zeit FROM teilnehmer t JOIN rennen r on (t.rennen = r.rennen) JOIN strecke s on (r.strecke = s.strecke) WHERE t.Zeit < s.ZeitMax AND r.Veranstalltung = @veranstaltung ORDER BY t.ZEIT asc
Die landläufige "Halbwahrheit" dazu ist, dass TOP X nicht in den Execution Plan eingreift. Folglich der Select normal ausgeführt wird und nur die Ergebnis-Menge auf die ersten X Reihen beschränkt wird. Das ist gefährliches Halbwissen! Hier sind zwei Bilder die "eindrucksvoll" belegen, dass man sich mit einem TOP den ganzen Server lahmlegen kann.
Dem geübten SQL-Auge dürfte sofort (wenn man die Bilder in groß betrachtet) auffallen das ohne TOP Hash-Match-Joins genutzt werden, wohingegen bei dem TOP 100 Nested-Loop-Joins genutzt werden. Was man im Bild nur erahnen kann, ist der Umstand, das mit dieser Konstellation jeder MS-SQL Server in die Knie zu bekommen ist.
Nested-Loops skalieren ganz beschissen, nämlich linear. Was kein Problem ist, wenn die zu bearbeitende Treffermenge klein ist. Hier ist der Problem begraben. Dem TOP entnimmt der QueryOptimizer eine Information, eine Vorhersage wie viele Treffer zu erwarten sind. Der Select wird nicht ausgeführt und dann die Treffermenge beschnitten, sondern der Select wird solange ausgeführt bis die gewünschte Treffermenge erreicht ist oder der Select keine Ergebnisse mehr liefert.
Normalerweise ist dieses "Denken" auch richtig. Wenn die Treffermenge normalerweise 10k Trefferr enthält und darauf ein TOP 1 angewendet wird ist es Schwachsinnig erst die 10K Treffer zu ermitteln und dann 9999 davon weg zu schmeißen.
Umgekehrt kann man sagen, das für einen Treffer selten ein kompletter Full-Table-Scann bei allen beteiligten Tabellen benötigt wird. So wird je nach "Where"-Bedingung aus der Lead-Tabelle der erste Datensatz ermittelt und so lange an die Folgeoperationen durch gereicht, bis er in der Treffermenge landet oder Aufgrund einer Bedingung ausscheidet. Das wird solange wiederholt bis de gewünschte Trefferzahl erreicht wurde. Im Beispiel benötigte es im "Gutfall" für einen Treffer 70 "Reads" aus der Lead-Tabelle (die Tabelle ganz rechts).
Was passiert aber, wenn Aufgrund einer Sortierung die komplette Lead-Tabelle gelesen werden muss? Das bekommt der Optimizer mit und wechselt sofort auf Hash-Match-Joins. Leider erkennt der Optimizer nicht, dass es auch andere Gründe geben kann, warum die Treffermenge rapide hochgehen kann. Der ungünstigste Fall ist folgender:
Die letzte Operation vor dem "TOP"-Operator führt einen Filter aus, der alle gelieferten Datensätze ausschließt. So müssen alle vorherigen Tabellen komplett gescannt werden und alle ermittelten Datensätze durch die Nested-Loops Operatoren bearbeitet werden. Bei Tabellen mit 10k und mehr Datensätzen sprengt das jeglichen verfügbaren Speicher. Der Server geht augenblicklich in die Knie. Wenn man Glück hat, ist die Instanz in CPU und Speicherverbrauch eingeschränkt, so dass die anderen Instanzen unbeeinflusst bleiben. Wenn nicht, dürfte man seinem Kunden gegenüber in Erklärungsnot geraten...
Die Gegenmaßnahmen sind recht einfach:
- Ausschließen das es zu solchen Extrem-Situationen kommt, wo ein Datensatz erst den ganzen ExecutionPlan durchlaufen muss um dann ausgeschlossen zu werden.
- Keep it Simple - Selects mit Top sollten ohne große Where-Bedingung auskommen.
- Dem QueryOptimizer Hilfestellung über query-Hints geben.