ハイブリッドグラフィックス
ハイブリッドグラフィックは同一のコンピュータで2つのグラフィックカードを動作させるというコンセプトで、始めはノートパソコンの電力消費量を抑える目的で構想され、今ではデスクトップのコンピュータにも拡張されています。
目次
ハイブリッドグラフィックのテクノロジーについて
一つのコンピュータで二つのグラフィックカードを使用して、高いパフォーマンスと省電力の両方を達成する、新しいテクノロジーがノートパソコンのメーカーによって開発されました。このテクノロジーは Windows ではしっかりとサポートされていますが、Linux ディストリビューションでは未だ実験的な段階です。
性能と電力消費量が異なる二組のグラフィックカードをハイブリッドグラフィックと呼称します。様々なテクノロジーが存在し、問題を解決するために個々のメーカーによって独自の方法が開発されています。このページでは、それぞれのアプローチとモデルについて軽く説明し、そして GNU/Linux システムのサポートがないことに対するコミュニティによるソリューションを紹介します。
"旧式"のハイブリッドモデル (ベーシックな切り替え)
This approach involves a two graphic card setup with a hardware multiplexer (MUX). It allows power save and low-end 3D rendering by using an Integrated Graphics Processor (IGP); or a major power consumption with 3D rendering performance using a Dedicated/Discrete Graphics Processor (DGP). This model makes the user choose (at boot time or at login time) within the two power/graphics profiles and is almost fixed through all the user session. The switch is done by a similar workflow:
- Turn off the display
- Turn on the DGP
- Switch the multiplexer
- Turn off the IGP
- Turn on again the display
This switch is somewhat rough and adds some blinks and black screens in laptops that could do it "on the fly". Later approaches made the transition a little more user-friendly.
新しい動的な切り替えモデル
Most of the new Hybrid-graphics technologies involves two graphic cards as the basic switching but now the DGP and IGP are plugged to a framebuffer and there is no hardware multiplexer. The IGP is always on and the DGP is switched on/off when there is a need in power-save or performance-rendering. In most cases there is no way to use only the DGP and all the switching and rendering is controlled by software. At startup, the Linux kernel starts using a video mode and setting up low-level graphic drivers which will be used by the applications. Most of the Linux distributions then use X.org to create a graphical environment. Finally, a few other softwares are launched, first a login manager and then a window manager, and so on. This hierarchical system has been designed to be used in most of cases on a single graphic card.
Nvidia Optimus
現状の問題
- Switching between cards when possible.
- Switching on/off the discrete card.
- Be able to use the discrete card for 3D render.
- Be able to use both cards for 3D render (problem arised in this post).
ソフトウェアによるソリューション
- asus_switcheroo -- ASUS などハードウェアマルチプレクサが搭載されたノートパソコンで Intel/Nvidia を切り替えるためのソリューション。開発者: Alex Williamson。
- byo_switcheroo -- vga_switcheroo を使ってカードを切り替える (acpi_call のような) ハンドラを作成するためのソリューション。開発者: Alex Williamson。
- vga_switcheroo -- Intel/ATI ノートパソコンが対象のオリジナルの GPU 切り替えソリューション。開発者: David Airlie。
- acpi_call -- ディスクリートのグラフィックカードの電源を切ってバッテリーを伸ばすことができます。開発者: Michal Kottman。
- PRIME -- 長い間開発中の Optimus ソリューション。開発者: David Airlie。
- Bumblebee -- ディスクリートのグラフィックカードで指定したプログラムを実行することができ、内蔵のグラフィックカードで X セッションを動かすことができます。Nvidia の Optimus カードで動作。開発者: Martin Juhl。
- hybrid-windump -- Nvidia を使って Intel のディスプレイにウィンドウを投げます。開発者: Florian Berger と Joakim Gebart。
- gpu-switchAUR -- gpu-switch はデュアル GPU の MacBook Pro で、内蔵・外部 GPU を次の起動時に切り替えるアプリケーションです。
- systemd-vgaswitcheroo-unitsAUR -- AMD/NVIDIA & Intel のデュアル GPU 構成で起動時にディスクリート GPU を無効化します。
ATI Dynamic Switchable Graphics
Nvidia のテクノロジーに似ている新しいテクノロジーで、ハードウェアマルチプレクサを使用しません。
現状の問題
The Dynamic Switch needs Xorg support for the discrete videocard assigned for rendering to work [1]. So, rendering on the discrete gpu will not work until the Xorg team adds support for it.
This means that with a muxless intel+ati design, you cannot use your discrete card by simply modprobing the radeon module.
As of now, there are 2 choices:
- Test and improve some virtualGL based program to make the switch, like the common-amd branch of bumblebee project. Check the project repository and this useful post.
- Use the proprietary driver with powerxpress (a.k.a. pxp) support maintained by Vi0l0 (remember to check for xorg compatibility).
ディスクリート GPU の完全な電源オフ
高性能なグラフィックプロセッサの電源を切って電力を抑えたい場合、AUR から acpi_call-gitAUR パッケージをインストールすることで行うことが可能です。
インストールしたらカーネルモジュールをロードしてください:
modprobe acpi_call
カーネルモジュールをロードしたら以下を実行します (root 権限が必要です):
turn_off_gpu.sh
This script will go through all the known data buses and attempt to turn them off. You will get an output similar to the following:
Trying \_SB.PCI0.P0P1.VGA._OFF: failed Trying \_SB.PCI0.P0P2.VGA._OFF: failed Trying \_SB_.PCI0.OVGA.ATPX: failed Trying \_SB_.PCI0.OVGA.XTPX: failed Trying \_SB.PCI0.P0P3.PEGP._OFF: failed Trying \_SB.PCI0.P0P2.PEGP._OFF: failed Trying \_SB.PCI0.P0P1.PEGP._OFF: failed Trying \_SB.PCI0.MXR0.MXM0._OFF: failed Trying \_SB.PCI0.PEG1.GFX0._OFF: failed Trying \_SB.PCI0.PEG0.GFX0.DOFF: failed Trying \_SB.PCI0.PEG1.GFX0.DOFF: failed Trying \_SB.PCI0.PEG0.PEGP._OFF: works! Trying \_SB.PCI0.XVR0.Z01I.DGOF: failed Trying \_SB.PCI0.PEGR.GFX0._OFF: failed Trying \_SB.PCI0.PEG.VID._OFF: failed Trying \_SB.PCI0.PEG0.VID._OFF: failed Trying \_SB.PCI0.P0P2.DGPU._OFF: failed Trying \_SB.PCI0.P0P4.DGPU.DOFF: failed Trying \_SB.PCI0.IXVE.IGPU.DGOF: failed Trying \_SB.PCI0.RP00.VGA._PS3: failed Trying \_SB.PCI0.RP00.VGA.P3MO: failed Trying \_SB.PCI0.GFX0.DSM._T_0: failed Trying \_SB.PCI0.LPC.EC.PUBS._OFF: failed Trying \_SB.PCI0.P0P2.NVID._OFF: failed Trying \_SB.PCI0.P0P2.VGA.PX02: failed Trying \_SB_.PCI0.PEGP.DGFX._OFF: failed Trying \_SB_.PCI0.VGA.PX02: failed
See the "works"? This means the script found a bus which your GPU sits on and it has now turned off the chip. To confirm this, your battery time remaining should have increased. Currently, the chip will turn back on with the next reboot to get around this we do the following:
Add the kernel module to the array of modules to load at boot:
/etc/modules-load.d/acpi_call.conf
#Load 'acpi_call.ko' at boot. acpi_call
To turn off the GPU at boot we could just run the above script but honestly that is not very elegant so instead lets make use of systemd's tmpfiles.
/etc/tmpfiles.d/acpi_call.conf
w /proc/acpi/call - - - - \\_SB.PCI0.PEG0.PEGP._OFF
The above config will be loaded at boot by systemd. What it does is write the specific OFF signal to the /proc/acpi/call
file. Obviously, replace the \_SB.PCI0.PEG0.PEGP._OFF
with the one which works on your system (please note that you need to escape the backslash).