玩式草子─ソフトウェアとたわむれる日々

第52回X、MesaそしてLLVMその3]

前回までに、LLVM、MesaLibとビルドを進め、ようやくXorgサーバを動かせるところまで辿りつきました。起動したサーバの情報をxdpyinfoで調べると、バージョン1.14.2であることは確認できたものの、果してこのサーバは本当にMesaLibが提供しているドライバやLLVMが提供しているライブラリを使っているのでしょうか?

Xorgサーバのように多くの部品から構成されている複雑なソフトウェアでは、一見正しく動作しているように見えても、実は想定した機能が利用できずにフォールバックモードで動いていた、ということもよくあります。そこでXorgサーバの動作を詳しく調べてみることにしました。

Xorgサーバのログファイル

Xorgサーバは/var/logディレクトリにXorg.0.logという名称のログファイルを作成し、起動時に認識したハードウェアやロードした各種モジュールについて記録しています。そこで、まずこのログファイルを眺めてみました。

$ cat -n /var/log/Xorg.0.log
    1   [415001.067] 
    2   X.Org X Server 1.14.2
    3   Release Date: 2013-06-25
    4   [415001.067] X Protocol Version 11, Revision 0
    5   [415001.067] Build Operating System: Linux 3.8.13-plamo64 x86_64 
    6   [415001.067] Current Operating System: Linux corei7 3.11.1-plamo64 #1 SMP PREEMPT Fri Sep 2014:48:13 JST 2013 x86_64
    7   [415001.067] Kernel command line: BOOT_IMAGE=/boot/vmlinuz-3.11.1-plamo64 root=/dev/sdc2 ro vga16 unicon=eucjp vt.default_utf8=0 panic_output=7
    8   [415001.067] Build Date: 29 August 2013  05:11:53PM
     ....

ログファイルの先頭部分では、起動しているXorgサーバのバージョン(1.14.2)やソースコードの公開日(2013-06-25⁠⁠、ビルドされた環境(Linux 3.8.13-plamo64 x86_64⁠⁠、現在動いている環境(Linux corei7 3.11.1-plamo64..)起動時のカーネルパラメータ、ビルドされた日時等の情報が記録されています。動作中の環境はXorgサーバをビルドした環境から更新されていることも正しく認識しています。

ログファイルを読み進めていくと、現在のABI(Application Binary Interface)設定についての記述がありました。前回にも触れましたが、Xorgサーバのように、必要なモジュールドライバを動的に組み込んで動作するソフトウェアでは、両者のABIのバージョンを合わせておく必要があります。

    39  [415001.148] (II) Module ABI versions:
    40  [415001.148]    X.Org ANSI C Emulation: 0.4
    41  [415001.148]    X.Org Video Driver: 14.1
    42  [415001.148]    X.Org XInput driver : 19.1
    43  [415001.148]    X.Org Server Extension : 7.0

実際のモジュール類のロードがこのあたりからです。76行目からはlibglamoregl.soというglamor_eglパッケージとしてビルドしたモジュールドライバをロードしていることが記録されています。このモジュールドライバのバージョンは0.5.0、Xorgサーバ1.14.2用にコンパイルされ、ANSI C Emulationのバージョン0.4というABIでサーバとやりとりするようです。

    72  [415001.151] Initializing built-in extension DRI2
    73  [415001.151] (II) "glx" will be loaded by default.
    74  [415001.151] (II) LoadModule: "dri2"
    75  [415001.151] (II) Module "dri2" already built-in
    76  [415001.151] (II) LoadModule: "glamoregl"
    77  [415001.151] (II) Loading /usr/lib64/xorg/modules/libglamoregl.so
    78  [415001.152] (II) Module glamoregl: vendor="X.Org Foundation"
    79  [415001.152]    compiled for 1.14.2, module version = 0.5.0
    80  [415001.152]    ABI class: X.Org ANSI C Emulation, version 0.4

もう少し先から、利用しているグラフィックカード用のドライバのロードが始まります。今使っているのは、AMD(ATI⁠⁠ RADEON HD5770を使ったグラフィックカードなので、それを利用するためにati_drv.soradeon_drv.soがロードされています。バージョン番号やABIの情報から、新しくビルドしたモジュールと確認できます。

    94  [415001.161] (II) LoadModule: "ati"
    95  [415001.161] (II) Loading /usr/lib64/xorg/modules/drivers/ati_drv.so
    96  [415001.170] (II) Module ati: vendor="X.Org Foundation"
    97  [415001.170]    compiled for 1.14.2, module version = 7.2.0
    98  [415001.170]    Module class: X.Org Video Driver
    99  [415001.170]    ABI class: X.Org Video Driver, version 14.1
   100  [415001.170] (II) LoadModule: "radeon"
   101  [415001.170] (II) Loading /usr/lib64/xorg/modules/drivers/radeon_drv.so
   102  [415001.177] (II) Module radeon: vendor="X.Org Foundation"
   103  [415001.177]    compiled for 1.14.2, module version = 7.2.0
   104  [415001.177]    Module class: X.Org Video Driver
   105  [415001.177]    ABI class: X.Org Video Driver, version 14.1

この後しばらくは、RADEONドライバが認識したハードウェア情報が続きますが、そのあたりは省略して先を見ていくと、MesaLibが提供しているドライバをロードしている部分がありました。

   486  [415001.344] (II) RADEON(0): [DRI2] Setup complete
   487  [415001.344] (II) RADEON(0): [DRI2]   DRI driver: r600
   488  [415001.344] (II) RADEON(0): [DRI2]   VDPAU driver: r600
   489  [415001.345] (II) RADEON(0): Front buffer size: 8000K
   490  [415001.345] (II) RADEON(0): VRAM usage limit set to 929451K
   491  [415001.345] (==) RADEON(0): Backing store disabled
   492  [415001.345] (II) RADEON(0): Direct rendering enabled

手元のRADEON HD5700は、AMD GPUの世代的に言うとR600よりも2世代くらい後のEvergreenと呼ばれる世代になります。しかしながら、AMD GPUの基本設計は次のNorthern Island世代までは共通しているようで、MesaLibではr600ドライバがr600、r700、Evergreen、Northern IslandまでのGPUに対応しています。

488行目にあるVDPAUとは、Video Decode and Presentation API for Unixと呼ばれる最近のGPUが持っている動画再生機能を使うためのライブラリで、それも正しくR600用のドライバが利用されているようです。

各種ライブラリのメモリマップ

/var/log/Xorg.0.logを調べた限りでは、新しくビルドしたXorgサーバとそれに対応したドライバは正しく動作しているようです。しかしながら、このログファイルだけではXorgサーバがr600のドライバを使っていることはわかるものの、r600のドライバが本当にLLVMのライブラリを利用しているのかまではわかりません。

動作しているバイナリファイル(Xorgサーバ)が実際にどのようなライブラリを利用しているのかは、procファイルシステムを使って調べることができます。

procファイルシステムは、/procディレクトリにマウントされる仮想的なファイルシステムで、カーネルが管理していてユーザ環境からは直接アクセスすることができない動作中のプロセスについての情報を、ユーザ環境に提供するために用意されています。

$ ls /proc
1/      17345/  28944/  29142/  29299/  30213/  3367/  3621/  5/     7623/        fs/           scsi/
10/     17346/  28960/  29145/  29300/  30429/  3379/  3634/  5036/  8/           interrupts    self@
11/     18/     28973/  29150/  29303/  3046/   3396/  3701/  5037/  8099/        iomem         slabinfo
 ...

UNIX/Linuxの設計思想では、ハードウェアを直接操作するカーネルは特権モードで動作して、ユーザ環境で動作するアプリケーションからは直接アクセスできないようになっています。しかしながら、両者の分離を徹底しすぎると不便なことも多いので、Linuxではカーネルの内部情報をprocファイルシステム経由でユーザ環境のアプリケーションに公開すると共に、アプリケーションからいくつかの設定を変更することを認めています。

procファイルシステムに現われた数字だけのディレクトリは、その数字をプロセスIDとするプロセスについて、カーネルが管理している各種情報を提供するために使われます。

動作しているXorgサーバのプロセスIDはpsコマンドで知ることができます。

$ ps ax | grep X
 8832 pts/5    S+     0:00 grep X
28973 tty1     S+     0:00 xinit /home/kojima/.xinitrc -- /usr/bin/X :0
28974 tty7     Ssl+   7:20 /usr/bin/X :0

現在、動作しているXorgサーバのプロセスIDは28974なので、/proc/28974がXorgサーバの動作状態を提供するディレクトリになります。なお、procファイルシステムを参照する際にはroot権限が必要となることが多いので、以下の操作ではsudoを介して実行しています。

$ sudo ls -F /proc/28974
auxv             cpuset   limits     mountstats     pagemap      stack      wchan
cgroup           cwd@     loginuid   net/           personality  stat
clear_refs       environ  maps       ns/            root@        statm
cmdline          exe@     mem        oom_adj        sched        status
comm             fd/      mountinfo  oom_score      sessionid    syscall
coredump_filter  fdinfo/  mounts     oom_score_adj  smaps        task/

このディレクトリにあるファイルやディレクトリには動作しているプロセスについての各種情報が収められています。これらのうちからmapsというファイルを参照して、プロセスが利用しているメモリの状態(メモリのマッピング情報)を調べてみます。

$ sudo cat /proc/28974/maps
00400000-00604000 r-xp 00000000 08:22 1603887                            /usr/bin/Xorg
00803000-00811000 rw-p 00203000 08:22 1603887                            /usr/bin/Xorg
00811000-03e12000 rw-p 00000000 00:00 0                                  [heap]
7f02269f8000-7f0226d93000 rw-s 114f2c000 00:0d 6251                      /dev/dri/card0
7f022712e000-7f022712f000 rw-s 10c57d000 00:0d 6251                      /dev/dri/card0
...
7f022c3bd000-7f022cbbd000 rw-p 00000000 00:00 0                          [stack:28977]
7f022cbbd000-7f022cc9d000 r-xp 00000000 08:22 1576862                    /usr/lib64/libstdc++.so.6.0.16
7f022cc9d000-7f022ce9c000 ---p 000e0000 08:22 1576862                    /usr/lib64/libstdc++.so.6.0.16
7f022ce9c000-7f022cea4000 r--p 000df000 08:22 1576862                    /usr/lib64/libstdc++.so.6.0.16
7f022cea4000-7f022cea6000 rw-p 000e7000 08:22 1576862                    /usr/lib64/libstdc++.so.6.0.16
7f022cea6000-7f022cebb000 rw-p 00000000 00:00 0 
7f022cebb000-7f022cf73000 r-xp 00000000 08:22 1602804                    /usr/lib64/libLLVMSupport.so
7f022cf73000-7f022d173000 ---p 000b8000 08:22 1602804                    /usr/lib64/libLLVMSupport.so
7f022d173000-7f022d179000 rw-p 000b8000 08:22 1602804                    /usr/lib64/libLLVMSupport.so
7f022d179000-7f022d17b000 rw-p 00000000 00:00 0 
7f022d17b000-7f022d2d0000 r-xp 00000000 08:22 1602806                    /usr/lib64/libLLVMCore.so
7f022d2d0000-7f022d4d0000 ---p 00155000 08:22 1602806                    /usr/lib64/libLLVMCore.so
7f022d4d0000-7f022d4dc000 rw-p 00155000 08:22 1602806                    /usr/lib64/libLLVMCore.so
7f022d4dc000-7f022d515000 r-xp 00000000 08:22 1602826                    /usr/lib64/libLLVMObject.so
7f022d515000-7f022d714000 ---p 00039000 08:22 1602826                    /usr/lib64/libLLVMObject.so
...
7f0231e8b000-7f0231e8d000 rw-p 00036000 08:22 1602818                    /usr/lib64/libLLVMVectorize.so
7f0231e8d000-7f0232468000 r-xp 00000000 08:22 1597588                    /usr/lib64/dri/r600_dri.so
7f0232468000-7f0232668000 ---p 005db000 08:22 1597588                    /usr/lib64/dri/r600_dri.so
7f0232668000-7f02326c3000 rw-p 005db000 08:22 1597588                    /usr/lib64/dri/r600_dri.so
7f02326c3000-7f02328a4000 rw-p 00000000 00:00 0 
...
7f02334fc000-7f0233558000 r-xp 00000000 08:22 1603363                    /usr/lib64/xorg/modules/drivers/radeon_drv.so
7f0233558000-7f0233757000 ---p 0005c000 08:22 1603363                    /usr/lib64/xorg/modules/drivers/radeon_drv.so
7f0233757000-7f0233763000 rw-p 0005b000 08:22 1603363                    /usr/lib64/xorg/modules/drivers/radeon_drv.so
7f0233763000-7f0233764000 r-xp 00000000 08:22 1603361                    /usr/lib64/xorg/modules/drivers/ati_drv.so
7f0233764000-7f0233964000 ---p 00001000 08:22 1603361                    /usr/lib64/xorg/modules/drivers/ati_drv.so
7f0233964000-7f0233965000 rw-p 00001000 08:22 1603361                    /usr/lib64/xorg/modules/drivers/ati_drv.so
 ...

上記のように、mapsファイルにはXorgサーバ自身が利用しているライブラリやドライバモジュール類、さらにそれらドライバモジュールが利用しているライブラリが、メモリ上のどの位置に配置されているかが表示されています。今回ビルドしたXorgサーバは確かにLLVMのライブラリを組み込んで動作しています。

MesaLibの状況

X Window SystemはOpenGLのような3Dグラフィック技術が生まれるはるか以前に開発が始まったので、動作にOpenGLは必須ではありません。そのためX Window System用に開発されてきたソフトウェアのOpenGLへの対応はバラつきがあるのが現状です。しかしながら、現在も開発が続いているソフトウェアでは、次第にOpenGLにも積極的に対応するようになってきました。

たとえば、KDE4環境ではOpenGLに対応したPlasmaと呼ばれる機能が画面描画等を一手に引き受けており、⁠3Dグラフィックを利用した仮想画面切り替え」といったデスクトップ効果を使うことができます。

図1 デスクトップキューブを使った仮想デスクトップの切り替え例
図1 デスクトップキューブを使った仮想デスクトップの切り替え例

このような機能を持つため、KDEではKInfocenterと呼ばれるシステム情報を表示するツールでも、XサーバとともにOpenGLに関する詳しい情報が確認できます。

図2 KInfocenterのOpenGL情報
図2 KInfocenterのOpenGL情報

この結果を見ても、MesaLib 9.2.2のGallium3Dフレームワークのドライバとradeonカーネルモジュールが正しく認識されていることがわかります。

さて、それではこの環境のOpenGLの性能はどれくらいなのでしょう? 今回構築したOpenGL環境は、カーネルに付属のradeonモジュールとMesaLibが提供するDRI用ドライバ、X Window Systemの提供するradeon用ドライバ、というソースコードが公開されたソフトウェアのみを組み合わせて実現しています。

一方、AMDやNVIDIAといったグラフィックカードメーカは、自社製のグラフィックカード用にソースコードを(一部)公開していないLinux版のドライバを提供しています。それらのドライバには製造元のみが知る非公開のノウハウや機能が盛り込まれていて、OSS版のドライバよりも高性能と考えられています。そこで今回は、AMDが提供しているCatalyst-13.11-beta-v9.4というドライバと比較してみることにしました。

図3 KInfocenterで見たAMD Catalystドライバ
図3 KInfocenterで見たAMD Catalystドライバ

OpenGLの性能テストには、Geeks3d.comが公開しているGpuTestというツールを試してみました。このツールはOpenGLのさまざまな機能の性能(速度)を7種のテストから測定するように構成されています。

図4 GpuTestのfurmarkテスト
図4 GpuTestのfurmarkテスト

GpuTestが提供している各テストを試してみると、AMD Catalystのドライバは7種のテスト全てを実行できるものの、MesaLibのドライバでは、OpenGL 4.0の機能を必要とするTessMarkは実行不能、GiMarkと2種のPixMarkテストはドライバのバグで計測不能となり、実行できた残り3種のテストでも、成績はAMD Catalystドライバに大きく引き離される、という結果になりました。

FurMarkGiMarkPixMark PianoPixMark VolplosionPlot3DTessMark (X16/X16)Triangle
AMD Catalyst1272273330510681713310914267133
MesaLib633N/AN/AN/A10094N/A65195

あれこれ苦労してMesaLibのドライバをビルドしてきたことを考えるとやや残念な結果ですが、このあたりはGPUの製造元に一日以上の長があるということでしょう。もっとも、KDEのPlasma環境を使っている程度では両者の差は感じませんし、AMD Catalystドライバが自社製のグラフィックカードのみを対象とするのに対し、MesaLibはより広い視点から、IntelやNVIDIAのカードにも共通のフレームワークで対応しようとしています。LLVMと組み合わせたこのGallium3Dフレームワークはまだまだ発展途上で、開発者たちは性能改善に日夜取り組んでいることを忘れてはならないでしょう。

おすすめ記事

記事・ニュース一覧