El uso de un ordenador portátil de gráficos híbridos en linux

Introducción.

Tengo un ordenador portátil con los llamados gráficos híbridos. Es decir, tiene dos GPUs – uno de ellos es parte del SoC (Intel HD3000 GPU), la otra es la «discreta» Radeon HD 6630M PCIe de AMD. Typicaly, viejos modelos de computadoras portátiles de doble GPU (y las nuevas máquinas de Apple Macbook Pro) tienen un multiplexor que permite cambiar la salida de la GPU para mostrar. Como la mayoría de los ordenadores portátiles modernos, mi cuenta con una combinación de «muxless» de las GPUs – es decir, la GPU más potente no tiene ninguna conexión física con el panel de visualización. En su lugar, se puede escribir en la memoria del framebuffer de la GPU menos potente (o puede realizar sólo la parte computacional de OpenGL / DirectX y dejar que la GPU de dibujo 2D mango primaria y blitting).

El soporte de Linux para los gráficos híbridos aunque imperfecta. Para ser honesto, es un asco, incluso ahora que este tipo de portátil han estado dominando el mercado para algunas de 4-5 años ya. Con la reciente llegada de la interfaz «DRI-PRIME» el kernel linux y el espacio de usuario ahora es compatible con el uso de la GPU secundario para la descarga de las cargas de trabajo intensivas de gráficos. En este momento de utilizar la GPU independiente, una aplicación tiene que ser puesto en marcha con una variable de entorno especial (es decir, «DRI_PRIME = 1») y el sistema se supone que es dinámicamente encender el GPU cuando se necesita y apagarla para reducir el consumo de energía y calefacción en otros momentos. Por desgracia, el apoyo a la administración de energía es todavía profundamente roto. En este post voy a resumir mis conclusiones y scripts que permiten apagar el GPU externa permanente para ahorrar energía y aumentar la duración de la batería de la computadora portátil. No estoy usando la GPU secundaria porque OpenGL y X11 controladores de la GPU de Intel son más estables, y el conductor Radeon de código abierto / mesa aun no soporta OpenCL (API computacional para GPUs).

vga_switcheroo

La interfaz del núcleo para controlar la potencia de la GPU externa se llama «vga_switcheroo» y permite que apagar la GPU. Por desgracia, me he enterado de que mi ordenador portátil (y la mayoría de los otros) permiten a la GPU después de un ciclo de suspensión-reanudación. Creo que este comportamiento es intencionado, ya que las llamadas ACPI se deben utilizar para controlar la potencia de la GPU. Sin embargo, se confunde el vga_switcheroo que piensa que la tarjeta todavía está apagado. Mientras tanto, los drenajes de tarjetas de algunos 10-30 vatios de potencia, reduciendo efectivamente la duración de la batería de 7 horas hasta 2 horas o menos.

Mi primer intento de este problema fue un parche que obligó al vga_switcheroo a desactivar todas las cartas que no se llevaron a cabo por el espacio de usuario en el curriculum vitae. Esto se ha solucionado el problema por un tiempo, pero fue hacker y nunca lo hizo en el núcleo principal. Sin embargo, todavía es útil para los núcleos de Linux hasta 3,9.
Http://lkml.indiana.edu/hypermail/linux/kernel/1204.3/02530.html

kernel 3.10 +

A partir de la versión 3.10 de Linux, se realizaron varios cambios en lo que respecta a la administración de energía híbrida de gráficos. El primero es la introducción de la administración de energía dinámica (en forma de código de control de reloj y analizar los estados de energía predefinidos proporcionados por el OEM BIOS) para los chips Radeon. Segundo es el cambio en el vga_switcheroo que permitió que se apagara la tarjeta cuando no se use y sin la interacción del usuario. No funciona hasta cierto punto, pero el problema con la tarjeta que está encendido después de un ciclo de sueño-resume permanece />
El problema es que ahora, cuando puedo desactivar manualmente la tarjeta a través de la vga_switcheroo, el dispositivo PCI se ha ido – se retira y nunca vuelve a aparecer. El mismo comportamiento podría ser exhibido en la pre-kernels 3.10 si se emitió la orden de «eliminar» al nodo DRM (/ sys/class/drm/card1 /). Además, mi truco para la vga_switcheroo dejó de funcionar, ya que estas mejoras. Ahora bien, esto no me hace feliz y me dispuse a averiguar la solución.

Acpi_call poderes

Linux frente a la GPU Radeon utilizando el puente PCIe PCIe y GPU registros. Una forma «portátil» y «oficial» para controlar la potencia de una GPU está utilizando una llamada ACPI. ACPI es una interfaz para los equipos basados ​​en Intel X86 (aunque ahora también aplicado para las CPUs ARM en un intento de proporcionar el apoyo a UEFI, Windows RT y un kernel linux unificado binario capaz de funcionar con cualquier SoC ARM) destinado a proporcionar la abstracción de la enumeración de hardware y administración de energía. Contiene tablas con listas de (plug-and-play) periféricos que pueden ser utilizados por el kernel del sistema operativo en lugar de la peligrosa «sondear» mecanismo de PCI y otra PNP. Por otra parte, contiene una especificación para el lenguaje de código de bytes interpretado. Algunos métodos son implementados por el OEM en el interior de las tablas ACPI BIOS para realizar ciertas funciones – estado de la batería de consultas, el poder hacia arriba y hacia abajo los dispositivos etc
gente tiene desde figurado durante mucho tiempo fuera de usar llamadas ACPI en linux para controlar la potencia de la GPU discreta. A pesar de que podría interferir con la interfaz vga_switcheroo, en caso de que ya sea deshabilitar completamente la GPU o la alimentación externa si fuera a través de vga_switcheroo primero, estamos a salvo para usarlo. Por otra parte, he descubierto que puedo usar una llamada ACPI para encender el dispositivo y hacerlo visible para el sistema después se retira como se describe en el párrafo anterior
Existe un módulo para el kernel de Linux que permite realizar ACPI arbitraria las llamadas desde el espacio de usuario. Resulta que una llamada directa ACPI incluso puede evitar la nueva vga_switcheroo. Hay una buena guía sobre cómo instalar el módulo acpi_call al subsistema DKMS para que se empaqueta y se construye de forma automática cada vez que actualice el núcleo Linux en su machine.
http://garyservin.wordpress.com/2012/01/06/disabling-discrete-gpu-in-debian-gnulinux-wheezy/

El módulo contiene la secuencia de comandos turn_off_gpu.sh en la carpeta de ejemplos que se puede utilizar para apagar la GPU. Corrí él y tomó un aviso del método utilizado para mi portátil – fue la » _SB.PCI0.PEG0.PEGP._OFF» (lo que significa South Bridge -> controlador PCI 0 -> PCI Express Graphics -> PCI Express Graphics Port)

Ahora, me hizo el siguiente truco mágico:
echo» _SB.PCI0.PEG0.PEGP . _ON «> / proc / acpi / llamada
Y BANG! después de haber desaparecido cuando se apaga a través del vga_switcheroo, la GPU fue identificado por linux y activar de nuevo. Neato.

Poniendo todo junto.
Ahora el verdadero atolladero es que la tarjeta aún drena el poder después de la reanudación. Yo pensé que tenía que escribir un script que apagar la tarjeta. Es resultó que a veces si el portátil se despertó y luego inmediatamente se fue a dormir debido a alguna condición de carrera, systemd no se ha ejecutado el gancho currículum.
ACCIÓN == «cambio», SUBSYSTEM == «power_supply», RUN + = «/ etc / gpu_poweroff.sh»
ACCIÓN == «cambio», SUBSYSTEM == «drm», RUN + = «/ etc / gpu_poweroff.sh»

Ahora, cree el archivo / etc / gpu_poweroff.sh guión con los contenidos mencionados a continuación. Puede descomentar la «eco» llama a depurar la secuencia de comandos y verificar que está recibiendo llamadas. Por cierto, la parte power_profile no es necesaria, pero es un ejemplo de cómo poner una GPU Radeon en un estado de bajo consumo sin deshabilitarlo.

Gpu_poweroff.sh

# / bin / bash

# esto es un script para reducir el consumo de energía
# de GPUs Radeon en los ordenadores portátiles. comente cualquier parte
# de ella que no es necesario

# echo» guión gpu @ `date` «>> / tmp / foo

if [-e / sys / class / drm / card0], luego
for i in / sys / class / drm / tarjeta *; hacer
if [-e $ i / dispositivo / power_method], luego
perfil de eco> $ i / dispositivo / power_method
fi
if [-e $ i / dispositivo / power_profile], luego
echo bajo> $ i / / dispositivo power_profile
fi
hecho
fi

if [-d / sys / kernel / debug / vgaswitcheroo], luego
echo off> / sys / kernel / debug / vgaswitcheroo / switch
fi

acpi_methods = «
_SB.PCI0.P0P1.VGA._OFF
_SB.PCI0.P0P2.VGA._OFF
_SB_.PCI0.OVGA.ATPX
_SB_.PCI0.OVGA.XTPX
_SB.PCI0.P0P3.PEGP._OFF
_SB.PCI0. P0P2.PEGP._OFF
_SB.PCI0.P0P1.PEGP._OFF
_SB.PCI0.MXR0.MXM0._OFF
_SB.PCI0.PEG1.GFX0. _OFF
_SB.PCI0.PEG0.GFX0.DOFF
_SB.PCI0.PEG1.GFX0.DOFF
_SB.PCI0.PEG0.PEGP._OFF
_SB.PCI0.XVR0.Z01I.DGOF
_SB.PCI0.PEGR.GFX0._OFF
_SB.PCI0.PEG.VID._OFF
_SB.PCI0.PEG0.VID._OFF
_SB. PCI0.P0P2.DGPU._OFF
_SB.PCI0.P0P4.DGPU.DOFF
_SB.PCI0.IXVE.IGPU.DGOF
_SB.PCI0.RP00. VGA._PS3
_SB.PCI0.RP00.VGA.P3MO
_SB.PCI0.GFX0.DSM._T_0
_SB.PCI0.LPC.EC.PUBS. _OFF
_SB.PCI0.P0P2.NVID._OFF
_SB.PCI0.P0P2.VGA.PX02
_SB_.PCI0.PEGP.DGFX._OFF
_SB_.PCI0.VGA.PX02
_SB.PCI0.PEG0.PEGP.SGOF />
_SB.PCI0.AGP.VGA.PX02
«

# apagar el dGPU través de una llamada ACPI
if [-e / proc / acpi / llamada] y luego
for i in $ acpi_methods; hacer
echo $ i> / proc / acpi / llamada
hecho
# echo >> / tmp / foo
fi

salida 0

Que sea ejecutable mediante la emisión de un «chmod + x / etc / gpu_poweroff.sh « de comandos.
También, echar un vistazo a la» / etc / rc.local «. Si no existe, cree que con el siguiente contenido y hacerlo ejecutable:

# / bin / sh-e

#f1c232;»> exit 0

Si existe, inserte la llamada a la «/ etc / gpu_poweroff.sh» antes de la línea de «salida».

Bonus

Para silenciar los fans en el ordenador portátil Sony Vaio, puede añadir lo siguiente al script rc.local (aconsejo en contra de poner a la secuencia de comandos gpu_poweroff porque este comando tiene un retraso notable):

if [-e / sys / devices / platform / sony-laptop / thermal_control], luego
eco silencioso> / sys / devices / platform / sony-laptop / thermal_control
fi

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *