Linux - lepsze sterowanie zarządzaniem energii ACPI i fglrx.
21 listopada, 2008
Jakiś czas temu pisałem o fglrx i oszczędzaniu energii. Stwierdziłem, że znaczne ulepszenie istniejącego skryptu jest proste. Poniżej efekty w postaci dobrego zarządzania.
Jak pisałem, poprzednio były tylko dwa tryby: low power (przy pracy na zamkniętej pokrywie i na baterii), oraz default. Na dodatek wartości dobierane były na sztywno na podstwie tego, co aticonfig --lsp zwraca jako default i low.
Obecnie definiowane są 3 wartości:
- Praca przy zamkniętej pokrywie
- Praca na baterii i otwartej pokrywie
- Praca na zasilaczu i otwartej pokrywie
Wartości definiuje się wprost w pliku /etc/default/fglrx:
FGLRX_ACPI_SWITCH_POWERSTATES=true FGLRX_ACPI_LIDCLOSE_MODE=1 FGLRX_ACPI_BATTERY_MODE=2 FGLRX_ACPI_AC_MODE=3
Cyfry to oczywiście numery trybu zwracane przez aticonfig --lsp. W powyższym ustawieniu: jeśli zamykamy pokrywę (czyt. nie korzystamy z grafiki), to maksymalnie ją spowalniamy (jedyny powód, by tego nie robić to ogrzewanie mieszkania grafiką - pomijam), jeśli pracujemy na baterii, to pracujemy na średniej wydajności, a jeśli mamy prąd, to bierzemy ile fabryka dała. Oczywiście nie ma przeciwskazań, by ustawić np. wszędzie 1 (ja tak mam).
Największe modyfikacje to plik /etc/acpi/fglrx-powermode.sh. Obecnie wygląda on tak:
#!/bin/bash . /etc/default/fglrx if [ x$FGLRX_ACPI_SWITCH_POWERSTATES != xtrue ]; then exit; fi getXuser() { user=`finger| grep -m1 ":$displaynum " | awk '{print $1}'` if [ x"$user" = x"" ]; then user=`finger| grep -m1 ":$displaynum" | awk '{print $1}'` fi if [ x"$user" != x"" ]; then userhome=`getent passwd $user | cut -d: -f6` export XAUTHORITY=$userhome/.Xauthority else export XAUTHORITY="" fi } grep -q closed /proc/acpi/button/lid/*/state if [ $? = 0 ]; then lid_closed=1 else lid_closed=0 fi grep -q off-line /proc/acpi/ac_adapter/*/state if [ $? = 0 ]; then on_dc=1 else on_dc=0 fi if [ ${lid_closed} -eq 1 ]; then echo "fglrx: setting low power" for x in /tmp/.X11-unix/*; do displaynum=`echo $x | sed s#/tmp/.X11-unix/X##` getXuser; if [ x"$XAUTHORITY" != x"" ]; then export DISPLAY=":$displaynum" powermode=$FGLRX_ACPI_LIDCLOSE_MODE if [ x"$powermode" != x"" ]; then su $user -c "/usr/bin/aticonfig --set-powerstate=$powermode --effective=now" &>/dev/null fi fi done else if [ ${on_dc} -eq 0 ]; then echo "fglrx: setting AC powermode" for x in /tmp/.X11-unix/*; do displaynum=`echo $x | sed s#/tmp/.X11-unix/X##` getXuser; if [ x"$XAUTHORITY" != x"" ]; then export DISPLAY=":$displaynum" powermode=$FGLRX_ACPI_AC_MODE if [ x"$powermode" != x"" ]; then su $user -c "/usr/bin/aticonfig --set-powerstate=$powermode --effective=now" &>/dev/null fi fi done else echo "fglrx: setting battery powermode" for x in /tmp/.X11-unix/*; do displaynum=`echo $x | sed s#/tmp/.X11-unix/X##` getXuser; if [ x"$XAUTHORITY" != x"" ]; then export DISPLAY=":$displaynum" powermode=$FGLRX_ACPI_BATTERY_MODE if [ x"$powermode" != x"" ]; then su $user -c "/usr/bin/aticonfig --set-powerstate=$powermode --effective=now" &>/dev/null fi fi done fi fi
Skrypt nie był testowany na okoliczność błędów typu niezdefiniowana czy błędna wartość dla któregoś trybu, poza tym wygląda, że działa OK. Zachęcam do poprawek/uwag.