ビデオメモリにスワップ

提供: ArchWiki
2022年4月10日 (日) 15:24時点におけるAshMyzk (トーク | 投稿記録)による版 (→‎FUSE filesystem: 追加)
ナビゲーションに移動 検索に移動
この記事あるいはセクションは翻訳の途中です。
ノート: 本記事は 2016-03-26 の記事の翻訳です。最新情報は英語版をご確認ください。 (議論: トーク:ビデオメモリにスワップ#)

関連記事

システムのスワップとしてビデオメモリを利用する方法の簡単な記事です。

MTD カーネルサブシステム

メリット

グラフィックカードに搭載された GDDR SDRAM や DDR SDRAM はカーネルの MTD サブシステムを使うことでスワップとして利用することができます。専用のグラフィックメモリが 256 MB 以上存在してシステムメモリ (DDR SDRAM) の量が限られている場合、グラフィックメモリにスワップを設定する価値があります。

警告:
  • バイナリドライバでは上手く行きません。
  • グラフィックドライバーが使用するメモリを設定しないと、スワップとして使われてるメモリにテクスチャを保存しようとして Xorg がクラッシュする可能性があります。ビデオメモリを上書きすることで出来るビデオドライバーを使用することで安定性が増します。

カーネルの要件

メインラインカーネルの MTD はバージョン 2.6.23 から利用できます。

事前設定

MTD モジュールを有効にしたカーネルを実行している場合、ビデオカードのメモリに対応する PCI アドレスの領域を指定してモジュールをロードしてください。

利用可能なメモリ領域を確認するには、以下のコマンドを実行して VGA compatible controller のセクションをチェックしてください:

$ lspci -vvv
01:00.0 VGA compatible controller: NVIDIA Corporation GK104 [GeForce GTX 670] (rev a1) (prog-if 00 [VGA controller])
	Subsystem: ASUSTeK Computer Inc. Device 8405
	Control: I/O+ Mem+ BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr- Stepping- SERR- FastB2B- DisINTx-
	Status: Cap+ 66MHz- UDF- FastB2B- ParErr- DEVSEL=fast >TAbort- <TAbort- <MAbort- >SERR- <PERR- INTx-
	Latency: 0
	Interrupt: pin A routed to IRQ 57
	Region 0: Memory at f5000000 (32-bit, non-prefetchable) [size=16M]
	Region 1: Memory at e8000000 (64-bit, prefetchable) [size=128M]
	Region 3: Memory at f0000000 (64-bit, prefetchable) [size=32M]
	Region 5: I/O ports at e000 [size=128]
	[virtual] Expansion ROM at f6000000 [disabled] [size=512K]
	Capabilities: <access denied>
	Kernel driver in use: nvidia
	Kernel modules: nouveau, nvidia
ノート:
  • 複数の GPU が搭載されている場合、複数のエントリが表示されます。
  • 使用するグラフィックカードに GDDR5 SDRAM が 2 GB 以上搭載されていても、上記のコマンドで全ての容量が出力されることはありません。

最も利用価値が高いのは prefetchable で64ビットで容量が一番大きな region です。

ビデオカードを機能させるにはメモリが多少必要なので、計算が必要です。オフセットは2の累乗で簡単に計算できます。グラフィックカードはアドレス領域の最初の部分をテクスチャなどに使います。この記事の冒頭で書いたように、2つのプログラムが同じセクタに書き込みを行うと、安定性に問題が生じます。

警告: 以下の例は古くなっており正確ではありません。

例: グラフィックメモリが合計で 256 MB ある場合、式は 2^28 になります (2の28乗)。グラフィックメモリに約 64 MB 残すとするとグラフィックメモリの中でスワップに使用する領域は 2^26 で計算されます。

上の値を使って、差を取ってスワップメモリに使用する容量を決定してください。通常の動作には 2^24 (32M) 残せば十分です。

セットアップ

slram モジュールを設定:

# /etc/modprobe.d/modprobe.conf
options slram map=VRAM,0xStartRange,+0xUsedAmount

起動時にモジュールをロード:

# /etc/modules-load.d/vramswap.conf
slram
mtdblock

systemd サービスを作成:

# /usr/lib/systemd/system/vramswap.service
[Unit]
Description=Swap on Video RAM

[Service]
Type=oneshot
ExecStart=/usr/bin/mkswap /dev/mtdblock0
ExecStart=/usr/bin/swapon /dev/mtdblock0 -p 10
ExecStop=/usr/bin/swapoff /dev/mtdblock0
RemainAfterExit=yes

[Install]
WantedBy=multi-user.target

Xorg ドライバーの設定

X を安定化させるために、検出されているビデオメモリよりも少ないメモリしか使用しないようにビデオドライバーを設定する必要があります:

/etc/X11/xorg.conf.d/vramswap.conf
Section "Device"
    Driver "radeon" # or whichever other driver you use
    VideoRam 32768
	#other stuff
EndSection

上記の例ではグラフィックメモリの 32 MB だけを使用するように指定しています。

ノート: ドライバーによってはビデオメモリの値を MiB で指定します。man ページを参照してください。

トラブルシューティング

以下のコマンドを使うことでディスクパーティションやフラッシュディスク、あるいはこのページのビデオメモリのように、様々な領域で使われているスワップを確認できます:

$ swapon -s

参照

FUSE filesystem

This method works on hardware with OpenCL support using a FUSE filesystem backing a swapfile. See GPGPU for more information.

Setup

First, install vramfs-gitAUR. Then, create an empty directory as mount point (e.g /tmp/vram).

Now run the following commands to set up the vramfs and a swapfile.

# vramfs /tmp/vram 256MB -f # Substitute 256M with your target vramfs size
# dd if=/dev/zero of=/tmp/vram/swapfile bs=1M count=200 # Substitute 200 with your target swapspace size in MiB
# chmod 0600 /tmp/vram/swapfile
# mkswap -U clear /tmp/vram/swapfile

Your Swap should now be ready. Run swapon to check.

See Swap#Swap file for more information.

ノート: This is not persistent and will be gone after a system reboot.
ヒント: You can also use /tmp/vram as temporary storage, much like a Tmpfs.

Troubleshooting

swapon: /tmp/vram/swapfile: skipping - it appears to have holes.

The swapfile created is not contiguous. A loop device can be set up to work around this issue.

# cd /tmp/vram
# LOOPDEV=$(losetup -f)
# truncate -s 4G swapfile # replace 4G with target swapspace size, has to be smaller than the allocated vramfs
# losetup $LOOPDEV swapfile
# mkswap $LOOPDEV
# swapon $LOOPDEV

See also