PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Low-Latency Desktop System



Shutdown
20.01.06, 14:33
Da Linux auch auf dem Desktop-Sektor immer mehr Bedeutung gewinnt, werden an Linux auch immer größere Ansprüche gestellt. Von Haus aus ist Linux so wie jedes andere Betriebssystem nicht perfekt und muss noch ein bisschen eingestellt werden, um die optimale Power aus dem Computer herauszuholen.
Viele Desktopuser sehen die Reaktionsgeschwindigkeit ihres Systems als sehr wichtig an, und da es ja immer mehr Linux-Desktop-PCs gibt, will ich hier ein paar Tipps & Tricks vorstellen, wie man seinem System ein bisschen mehr gefühlte Power verpassen kann.


1.) Hardware

Wenn die Hardware schlecht eingestellt ist, wird alles andere natürlich auch nicht mehr besser...man sollte bei der Hardware darauf achten, dass alles im System gut gekühlt ist, seinen PC ab und an mal auch innen entstauben und vor allem auch im BIOS darauf achten, dass alles richtig eingestellt ist.
Wer in seinem PC Grafik-, Sound-, TV- oder sonstige MultiMedia-Karten hat, sollte auch darauf achten, dass die Interrupt-Verteilung stimmt. Hier gibt es insbesondere mit TV-Karten oft heftige Probleme.
Die aktuelle IRQ-Belegung in eurem PC kriegt ihr mit einem einfachen "cat /proc/interrupts" in einem Terminal heraus.
Zuersteinmal sollten Grafik- und Soundkarten auf jeden Fall einen IRQ für sich bekommen, am besten auch einen mit hoher Priorität. Die Rangabfolge der IRQs ist folgende (höchste zuerst, niedrigste zuletzt): 0, 1, 8, 9, 10, 11, 12, 13, 14, 15, 3, 4, 5, 6, 7 .
PCI-Karten können in "normalen" PCs normalerweise die IRQs 9, 10 oder 11 bekommen. Sollten die IRQs nicht optimal verteilt sein, hilft meist nur die Karten in andere PCI-Slots umzusetzen, die IRQs sind bei den meisten Boards fest mit bestimmten Slots gekoppelt, teilweise kann man auch im BIOS Slots bestimmte IRQs zuweisen.


2.) Der Kernel

Ohne einen gut konfigurierten Kernel kann das System auch träge werden, man sollte bei der Konfiguration vor allem auf folgendes achten:

Processor type and features -->
_Processor family -->
__<Hier eure CPU auswählen>
_Preemption Model --->
__ Preemptible Kernel (Low-Latency Desktop)
_ Preempt The Big Kernel Lock
_Timer frequency -->
__ 1000 Hz

Außerdem können auch Patchsets wie z.B. das -ck Patchset (http://members.optusnet.com.au/ckolivas/kernel/), die die Latency des Systems verbessern sollen, nützlich sein. Beim -ck Patchset ist u.a. ein Patch enthalten, mit dem man 1 GB RAM voll nutzen kann, ohne den langsameren HighMem-Support aktivieren zu müssen und ein anderer Patch, der es Anwendungen von normalen Usern erlaubt, mit höherer Priorität zu laufen - nützlich bei MultiaMedia-Anwendungen wie xmms, xine oder dergleichen.

Aktuell in der Entwicklung befindet sich eine extremere Variante der Preemption-Optionen, die es momentan im Kernel gibt - mit ihr sollen Systeme annähernd Realtime-Reaktionen erreichen.
Beta-Patches gibt es auf der RedHat-FTP Seite von Ingo Molnar (http://people.redhat.com/mingo/realtime-preempt/), ich rate allerdings von der Beutzung ab, da das Risiko für Kernel Panics sehr hoch ist. In der Zukunft wird dieser Patch aber sehr wahrscheinlich äußerst interessant werden.

/!\ Achtung: Der 1GB-LowMem-Patch verursacht in Verbindung mit bestimmten Programmen Probleme, bekannte Probleme sind, dass VMware nicht läuft, xine mit Win32-Plugins und TightVNC unvorhersehbare Crashs produzieren.


3.) UserSpace-Software

Wer sich ein bisschen mit PCs auskennt, weiss, dass PCI-Karten eine individuelle Einstellung, genannt "Latency Timer", haben, über die geregelt wird, wie lange eine Karte Daten über den PCI-Bus schicken darf, bevor eine andere zum Zug kommt.
Im BIOS der meisten PCs kann man diesen Timer nur allgemein einstellen, die Karten individuell zu konfigurieren ist aber mit Linux problemlos möglich.
Mit den Tools "lspci" und "setpci" können diese Einstellungen ausgelesen und verändert werden. Man holt sich dazu die Adresse der jeweiligen Karte mit lspci und stellt den Timer dann mit setpci ein, hier ein kleines Beispiel:

# lspci -v
[...]
02:0c.0 Multimedia controller: Philips Semiconductors SAA7146 (rev 01)
Subsystem: Technotrend Systemtechnik GmbH Technotrend/Hauppauge DVB card rev2.1
Flags: bus master, medium devsel, latency 32, IRQ 9
Memory at feafd400 (32-bit, non-prefetchable) [size=512]
[...] Das ist meine TV-Karte, die von einer größeren latency als der üblichen 32 extrem profitieren kann. Die Adresse der Karte ist hier mit "02:0c.0" angegeben, nun stellen wir die latency auf 192 hoch, zu beachten ist hier lediglich, dass die Werte als Hexadezimalzahlen übergeben werden müssen und das Maximum bei 248 = f8 liegt. (Größere Werte werden auf 248 gesetzt, es gibt also keine Probleme wenn ihr auf die Schnelle zB ff als Maximum setzt)

# setpci -v -s 02:0c.0 latency_timer=c0
02:0c.0:0d c0

# lspci -v
[...]
02:0c.0 Multimedia controller: Philips Semiconductors SAA7146 (rev 01)
Subsystem: Technotrend Systemtechnik GmbH Technotrend/Hauppauge DVB card rev2.1
Flags: bus master, medium devsel, latency 192, IRQ 9
Memory at feafd400 (32-bit, non-prefetchable) [size=512]
[...]
Wer sich ein bisschen mit Scripts auskennt kann das nun dynamisch regeln lassen, je nachdem welche Programme laufen. Das folgende Script übernimmt diese Aufgabe und stellt alle 60 Sekunden die Latenzen, falls erforderlich, optimal ein.

/!\ Achtung! Im folgenden Script unbedingt die Adressen der Karten anpassen, diese können wie oben beschrieben über lspci -v ermittelt werden!
Eigene Programme können natürlich einfach hinzugefügt werden, ich habe ein paar Beispiele in das Script reingepackt. (Details siehe nächster Post)
Ich übernehme natürlich auch keinerlei Verantwortung dafür, was die Benutzung dieses Scripts evtl als Folgen nach sich ziehen könnte!

#! /bin/sh

echo "PCI LATENCY BOOSTER"
echo " v 0.1"
echo ""

VGA_ADDR="01:00.0"
DVB_ADDR="02:0c.0"
SND_ADDR="02:0b.0"
SATA_ADDR="02:0a.0"
NIC_ADDR="02:08.0"

VAL_ULTRA="c0"
VAL_HIGH="90"
VAL_MED="40"
VAL_LOW="20"

VGA_VAL=$VAL_HIGH
DVB_VAL=$VAL_LOW
SND_VAL=$VAL_LOW
SATA_VAL=$VAL_LOW
NIC_VAL=$VAL_LOW

VGA_VAL_OLD="0"
DVB_VAL_OLD="0"
SND_VAL_OLD="0"
SATA_VAL_OLD="0"
NIC_VAL_OLD="0"

KILLVAR="0"
while [ KILLVAR != "1" ]; do

DATEVAR=`date '+%Y-%m-%d %H.%M'`

VGA_VAL=$VAL_HIGH
DVB_VAL=$VAL_LOW
SND_VAL=$VAL_LOW
SATA_VAL=$VAL_LOW
NIC_VAL=$VAL_LOW

XINEVAR=`ps -A | grep xine`
if [ -n "$XINEVAR" ]; then
VGA_VAL=$VAL_ULTRA
SND_VAL=$VAL_HIGH
fi

XMMSVAR=`ps -A | grep xmms`
if [ -n "$XMMSVAR" ]; then
SND_VAL=$VAL_HIGH
fi

VDRVAR=`ps -A | grep vdr`
if [ -n "$VDRVAR" ]; then
DVB_VAL=$VAL_ULTRA
SATA_VAL=$VAL_MED
fi

PROJECTXVAR=`ps -A | grep projectx`
if [ -n "$PROJECTXVAR" ]; then
SATA_VAL=$VAL_HIGH
fi

GAMEVAR=`ps -A | grep -e ut2004 -e cedega`
if [ -n "$GAMEVAR" ]; then
VGA_VAL=$VAL_ULTRA
SND_VAL=$VAL_HIGH
fi

# -----------------------------------------------

if [ $VGA_VAL != $VGA_VAL_OLD ]; then
/sbin/setpci -v -s $VGA_ADDR latency_timer=$VGA_VAL > /dev/null 2>&1
echo "VGA : "$VGA_VAL" ["$DATEVAR"]"
fi

if [ $DVB_VAL != $DVB_VAL_OLD ]; then
/sbin/setpci -v -s $DVB_ADDR latency_timer=$DVB_VAL > /dev/null 2>&1
echo "DVB : "$DVB_VAL" ["$DATEVAR"]"
fi

if [ $SND_VAL != $SND_VAL_OLD ]; then
/sbin/setpci -v -s $SND_ADDR latency_timer=$SND_VAL > /dev/null 2>&1
echo "SND : "$SND_VAL" ["$DATEVAR"]"
fi

if [ $SATA_VAL != $SATA_VAL_OLD ]; then
/sbin/setpci -v -s $SATA_ADDR latency_timer=$SATA_VAL > /dev/null 2>&1
echo "SATA: "$SATA_VAL" ["$DATEVAR"]"
fi

if [ $NIC_VAL != $NIC_VAL_OLD ]; then
/sbin/setpci -v -s $NIC_ADDR latency_timer=$NIC_VAL > /dev/null 2>&1
echo "NIC : "$NIC_VAL" ["$DATEVAR"]"
fi

VGA_VAL_OLD=$VGA_VAL
DVB_VAL_OLD=$DVB_VAL
SND_VAL_OLD=$SND_VAL
SATA_VAL_OLD=$SATA_VAL
NIC_VAL_OLD=$NIC_VAL

sleep 60

done
Das Script muss natürlich als Root laufen oder zumindest mit sudo gestartet werden...setpci mit chmod auf suid zu setzen ist sicherlich keine gute Idee!!!

Wer diese Tipps berücksichtigt und sein System entsprechend einstellt wird sicherlich einen Vorteil davon haben :D
Anmerkungen, Verbesserungen oder andere Tipps sind hier natürlich mehr als nur Willkommen ;)

Links zum Thema:
-ck Patchset von Con Kolivas (http://members.optusnet.com.au/ckolivas/kernel/)
Einsatzmöglichkeiten für -ck, nützliche Tipps (http://ck.kolivas.org/faqs/audio_hints)
Realtime-Preemption Patches von Ingo Molnar (http://people.redhat.com/mingo/realtime-preempt/)
Linux hardware stability guide, part 1 (http://www-128.ibm.com/developerworks/linux/library/l-hw1/)
Linux hardware stability guide, part 2 (http://www-128.ibm.com/developerworks/library/l-hw2.html)

Shutdown

Shutdown
02.02.06, 21:42
Q: Wie kann ich herausfinden, ob ein bestimmtes Programm eine meiner Karten besonders stark fordert bzw viele IRQs erzeugen lässt?
A:

watch -n 5 cat /proc/interrupts
Beispiel-Output:

Every 5.0s: cat /proc/interrupts Wed Apr 19 11:41:44 2006

CPU0
0: 348292 XT-PIC timer
1: 1417 XT-PIC i8042
2: 0 XT-PIC cascade
3: 18166 XT-PIC uhci_hcd:usb1
5: 5708 XT-PIC libata
7: 2 XT-PIC saa7146 (0)
8: 1 XT-PIC rtc
9: 137 XT-PIC acpi, aic7xxx
10: 0 XT-PIC uhci_hcd:usb2, EMU10K1
11: 20108 XT-PIC eth0, nvidia
14: 26 XT-PIC ide0
15: 25 XT-PIC ide1
NMI: 0
LOC: 348222
ERR: 0
MIS: 0 1. Spalte: IRQs der Geräte
2. Spalte: Wie oft das Gerät seit der PC läuft einen IRQ gesendet hat
3. Spalte: Namen der Geräte bzw Gerätetreiber

Vorgehen:
1. Fragliches Programm starten, falls nötig dafür sorgen, dass es arbeitet oder eben macht was es soll
2. Watch-Befehl laufen lassen
3. Die Werte der Geräte (Namen der Gerätetreiber werden in der 3. Spalte aufgelistet), die interessant sind, in der 2. Spalte beobachten. Sollten die Werte schnell größer werden, ist das bestimmte Gerät am Arbeiten.
Die Größe der Werte ist von Gerätetyp zu Gerätetyp anders, generell kann man alles was mehr als +100 in 5 Sekunden ist, als deutliches Zeichen für Aktivität werten. TV-Karten schaffen bis zu +2000 in 5 Sekunden und mehr, Grafikkarten +500 und mehr. (Das Script gibt alle 5 Sekunden neue Werte aus)

/!\ Achtung: Wenn sich mehrere Geräte einen Interrupt teilen, zählen die erzeugten IRQs der Geräte zusammen! Also immer prüfen, ob das Gerät auch alleine die Änderungen der Werte verursacht!


*** *** ***


Q: Wie funktioniert das Script genau oder wie kann ich es für meinen PC anpassen?
A: Ich will hier noch auf ein paar kleine Details eingehen, die der ein oder andere vielleicht von alleine problemlos beherrscht, andere aber evtl nicht.
Das obige Script besteht wie wohl jeder sehen wird aus einer Endlosschleife, in der alle 60 Sekunden überprüft wird, ob bestimmte Programme laufen. Daraus werden dann Variablen Werte gegeben, die dann wiederum per setpci-Befehl also Latency für die PCI-Karten gesetzt werden.
IMHO ist diese Form die beste, da mit diesem Script nicht sämtliche Latenzen alle 60 Sekunden neu gesetzt werden, sondern nur die Latenzen, die andere Werte bekommen sollen wenn Programme gestartet oder beendet wurden.

Neue Gerätetypen können hinzugefügt werden indem man sich an den bereits vorhandenen orientiert, die Syntax einfach übernehmen.
Auf den ersten Blick kann das Script abschreckend kompliziert wirken, aber wenn man es sich genauer ansieht ist es eigentlich wirklich simpel aufgebaut. Also nehmt euch 10 Minuten um es wirklich zu verstehen wenn ihr unsicher seid! (Zur Not kann man mich auch Fragen, ich helfe gerne wenns wirklich klemmt und ihr wenigstens versucht habt, die Sache alleine anzugehen - aber auch bitte erstmal weiterlesen, jetzt kommen die Details ;) )
Neue Programme können auch hinzugefügt werden, indem man entweder einen neuen if-Block zur Programmabfrage hinzufügt oder einen bestehenden ergänzt, am Beispiel Quake3 würde man also einfach die GAMEVAR auf Quake3 ausweiten:
(Bei Nicht-Spielen, würde man sich einen if-Block suchen bzw erstellen, der halt die im Einzelfall geforderten Geräte-Variablen mit höheren Werten versieht)


GAMEVAR=`ps -A | grep -e quake3 -e ut2004 -e cedega`
if [ -n "$GAMEVAR" ]; then
VGA_VAL=$VAL_ULTRA
SND_VAL=$VAL_HIGH
fi

Zum Verständnis: "ps -A" gibt alle Laufenden Prozesse aus, "grep" filtert die Interessanten Sachen heraus, indem es alles was nicht mit "-e <Prozessname>" überprüft wird. Wenn nach dem Filtern nun etwas anderes als nichts übrigbleibt ( "if [ -n ..." ), werden die VGA- und SND-Variablen auf höhere Werte eingestellt.
Am Anfang jedes Schleifendurchlaufs stellt das Script alle Variablen auf Standard-Werte, prüft wieder nach Programmen und setzt dann ggf. neue Latenzen, wenn der Wert aus der vorherigen Schleife anders war.
Läuft nun ein Programm nicht mehr, das in der vorherigen Schleife gelaufen ist, wird der Wert nicht erhöht und die Werte der alten und aktuellen Schleife unterscheiden sich. Die Folge: setpci wird aufgerufen und setzt neue Latenzen.
Wenn ein Programm mehr läuft, wird der Wert eben erhöht und unterscheidet sich, auch dann wird natürlich setpci aufgerufen.
Die Überprüfung auf unterschiedliche Werte findet im unteren Teil des Scripts statt: "if [ ... != ... ] ... " - das "!=" bedeutet ungleich.
Am Anfang jeder Schleife wird *_VAL in *_VAL_OLD kopiert, dadurch hat man die Werte der vorhergehenden Schleife in der aktuellen konserviert und kann prüfen, ob sich etwas geändert hat.

Wer also ein bisschen was von Shell-Scripten versteht, sollte mit diesen Informationen ohne weitere Probleme in der Lage sein, sich das Script anzupassen.


*** *** ***


Q: Sind irgendwelche Probleme mit dem Script oder LowLatency allgemein bekannt?
A: Probleme mit den PCI-Latenzen oder meinem Script sind mir keine bekannt, aber der 1GB-LowMem-Patch für den Kernel kann mit einigen wenigen Programmen zu Problemen führen. Die mir bekannten Problemkinder sind im 1. Post im Punkt 2 (Kernel) angeführt.
Desweiteren habe ich als die Preemption-Features noch relativ neu im Kernel waren, von Problemen mit der Preemption gehört (Kernel Panics), aktuell ist mir hier aber nichts bedenkliches bekannt. Die Realtime-Preemption-Patches von Ingo Molnar funktionieren meist nicht und sind im Moment eh noch in der Beta-Phase, ich rate davon ab, sie zu benutzen.


*** *** ***


Falls es trotz allem noch ungeklärte Fragen gibt, ihr eine super Idee für einen anderen Kniff habt, wie man die Latenzen eines PCs weiter runterschrauben kann oder wenn ihr die FAQ hier gerne erweitert hättet, schickt mir ne PM und ich kümmere mich gerne drum :D

Shutdown