LinuxでNvidiaもIntelもおかしなことになっているのでRadeonにかえてみた

もういやだ

パワフルなThinkStation P720ワークステーションだが、最近様子がおかしい。 Nvidiaではおなじみの

  • 画面が点滅する
  • X11 APIでスクリーンキャストするとウィンドウが消えてしまう (だからスクリーンショットでもウィンドウが消える)

という問題は直る気配がない…どころか、従来はVblankとFlippingを禁止すれば抑制できたのだが、最近はダメだ。 さらにいえば、Nvidia固有だったこの問題は、最近ではIntelでも発生する、というかINtelのほうがひどくなっている。

そして、追加で

  • Libreofficeが使っているSAL PLUGINとglibの連携が腐ってしまって、ほとんど操作不能なレベルでフリーズする
  • Vivaldiでありとあらゆる操作においてフリーズする

という問題が追加された。 Libreofficeの問題は最初Nvidiaだけだったが、現在はIntelでも発生するし、SAL_USE_VCLPLUGIN=genで防げたのだが、現在はこれも無理である。

そして、4kディスプレイにしてからビデオメモリが足りないのか、ウィンドウを開いていくとウィンドウ領域がグリッド状に表示され、かすかにウィンドウが見える場合もあるがほとんどの場合見えず、操作もできないという状態になる、ということに悩まされた。 作業効率が恐ろしく悪いことになってしまうため、毎日とてもストレスだし、貴重な時間を、1日で1-2時間程度失っている状態だった。

もうこれは耐えられない。

一方、Godavariはこのような問題を発生しない。 「じゃあGodavariでやれよ」と思うかもしれないが、Godavariは全面的にとっても非力である。よく馬鹿にされるくらいには。

それで、現在の出費は痛いし、TSMCは7mmプロセッサを控えている状態だというのはわかっているが、 結局のところRadeon 3000シリーズは噂の域を出ないということも踏まえて、思い切ってRadeon RX580を購入することにした。

なぜRX580か

最大の理由はLinuxにおけるパフォーマンスである。

WindowsにおいてはVega RXもそれなりの性能を示すようだが、Linuxにおいては多くの場合Vega RXとの性能差は誤差の範疇に留まる。 Vega RXでもGTX1060は越えない、というような所ぅたいだ。

にもかかわらずVega RXはずっと高値を維持しており、相当にコストパフォーマンスが悪い。 しかも、Vega RXはNvidiaと比べても相当燃費が悪いようで、「電気をめちゃくちゃ食う」のである。

そもそも私のP720はQuadro P6000のSLIを想定しているためキャパシティとしては耐えられないこともないのだが、家の電気回線はそうではないし、 無駄な電気は使いたくない。

また、Vega RXのパフォーマンスはVega RX 64であっても「Nvidia GTX1070に届かない程度」というのがWindowsにおいても現実であるようで、 ゲームのことを考えて高性能なカードを選ぶ、という気にもなれなかった。

タイミングは悪いなぁ、やたら高いなぁと思いつつも、Linuxにおいてはベストな選択肢となりそうなRX580を選択したということだ。

製品はAMD専門メーカーSapphireのゲーミング向けNITRO+シリーズSA-RX580-8GDN+001V2 VD6801を選択した。 オーバークロック製品で、発熱量は多いが性能は高いようだ。

P720にSapphire NITRO+ RX580は「ギリギリ入る」

製品が届いてびっくりした。 「大きい」

いやもう、比べるのが無意味なぐらい大きい。 「ミドルクラスだし、GTX960と同じくらいだろう」とか思ってサイズのことは一切気にしなかったのだが、「これはやばいかもしれない」と感じるほど大きかった。 ゲーミング向けトップモデルはこれより大きいのか!?

入らないかもしれない、と懸念したが、結局はギリギリながら収まった。 上下とも入るが、下段に関しては電源配線に触れてしまう。 また、サイドパネルに接触するため、サイドパネルがしめづらくなる。

「普通に入る」とは言い難い、「かろうじて入った」である。 だが、入る。

なお、SA-RX580-8GDN+001V2は補助電源が8ピン+6ピンというGTX1080Ti並の要求で、P720の標準の補助電源は2本であるためこれを全部使ってしまい、SLI構成はできない。 汎用の拡張コネクタがあるのだが、こちらは専用品で、なおかつLenovoとして単体の販売はしていないので、Crossfire構成にしたい場合は予めP6000のような「補助電源を2つ使う」ビデオカードを2枚構成にしておく必要がある。

クーリングパイプがまるでインテークマニホールドのようで、さらにSAPPHIREのロゴが青く輝き、大変かっこいい。 まぁ、P720の場合サイドパネルが透明なわけでもないので、全く見えないが。

消費電力は

4114+Quadro P400構成と比較すると、アイドル時で107Wと、約60W増えた。 運用時も140から220Wで、60W増加と見ていいだろう。 ただし、変動しやすくなったため、平均すると80W増加とみたほうがいいかもしれない。

ただし、変動しやすくなったのは、「今までP400で処理しきれなかった分を即座に処理する瞬発力があるため」と見ることができ、効率的には変わっていないかもしれない。

「省電力」という印象はなくなってしまったが、性能を考えればまぁ想定通りといったところ。

問題は解消したか

ほぼyesである。

  • 画面の点滅はなくなった。代わりにログイン時に画面がおかしくなることがあるが、支障は実際にはない
  • スクリーンショット、及びスクリーンキャスティングでウィンドウが消える不具合はなくなった
  • Libreofficeがフリーズする問題は解消された
  • Vivaldiが異様にフリーズするという問題は 軽減された
  • ウィンドウが表示できなくなる問題は解消された

また、私が非常に不満としていた、私お気に入りのフラゲ1が重すぎるという問題が事実上解消された。

この問題自体はつい先日からChromiumがマルチスレッドでFlashを処理してくれるようになり、最大で12.5%(5スレッド)で処理してくれるためにかなり軽減されてはいたのだが、 ビデオ描画のもたつきがなくなったためか、全く支障なくなった。 不思議なものだ。 まぁ、Flashはビデオアクセラレーションの対象ではあるのだが。

ちなみに、このゲームがあまりにも重いのは「4114が非力で、うち特有の問題」と考えていたのだが、先日Thinkpad X1でやってみたところ、とてもプレイできないくらい重かった。 というわけで、むしろ「このハイパフォーマンスマシンですらもこの程度」という状態だったと考えられる。 恐らくはWindowsであれば支障ないのだろう。

Vivaldiの重さはどこから

RX580になってVivaldiが操作のたびに、あるいはフォーカスするたびに止まる (タブ=レンダリングプロセスが止まるのではなく、Vivaldi全体が止まる)という問題は解消された。

ちなみに、Intelはこの問題はより深刻で、Vivaldiを立ち上げたあとメニュー操作をするとウィンドウマネージャごと固まってしまう。

だが、依然としてふたつの問題がある。

ひとつは、右クリックでメニューを開くとかなり長い時間固まるということだ。 これはstraceしてみると

read(17, "!", 2)                        = 1
write(18, "!", 1)                       = 1
openat(AT_FDCWD, "/usr/local/share/fonts/Commercial/FONT-COMP-SET21/Fontstyles2/FontGraphic_Mac/UniversalWalk.otf", O_RDONLY) = 251
fstat(251, {st_mode=S_IFREG|0644, st_size=8832, ...}) = 0
mmap(NULL, 8832, PROT_READ, MAP_PRIVATE, 251, 0) = 0x7fc6fd5f7000
close(251)                              = 0
munmap(0x7fc6fd5f7000, 8832)            = 0
openat(AT_FDCWD, "/usr/local/share/fonts/Commercial/FONT-COMP-SET21/Fontstyles2/FontGraphic_Mac/UniversalWalk.otf", O_RDONLY) = 251
fstat(251, {st_mode=S_IFREG|0644, st_size=8832, ...}) = 0
mmap(NULL, 8832, PROT_READ, MAP_PRIVATE, 251, 0) = 0x7fc6fd5f7000
close(251)                              = 0
munmap(0x7fc6fd5f7000, 8832)            = 0
openat(AT_FDCWD, "/usr/local/share/fonts/Commercial/FONT-COMP-SET21/Fontstyles2/FontGraphic_Mac/UniversalWalk.otf", O_RDONLY) = 251
fstat(251, {st_mode=S_IFREG|0644, st_size=8832, ...}) = 0
mmap(NULL, 8832, PROT_READ, MAP_PRIVATE, 251, 0) = 0x7fc6fd5f7000
close(251)                              = 0
munmap(0x7fc6fd5f7000, 8832)            = 0
openat(AT_FDCWD, "/usr/local/share/fonts/Commercial/FONT-COMP-SET21/Fontstyles2/FontGraphic_Mac/UniversalWalk.otf", O_RDONLY) = 251
fstat(251, {st_mode=S_IFREG|0644, st_size=8832, ...}) = 0
mmap(NULL, 8832, PROT_READ, MAP_PRIVATE, 251, 0) = 0x7fc6fd5f7000
close(251)                              = 0
munmap(0x7fc6fd5f7000, 8832)            = 0
openat(AT_FDCWD, "/usr/local/share/fonts/Commercial/FONT-COMP-SET21/Fontstyles2/FontGraphic_Mac/UniversalWalk.otf", O_RDONLY) = 251
fstat(251, {st_mode=S_IFREG|0644, st_size=8832, ...}) = 0
mmap(NULL, 8832, PROT_READ, MAP_PRIVATE, 251, 0) = 0x7fc6fd5f7000
close(251)                              = 0
munmap(0x7fc6fd5f7000, 8832)            = 0
openat(AT_FDCWD, "/usr/local/share/fonts/Commercial/FONT-COMP-SET21/Fontstyles2/FontGraphic_Mac/UniversalWalk.otf", O_RDONLY) = 251
fstat(251, {st_mode=S_IFREG|0644, st_size=8832, ...}) = 0
mmap(NULL, 8832, PROT_READ, MAP_PRIVATE, 251, 0) = 0x7fc6fd5f7000
close(251)                              = 0
munmap(0x7fc6fd5f7000, 8832)            = 0
openat(AT_FDCWD, "/usr/local/share/fonts/Commercial/FONT-COMP-SET21/Fontstyles2/FontGraphic_Mac/UniversalWalk.otf", O_RDONLY) = 251
fstat(251, {st_mode=S_IFREG|0644, st_size=8832, ...}) = 0
mmap(NULL, 8832, PROT_READ, MAP_PRIVATE, 251, 0) = 0x7fc6fd5f7000
close(251)                              = 0
munmap(0x7fc6fd5f7000, 8832)            = 0
openat(AT_FDCWD, "/usr/local/share/fonts/Commercial/FONT-COMP-SET21/Fontstyles2/FontGraphic_Mac/UniversalWalk.otf", O_RDONLY) = 251
fstat(251, {st_mode=S_IFREG|0644, st_size=8832, ...}) = 0
mmap(NULL, 8832, PROT_READ, MAP_PRIVATE, 251, 0) = 0x7fc6fd5f7000
close(251)                              = 0
madvise(0x3a38dab69000, 57344, MADV_DONTNEED) = 0
madvise(0x3a38dab69000, 57344, MADV_DONTNEED) = 0
madvise(0x3a38d9095000, 8994816, MADV_DONTNEED) = 0
madvise(0x3a38dab69000, 57344, MADV_DONTNEED) = 0
madvise(0x3a38dab69000, 57344, MADV_DONTNEED) = 0
madvise(0x3a38dab69000, 57344, MADV_DONTNEED) = 0
madvise(0x3a38dab8b000, 49152, MADV_DONTNEED) = 0
madvise(0x3a38d9095000, 8994816, MADV_DONTNEED) = 0
access("/usr/local/share/fonts/DeletedManjaro/UmePlus/umeplus-p-gothic.ttf", R_OK) = 0
madvise(0x3a38dab8b000, 385024, MADV_DONTNEED) = 0
madvise(0x3a38dab69000, 57344, MADV_DONTNEED) = 0
madvise(0x3a38dab69000, 57344, MADV_DONTNEED) = 0
madvise(0x3a38dab69000, 57344, MADV_DONTNEED) = 0
madvise(0x3a38dab8b000, 49152, MADV_DONTNEED) = 0
madvise(0x3a38d9095000, 8994816, MADV_DONTNEED) = 0
access("/usr/share/fonts/TTF/DejaVuSans.ttf", R_OK) = 0
madvise(0x3a38dab8b000, 385024, MADV_DONTNEED) = 0
madvise(0x3a38dab69000, 57344, MADV_DONTNEED) = 0
madvise(0x3a38dab69000, 57344, MADV_DONTNEED) = 0
madvise(0x3a38dab69000, 57344, MADV_DONTNEED) = 0
madvise(0x3a38dab8b000, 49152, MADV_DONTNEED) = 0
madvise(0x3a38d9095000, 8994816, MADV_DONTNEED) = 0
access("/usr/local/share/fonts/Monospace/font-bh-ttf-1.0.3/luxisr.ttf", R_OK) = 0
madvise(0x3a38dab8b000, 385024, MADV_DONTNEED) = 0
madvise(0x3a38dab69000, 57344, MADV_DONTNEED) = 0
madvise(0x3a38dab69000, 57344, MADV_DONTNEED) = 0
madvise(0x3a38dab69000, 57344, MADV_DONTNEED) = 0
madvise(0x3a38dab8b000, 49152, MADV_DONTNEED) = 0
madvise(0x3a38d9095000, 8994816, MADV_DONTNEED) = 0
access("/usr/share/fonts/gsfonts/NimbusSans-Regular.otf", R_OK) = 0
madvise(0x3a38dab8b000, 385024, MADV_DONTNEED) = 0
madvise(0x3a38dab69000, 57344, MADV_DONTNEED) = 0
madvise(0x3a38dab69000, 57344, MADV_DONTNEED) = 0
madvise(0x3a38dab69000, 57344, MADV_DONTNEED) = 0
madvise(0x3a38dab8b000, 49152, MADV_DONTNEED) = 0
madvise(0x3a38d9095000, 8994816, MADV_DONTNEED) = 0
access("/usr/share/fonts/TTF/MuktiNarrow.ttf", R_OK) = 0
madvise(0x3a38dab8b000, 385024, MADV_DONTNEED) = 0
madvise(0x3a38dab69000, 57344, MADV_DONTNEED) = 0
madvise(0x3a38dab69000, 57344, MADV_DONTNEED) = 0
madvise(0x3a38dab69000, 57344, MADV_DONTNEED) = 0
madvise(0x3a38dab8b000, 49152, MADV_DONTNEED) = 0
madvise(0x3a38d9095000, 8994816, MADV_DONTNEED) = 0
access("/usr/share/fonts/TTF/malayalam.ttf", R_OK) = 0
madvise(0x3a38dab8b000, 385024, MADV_DONTNEED) = 0
madvise(0x3a38dab69000, 57344, MADV_DONTNEED) = 0
madvise(0x3a38dab69000, 57344, MADV_DONTNEED) = 0
madvise(0x3a38dab69000, 57344, MADV_DONTNEED) = 0
madvise(0x3a38dab8b000, 49152, MADV_DONTNEED) = 0
madvise(0x3a38d9095000, 8994816, MADV_DONTNEED) = 0
access("/usr/share/fonts/TTF/Sampige.ttf", R_OK) = 0
madvise(0x3a38dab8b000, 385024, MADV_DONTNEED) = 0
madvise(0x3a38dab69000, 57344, MADV_DONTNEED) = 0
madvise(0x3a38dab69000, 57344, MADV_DONTNEED) = 0
madvise(0x3a38dab69000, 57344, MADV_DONTNEED) = 0
madvise(0x3a38dab8b000, 49152, MADV_DONTNEED) = 0
madvise(0x3a38d9095000, 8994816, MADV_DONTNEED) = 0
access("/usr/share/fonts/TTF/padmaa-Medium-0.5.ttf", R_OK) = 0
madvise(0x3a38dab8b000, 385024, MADV_DONTNEED) = 0
madvise(0x3a38dab69000, 57344, MADV_DONTNEED) = 0
madvise(0x3a38dab69000, 57344, MADV_DONTNEED) = 0
madvise(0x3a38dab69000, 57344, MADV_DONTNEED) = 0
madvise(0x3a38dab8b000, 49152, MADV_DONTNEED) = 0
madvise(0x3a38d9095000, 8994816, MADV_DONTNEED) = 0
access("/usr/share/fonts/TTF/VL-Gothic-Regular.ttf", R_OK) = 0
madvise(0x3a38dab8b000, 385024, MADV_DONTNEED) = 0
madvise(0x3a38dab69000, 57344, MADV_DONTNEED) = 0
madvise(0x3a38dab69000, 57344, MADV_DONTNEED) = 0
madvise(0x3a38dab69000, 57344, MADV_DONTNEED) = 0
madvise(0x3a38dab8b000, 49152, MADV_DONTNEED) = 0
madvise(0x3a38d9095000, 8994816, MADV_DONTNEED) = 0
access("/usr/share/fonts/OTF/ipag.ttf", R_OK) = 0
madvise(0x3a38dab8b000, 385024, MADV_DONTNEED) = 0
madvise(0x3a38dab69000, 57344, MADV_DONTNEED) = 0
madvise(0x3a38dab69000, 57344, MADV_DONTNEED) = 0
madvise(0x3a38dab69000, 57344, MADV_DONTNEED) = 0
madvise(0x3a38dab8b000, 49152, MADV_DONTNEED) = 0
madvise(0x3a38d9095000, 8994816, MADV_DONTNEED) = 0
access("/usr/share/fonts/TTF/TSCu_Paranar.ttf", R_OK) = 0
madvise(0x3a38dab8b000, 385024, MADV_DONTNEED) = 0
madvise(0x3a38dab69000, 57344, MADV_DONTNEED) = 0
madvise(0x3a38dab69000, 57344, MADV_DONTNEED) = 0
madvise(0x3a38dab69000, 57344, MADV_DONTNEED) = 0
madvise(0x3a38dab8b000, 49152, MADV_DONTNEED) = 0
madvise(0x3a38d9095000, 8994816, MADV_DONTNEED) = 0
access("/usr/share/fonts/TTF/NanumGothic.ttf", R_OK) = 0
madvise(0x3a38dab8b000, 385024, MADV_DONTNEED) = 0
madvise(0x3a38dab69000, 57344, MADV_DONTNEED) = 0
madvise(0x3a38dab69000, 57344, MADV_DONTNEED) = 0
madvise(0x3a38dab69000, 57344, MADV_DONTNEED) = 0
madvise(0x3a38dab8b000, 49152, MADV_DONTNEED) = 0
madvise(0x3a38d9095000, 8994816, MADV_DONTNEED) = 0
access("/usr/local/share/fonts/Korean/UnDotumBold.ttf", R_OK) = 0
madvise(0x3a38dab8b000, 385024, MADV_DONTNEED) = 0
madvise(0x3a38dab69000, 57344, MADV_DONTNEED) = 0
madvise(0x3a38dab69000, 57344, MADV_DONTNEED) = 0
madvise(0x3a38dab69000, 57344, MADV_DONTNEED) = 0
madvise(0x3a38dab8b000, 49152, MADV_DONTNEED) = 0
madvise(0x3a38d9095000, 8994816, MADV_DONTNEED) = 0
access("/usr/local/share/fonts/Commercial/Unknown/CODE2000.ttf", R_OK) = 0
madvise(0x3a38dab8b000, 385024, MADV_DONTNEED) = 0
madvise(0x3a38dab69000, 57344, MADV_DONTNEED) = 0
madvise(0x3a38dab69000, 57344, MADV_DONTNEED) = 0
madvise(0x3a38dab69000, 57344, MADV_DONTNEED) = 0
madvise(0x3a38dab8b000, 49152, MADV_DONTNEED) = 0
madvise(0x3a38d9095000, 8994816, MADV_DONTNEED) = 0
access("/usr/local/share/fonts/Morisawa/\343\203\222\343\203\251\343\202\256\343\203\216\344\270\270\343\202\264 Pr6N W4.otf", R_OK) = 0
madvise(0x3a38dab8b000, 385024, MADV_DONTNEED) = 0
madvise(0x3a38dab69000, 57344, MADV_DONTNEED) = 0
madvise(0x3a38dab69000, 57344, MADV_DONTNEED) = 0
madvise(0x3a38dab69000, 57344, MADV_DONTNEED) = 0
madvise(0x3a38dab8b000, 49152, MADV_DONTNEED) = 0
madvise(0x3a38d9095000, 8994816, MADV_DONTNEED) = 0
access("/usr/local/share/fonts/Morisawa/\343\203\222\343\203\251\343\202\256\343\203\216\344\270\270\343\202\264 Upr W4.otf", R_OK) = 0
madvise(0x3a38dab8b000, 385024, MADV_DONTNEED) = 0
madvise(0x3a38dab69000, 57344, MADV_DONTNEED) = 0
madvise(0x3a38dab69000, 57344, MADV_DONTNEED) = 0
madvise(0x3a38dab69000, 57344, MADV_DONTNEED) = 0
madvise(0x3a38dab8b000, 49152, MADV_DONTNEED) = 0
madvise(0x3a38d9095000, 8994816, MADV_DONTNEED) = 0
access("/usr/share/fonts/TTF/Mathematica6.ttf", R_OK) = 0
madvise(0x3a38dab8b000, 385024, MADV_DONTNEED) = 0
madvise(0x3a38dab69000, 57344, MADV_DONTNEED) = 0
madvise(0x3a38dab69000, 57344, MADV_DONTNEED) = 0
madvise(0x3a38dab69000, 57344, MADV_DONTNEED) = 0
madvise(0x3a38dab8b000, 49152, MADV_DONTNEED) = 0
madvise(0x3a38d9095000, 8994816, MADV_DONTNEED) = 0
access("/usr/share/fonts/TTF/Mathematica7.ttf", R_OK) = 0
madvise(0x3a38dab8b000, 385024, MADV_DONTNEED) = 0
madvise(0x3a38dab69000, 57344, MADV_DONTNEED) = 0
madvise(0x3a38dab69000, 57344, MADV_DONTNEED) = 0
madvise(0x3a38dab69000, 57344, MADV_DONTNEED) = 0
madvise(0x3a38dab8b000, 49152, MADV_DONTNEED) = 0
madvise(0x3a38d9095000, 8994816, MADV_DONTNEED) = 0
access("/usr/share/fonts/TTF/AndikaRegular.ttf", R_OK) = 0
madvise(0x3a38dab8b000, 385024, MADV_DONTNEED) = 0
madvise(0x3a38dab69000, 57344, MADV_DONTNEED) = 0
madvise(0x3a38dab69000, 57344, MADV_DONTNEED) = 0
madvise(0x3a38dab69000, 57344, MADV_DONTNEED) = 0
madvise(0x3a38dab8b000, 49152, MADV_DONTNEED) = 0
madvise(0x3a38d9095000, 8994816, MADV_DONTNEED) = 0
access("/usr/local/share/fonts/Japanese/Tsuyuzora-bunko/XZBB.ttf", R_OK) = 0
madvise(0x3a38dab8b000, 385024, MADV_DONTNEED) = 0
madvise(0x3a38dab69000, 57344, MADV_DONTNEED) = 0
madvise(0x3a38dab69000, 57344, MADV_DONTNEED) = 0
madvise(0x3a38dab69000, 57344, MADV_DONTNEED) = 0
madvise(0x3a38dab8b000, 49152, MADV_DONTNEED) = 0
madvise(0x3a38d9095000, 8994816, MADV_DONTNEED) = 0
access("/usr/local/share/fonts/Japanese/WadaLab/wlcmaru2004aribu4430/wlcmaru2004aribu.ttf", R_OK) = 0
madvise(0x3a38dab8b000, 385024, MADV_DONTNEED) = 0
madvise(0x3a38dab69000, 57344, MADV_DONTNEED) = 0
madvise(0x3a38dab69000, 57344, MADV_DONTNEED) = 0
madvise(0x3a38dab69000, 57344, MADV_DONTNEED) = 0
madvise(0x3a38dab8b000, 49152, MADV_DONTNEED) = 0
madvise(0x3a38d9095000, 8994816, MADV_DONTNEED) = 0
access("/usr/share/fonts/OTF/FiraSans-Regular.otf", R_OK) = 0
madvise(0x3a38dab8b000, 385024, MADV_DONTNEED) = 0
madvise(0x3a38dab69000, 57344, MADV_DONTNEED) = 0
madvise(0x3a38dab69000, 57344, MADV_DONTNEED) = 0
madvise(0x3a38dab69000, 57344, MADV_DONTNEED) = 0
madvise(0x3a38dab8b000, 49152, MADV_DONTNEED) = 0
madvise(0x3a38d9095000, 8994816, MADV_DONTNEED) = 0
access("/usr/local/share/fonts/Japanese/nukamiso/nukamiso_yamiyootf_beta07.otf", R_OK) = 0
madvise(0x3a38dab8b000, 385024, MADV_DONTNEED) = 0
madvise(0x3a38dab69000, 57344, MADV_DONTNEED) = 0
madvise(0x3a38dab69000, 57344, MADV_DONTNEED) = 0
madvise(0x3a38dab69000, 57344, MADV_DONTNEED) = 0
madvise(0x3a38dab8b000, 49152, MADV_DONTNEED) = 0
madvise(0x3a38d9095000, 8994816, MADV_DONTNEED) = 0
access("/usr/share/fonts/OTF/Vollkorn-Regular.otf", R_OK) = 0
madvise(0x3a38dab8b000, 385024, MADV_DONTNEED) = 0
madvise(0x3a38dab69000, 57344, MADV_DONTNEED) = 0
madvise(0x3a38dab69000, 57344, MADV_DONTNEED) = 0
madvise(0x3a38dab69000, 57344, MADV_DONTNEED) = 0
madvise(0x3a38dab8b000, 49152, MADV_DONTNEED) = 0
madvise(0x3a38d9095000, 8994816, MADV_DONTNEED) = 0
access("/usr/share/fonts/TTF/Ricty-Regular.ttf", R_OK) = 0
madvise(0x3a38dab8b000, 385024, MADV_DONTNEED) = 0
madvise(0x3a38dab69000, 57344, MADV_DONTNEED) = 0
madvise(0x3a38dab69000, 57344, MADV_DONTNEED) = 0
madvise(0x3a38dab69000, 57344, MADV_DONTNEED) = 0
madvise(0x3a38dab8b000, 49152, MADV_DONTNEED) = 0
madvise(0x3a38d9095000, 8994816, MADV_DONTNEED) = 0
access("/usr/local/share/fonts/Commercial/Motoya/NFbc1kp.ttc", R_OK) = 0
madvise(0x3a38dab8b000, 385024, MADV_DONTNEED) = 0
madvise(0x3a38dab69000, 57344, MADV_DONTNEED) = 0
madvise(0x3a38dab69000, 57344, MADV_DONTNEED) = 0
madvise(0x3a38dab69000, 57344, MADV_DONTNEED) = 0
madvise(0x3a38dab8b000, 49152, MADV_DONTNEED) = 0
madvise(0x3a38d9095000, 8994816, MADV_DONTNEED) = 0
access("/usr/local/share/fonts/Japanese/Motoya/MTLc3m.ttf", R_OK) = 0
madvise(0x3a38dab8b000, 385024, MADV_DONTNEED) = 0
madvise(0x3a38dab69000, 57344, MADV_DONTNEED) = 0
madvise(0x3a38dab69000, 57344, MADV_DONTNEED) = 0
madvise(0x3a38dab69000, 57344, MADV_DONTNEED) = 0
madvise(0x3a38dab8b000, 49152, MADV_DONTNEED) = 0
madvise(0x3a38d9095000, 8994816, MADV_DONTNEED) = 0
access("/usr/local/share/fonts/Japanese/tfont/TGothic-GT01.ttc", R_OK) = 0
madvise(0x3a38dab8b000, 385024, MADV_DONTNEED) = 0
madvise(0x3a38dab69000, 57344, MADV_DONTNEED) = 0
madvise(0x3a38dab69000, 57344, MADV_DONTNEED) = 0
madvise(0x3a38dab69000, 57344, MADV_DONTNEED) = 0
madvise(0x3a38dab8b000, 49152, MADV_DONTNEED) = 0
madvise(0x3a38d9095000, 8994816, MADV_DONTNEED) = 0
access("/usr/local/share/fonts/Japanese/UchidaAkira/OradanoGSRR.ttf", R_OK) = 0
madvise(0x3a38dab8b000, 385024, MADV_DONTNEED) = 0

という感じで、フォントを片っ端から読んでいて、ものすごく時間がかかっている感じだ。 ちなみに、これはChromiumだと起動時に発生するため、フォント数が増えるとChromiumは起動が遅くなるのだが、Vivaldiではコンテキストメニューの表示がすさまじく遅くなる。 また、この問題はフォームをクリックしたときに発生するため、非常にストレスになっている。

もうひとつはページをロードしたときにロードの途中で異様に時間がかかる。 これはstraceを見ても止まるわけではないのだが、特徴的な要素は見つからず、コンソールで見るとただ単に飛んでいる。 これはChromiumでも発生するため、恐らくBlinkの問題だ。

Vivladi固有の問題のほうは時間があるときに報告するつもりだ。

現状では「Firefoxを使う」というのが解決策になりそうだ。 Chromiumは最近とにかく重くなっている。CPUの使い方がえぐいし、異様に処理に時間がかかるようになった。 フリーズしている、と感じるような処理時間で、原因がよくわからないケースが多い。 これがバージョン71から発生していることは認識しているのだが、そもそも「ウェブレンダリングを難しくしすぎている」というのが問題で、 「なんでもかんでもウェブでやろうとするのやめてくれないかなぁ」と心底思う。

だいたいこの流れや、レンダリングエンジンの複雑さがGoogleの胸先三寸になってしまっていることにはとても気持ち悪さを感じている。

Radeon RX580はどうだったか

なお、RTX2000シリーズは通常利用での暴走や出火などが問題視されていることからあまり完成度は高くないと見られており、 AMDは14nmプロセスでNvidiaより圧倒的に性能が低く、それでありながらライバルと位置づけるNvidia製品よりもずっと高い、という状況である。 しかもTSMCは7nmプロセスの新しいカードを用意しており、Radeon VIIという新製品は「RTX2080相当の性能で、価格的にも同等。Vega RX 64比では性能は1.8倍」とのたまっている。 TSMC、及びAMDは7nmで攻勢をかけるつもりのようで、とにかく時期が悪いのは確かだ。

だから、今買うならGTX1080かRTX2070あたりが妥当な判断で、RX580が4万円程度はするという点を考えると普通の(Windowsの、ゲーマーの)ユーザーには「迷わず買う人以外は買わないほうがいい」レベルの製品だろうとは思う。

Linuxにおける性能は、おおよそWindowsにおけるGeForceとの関係と同等。 つまり、NvidiaがWindowsと比べて半分程度の性能しか出せていない以上、AMDのドライバもWindows版と比べて半分程度、と考えれば良いのではないだろうか。 以前はもっともっと差が開いていたのでだいぶ健闘しているといって良さそうだ。現在はNvidiaのプロプライエタリドライバとAMDのオープンソースドライバ(AMDGPU)は同等の出来ということになる。 性能面では、だが

ゲーミング部分で言うと、ドライバの出来と、ゲームにおける最適化の結果として圧倒的にGeForce寄りであり、Radeonはその力を発揮できないという状態が続いている。 だから、ゲーム用途では何も考えずにGeForceでいいというレベルだし、多分それはRadeon VIIが出ても変わらない。

一方、Linuxのワークステーションユースで不満が出るという気はしなかった。 vdpauinfoでは

display: :0   screen: 0
API version: 1
Information string: G3DVL VDPAU Driver Shared Library version 1.0

Video surface:

name   width height types
-------------------------------------------
420    16384 16384  NV12 YV12 
422    16384 16384  UYVY YUYV 
444    16384 16384  Y8U8V8A8 V8U8Y8A8 

Decoder capabilities:

name                        level macbs width height
----------------------------------------------------
MPEG1                          --- not supported ---
MPEG2_SIMPLE                    3 65536  4096  4096
MPEG2_MAIN                      3 65536  4096  4096
H264_BASELINE                  52 65536  4096  4096
H264_MAIN                      52 65536  4096  4096
H264_HIGH                      52 65536  4096  4096
VC1_SIMPLE                      1 65536  4096  4096
VC1_MAIN                        2 65536  4096  4096
VC1_ADVANCED                    4 65536  4096  4096
MPEG4_PART2_SP                  3 65536  4096  4096
MPEG4_PART2_ASP                 5 65536  4096  4096
DIVX4_QMOBILE                  --- not supported ---
DIVX4_MOBILE                   --- not supported ---
DIVX4_HOME_THEATER             --- not supported ---
DIVX4_HD_1080P                 --- not supported ---
DIVX5_QMOBILE                  --- not supported ---
DIVX5_MOBILE                   --- not supported ---
DIVX5_HOME_THEATER             --- not supported ---
DIVX5_HD_1080P                 --- not supported ---
H264_CONSTRAINED_BASELINE       0 65536  4096  4096
H264_EXTENDED                  --- not supported ---
H264_PROGRESSIVE_HIGH          --- not supported ---
H264_CONSTRAINED_HIGH          --- not supported ---
H264_HIGH_444_PREDICTIVE       --- not supported ---
HEVC_MAIN                      186 65536  4096  4096
HEVC_MAIN_10                   186 65536  4096  4096
HEVC_MAIN_STILL                --- not supported ---
HEVC_MAIN_12                   --- not supported ---
HEVC_MAIN_444                  --- not supported ---

Output surface:

name              width height nat types
----------------------------------------------------
B8G8R8A8         16384 16384    y  NV12 YV12 UYVY YUYV Y8U8V8A8 V8U8Y8A8 A8I8 I8A8 
R8G8B8A8         16384 16384    y  NV12 YV12 UYVY YUYV Y8U8V8A8 V8U8Y8A8 A8I8 I8A8 
R10G10B10A2      16384 16384    y  NV12 YV12 UYVY YUYV Y8U8V8A8 V8U8Y8A8 A8I8 I8A8 
B10G10R10A2      16384 16384    y  NV12 YV12 UYVY YUYV Y8U8V8A8 V8U8Y8A8 A8I8 I8A8 

Bitmap surface:

name              width height
------------------------------
B8G8R8A8         16384 16384
R8G8B8A8         16384 16384
R10G10B10A2      16384 16384
B10G10R10A2      16384 16384
A8               16384 16384

Video mixer:

feature name                    sup
------------------------------------
DEINTERLACE_TEMPORAL             y
DEINTERLACE_TEMPORAL_SPATIAL     -
INVERSE_TELECINE                 -
NOISE_REDUCTION                  y
SHARPNESS                        y
LUMA_KEY                         y
HIGH QUALITY SCALING - L1        y
HIGH QUALITY SCALING - L2        -
HIGH QUALITY SCALING - L3        -
HIGH QUALITY SCALING - L4        -
HIGH QUALITY SCALING - L5        -
HIGH QUALITY SCALING - L6        -
HIGH QUALITY SCALING - L7        -
HIGH QUALITY SCALING - L8        -
HIGH QUALITY SCALING - L9        -

parameter name                  sup      min      max
-----------------------------------------------------
VIDEO_SURFACE_WIDTH              y        48     4096
VIDEO_SURFACE_HEIGHT             y        48     4096
CHROMA_TYPE                      y  
LAYERS                           y         0        4

attribute name                  sup      min      max
-----------------------------------------------------
BACKGROUND_COLOR                 y  
CSC_MATRIX                       y  
NOISE_REDUCTION_LEVEL            y      0.00     1.00
SHARPNESS_LEVEL                  y     -1.00     1.00
LUMA_KEY_MIN_LUMA                y  
LUMA_KEY_MAX_LUMA                y  

また、vainfoは

vainfo: VA-API version: 1.3 (libva 2.3.0)
vainfo: Driver version: Mesa Gallium driver 18.3.1 for Radeon RX 580 Series (POLARIS10, DRM 3.27.0, 4.20.1-1-MANJARO, LLVM 7.0.0)
vainfo: Supported profile and entrypoints
      VAProfileMPEG2Simple            : VAEntrypointVLD
      VAProfileMPEG2Main              : VAEntrypointVLD
      VAProfileVC1Simple              : VAEntrypointVLD
      VAProfileVC1Main                : VAEntrypointVLD
      VAProfileVC1Advanced            : VAEntrypointVLD
      VAProfileH264ConstrainedBaseline: VAEntrypointVLD
      VAProfileH264ConstrainedBaseline: VAEntrypointEncSlice
      VAProfileH264Main               : VAEntrypointVLD
      VAProfileH264Main               : VAEntrypointEncSlice
      VAProfileH264High               : VAEntrypointVLD
      VAProfileH264High               : VAEntrypointEncSlice
      VAProfileHEVCMain               : VAEntrypointVLD
      VAProfileHEVCMain               : VAEntrypointEncSlice
      VAProfileHEVCMain10             : VAEntrypointVLD
      VAProfileJPEGBaseline           : VAEntrypointVLD
      VAProfileNone                   : VAEntrypointVideoProc

と当初対応しておらず、重大な弱点であった「H.265の非対応」は解消されているようだ。 (ただし、VP8/9には対応していない)

実際に試してみたところ、hevc_vaapiでのエンコードは116fpsと、P400でのNVENCには劣るもののかなりの優秀さを見せた。これだけ速ければ十分に実用的だろう。 画質がNVENCだと実用には厳しいところがあったのだが、VCEの場合いくらか画質がいいためより実用しやすい。 それでも、利用できる場合は「普通は画質を少しでも良く保存したい」ために「速さ優先」とはなりづらく限定的だが。

さらにNvidiaと違い、Waylandのコンポジターがちゃんと動作するというのも大きなメリットだろう。

消費電力的にも、あまり電気を使わないプロセッサを使っているからという事情が前提になってしまってはいるものの、使いづらくなるほどではない。 気持ちとしては「もっと消費電力が少なかったらなぁ」というのと、「2万円台前半だったらなぁ」という気持ちはとてもしてしまうのだが、そうした点を除けば「入れておけばとりあえず安心できるカード」であると言えるだろう。 「とりあえず入れる」には巨大すぎて入れるケースを随分選ぶが。

DVI-Dがひとつ、HDMIとDPがふたつずつで計5出力というところも、使いやすく不満になりにくい。 このビデオカードは大きさ的にも電力的にもそう来やすく選べるものではないが、Linuxでのグラフィックにまつわる不満を感じているのなら、RX580と言わずとも(例えば560でも)Radeonにする価値はありそうだ。

将来的には

「ゲームをする事情」と「デスクトップユースとして普通のアプリを動かす事情」は似ているのだが、「計算力を求める事情」と「Linuxにおいて快適な仕様」とは大きな違いが出てきている。

だから、贅沢を言えば2種類の仕様を用意できると最善で、贅沢を言えば、 「Ryzen + GeForce (主にWindows及びゲーム向け)」と「Ryzen Threadripper + Radeon (Linux及び計算向け)」の2台で編成できたらなぁ、と思う。 Zen2でこれを構成するのはなかなかドリーミーだ。

とはいえ、現実的に1台に絞るとしたら、「Ryzen + Radeon」という構成で「現実的な計算力とLinuxで扱いやすいグラフィック」というのを取るだろう。

現状、P720はどうなのかというと、やはり4114に求めたものと諦めていたものというのが大きい。

「メニーコア」という性能は、それを発揮する場面というのは本当に少ない。 実際、私の普段の運用では4114ですら持て余し気味である。 ところが、普段遣いではあらゆるアプリで処理性能が足りずストレスフルである。 「普通の使い方でモバイルi3程度の快適性しか求められない」というのはわかっていたが、それでもこのマシンのクラスを考えるととても残念な感じがする。

対して、実際にメニーコアを求めるケースでは4114では全然足りないのだが、それでも処理性能はi7とは段違いであった。 「4114はフルコアを活用できたとしてもi7に劣る」と考えていたが、実際は第8世代Core i7よりもずっと高速に動作した。 シングルコア性能も諦めていたほどに低くはなく、「さすがにそれなりに性能はある」と感じることができる。 そもそも、20コア40スレッドであるから、「20スレッドスケールテスト」が手元でできるというのもかなりのメリットだった。 だから、ちゃんと求めたものは実現できているし、価格を考えれば完全に目的を達成できるほどではないというのはわかっていた。

だが、結局のところ現状P720の最大の魅力は「省電力」である。 48Wから90W程度でありながら非常に優れた処理性能を発揮する、というのはかなり魅力的だ。

だが、やっぱりコンピュータは「性能が足りるか否か」であり、エクスペリエンスが良いかと聞かれるとYESとは答えがたい。 部分的にボトルネックになるブラウジングが全体の作業の足を引っ張るという状況も痛い。

「エクスペリエンスは諦めて処理量を増やしたい」というのとは矛盾しているのだが、やはりエクスペリエンスを優先したい気持ちが湧いてくる。 今回RX580にしたことで飛躍的にエクスペリエンスが向上したことも大きな理由になっている。 というより、RX580にしたことでP720がとりあえず不満ないくらいの動作をしてくれるようになった。 だから、バランス的には今の状態は悪くないのかもしれない。

Erina/Surtrに関する研究が一区切りついて、あまりデータプロセッシングすることがなくなったというのも大きい。 圧倒的に重い処理であったことから、これのためにメニーコアを求めたし、それによって成果も挙げたのだが、これがなくなると相当頻繁に回されるタスクを考えても実際8コアもあればあまり支障はなく、16コアのRyzenが用意されるのであれば不満はなさそうに思える。

ただ、ゲームをすることに関していえばGeForce優位は揺るぎそうにもないし、かといってLinuxでは現状NvidiaもIntelもなかなかの惨状ということを考えればRadeon以外選択肢はないという状態であり、 これが2台構成を求める理由ともなっているが、1台を選ぶのであればLinuxエクスペリエンスを優先することになるだろう。

ただ、Zen2の世代ではまだP720は現役で、しかも「非常に高機能で並列処理能力は高いが、通常の使い方ではそれほど性能は高くなく、消費電力はやや少なめで、筐体はとても大きい」マシンをメイン以外で使うというのは非常に難しい。 今Godavariがそうであるように、「主にWindows環境(音楽制作)、必要なときは計算資源または分離された帯域としてのLinux」みたいな使い方になるだろうか。 実際、音楽制作では機材がIntelプロセッサを想定したドライバでAMDドライバだといまいちうまく動かないケースもあり、現在のP720のような構成は非常に好ましい。 多くのVSTプラグインを使う場合も4114はかなり良い働きをしてくれる。 それでも、なんとも微妙な話で、Zen2世代でメイン機の差し替えを行うかは悩ましいところではある。

やはり「それぞれの用途で最適化した理想の2台」なんて夢見がちな話をするに留めるとして、多分本当に多くの人にとって有益なのは現時点で性能的にやや微妙な立ち位置にあるRyzen Gが不満のない性能まで引き上げられること、 あるいはRX 580相当のRadeonがもっと安く、省電力でコンパクトなものとして出てくることだろう。それは、次の世代で実現するかもしれないし、Zen3の世代まで待たねばならないかもしれない。

一方、X11はいよいよ限界を迎えている感もあるが、一方でWaylandがよくなっているわけでもない。 IntelもNvidiaも不具合が出る状態が続けばかなり苦しいことになるだろう。


  1. 具体的にはFlower Knight Girlである。 なお、 18禁バージョンもあるため 検索される際にはくれぐれも留意願いたい。

「ZshからRubyにしたら速くなる」 その理由とテクニック

現在取り組んでいるプロジェクトで、パフォーマンスチューニングの一環として当初Zshで書かれていたスクリプトをRubyで書き直すことによって、60倍程度の高速化を実現した。 もちろん、単純に書き換えただけではなく、可能な限りfork/execをしないようにしたり、コストがかかる処理を最小にするなどの工夫を伴って手に入れた結果だが、「ZshでしていたことをRubyに書き換えた」だけでも相当な効果があった。

このパフォーマンスチューニングは単にプログラムを書くだけの人には生まれにくい発想である。 Unix、そしてLinuxのシステムや、プログラミング言語処理系に関する知識がないと考えられない要素が多いのだ。

そこで、この話を解説する。

「ZshよりRubyが速い」そのわけ

根本的な話として、Zshはそもそも遅い処理系だ。 「Zshが遅い」という話はZshのメーリングリストでもちらほら話をされる。 別にBashと比べて遅いということではないのだが(Bashもまた非常に遅い処理系だからだ)、状況によっては速度が問題になる程度に遅い。

Rubyも相当に遅い処理系であると言われていたし、実際かなり遅かったのは事実だ。 それでもZshに比べれば随分早かったのだが。

だが、それ以降、Rubyは高速化に取り組み続けている。対して、Zshはあまり高速化には取り組んでいない。だから、差が開いている。

しかし、理由がそれだけというわけではない。

Zshは純粋なインタープリタである。対して、Rubyはスクリプト言語ではあるがバイトコードインタプリタ型である。 この違いは、syntax errorが起きるタイミングが、Rubyがスクリプトを実行しようとしたタイミングであるのに対し、Zshはその行に到達したときであることからもわかる。

インタープリタ型であれコンパイラ型であれ、ソースコードを機械語に変換しなければならない、という点は変わらない。 その違いは方法とタイミングである。

インタープリタ型言語の場合、「1行ずつ(1コマンドずつ)変換する」のである。 その変換方法はもちろん処理系によって異なるのだが、Zshの場合、complex commandでも複数の文をまとめて変換することはしないし、ループによって繰り返される場合でも一度変換したものを使いまわしたりはしない。

対してRubyは、最初にコード全体を構文木に変換する。 RUby 1.8までは構文木インタープリタによってこれを実行していたが、Ruby 1.9以降はこれをさらにバイトコードに変換し、バイトコードインタープリタ(VM)によって実行するようになった。 バイトコードはRuby専用の機械語のようなもので、VMによって非常に小さなコストで実行できる。 Ruby 2.6からはJITコンパイラも追加され、部分的にCコードを生成し、これをネイティブコンパイラ(例えばgcc)によってバイナリコードに変換する(こともできる)。

これで1行だけのようなコードだとあまり差は出ないし、Zshでは1行だけどRubyでは何十行という可能性もあるので、このようなケースではRuby有利というわけではなくなる。 だが、ループで何度も同じコードを実行するような場合には非常に大きな差になってくる。 今回の場合、テスト段階で500回のループであったことから、大きな差になったということである。 だからループ回数が増えると倍率的にも速度差はさらに開く。

fork/execとコンパイルにかかる時間

Unix関連に少し知識がある人であれば、「forkはコストが重く遅い」というのを聞いたことがあると思う。

だが、この認識にはちょっと注意が必要だ。 というのも、C言語の速度から見た時に「forkする時間があればどれだけ実行できるか」という点を考えるとsystemで外部コマンドを呼び出すとそこだけ局所的に時間がかかる、という状況が発生する。

だが、実際にはfork(2)しても1000分の数秒にすぎない。 どちらかといえばそれよりもexec(2)のほうが重いのだが、それでもせいぜい100分の1秒程度だ。 だから、C言語で書いている場合ですらそれなりに長くなる場合はむしろ実行コストを省略できてコマンドを呼び出すほうが速かったりする。

昔のUnixではfork(2)はもっともっと遅かった。 現在のLinuxにおいてfork(2)が速くなったのはコピーオンライト形式であることの恩恵が大きい。 古典的なUnixではfork(2)は呼び出した時点でプロセスのメモリをコピーしていた。直後にexec(2)する場合はコピーしたメモリの内容は全く使わないのでかなりの無駄だ。

ところが、現在のLinuxにおいてはfork(2)によってメモリはコピーされない。共有されるのである。 そしてforkされたプロセスが共有されているメモリに対して書き込みを行った時に別に領域を確保してそれを変更する仕組みだ。

結果的にfork自体は一瞬に近くなっている。

そして、もうひとつ重要なのが「コンパイル時間」だ。 Rubyは起動時に対象スクリプトの変換を行う。 だが、この変換コストは速くなるに従って増加している。以前は構文木に変換するだけだったのが、1.9からはさらにバイトコードに変換する時間が必要になったし、2.6でJITを使うとさらにCコードを生成してそれをコンパイルする時間まで必要になっている。 つまり、Rubyはだんだん「実行は速くなっているが、実行に着手するまでは時間がかかるようになっている」のである。

これは、例えばechoであれば

% time /bin/echo > /dev/null
/bin/echo > /dev/null  0.00s user 0.00s system 79% cpu 0.001 total

ということになるのだが、Rubyだと空っぽに近くても

% time ruby -e 'nil'         
ruby -e 'nil'  0.04s user 0.02s system 59% cpu 0.089 total

結構時間がかかる。 つまり、一瞬で実行が終わるRubyスクリプトを何度も何度も繰り返して呼び出すと、トータルではかなり時間がかかるわけだ。 もともとのスクリプトは本体はRubyで、呼び出しがZshだったので、20並列で各500回、Rubyによるコンパイルがかかっていた。だから、かなりの時間がかかっていたのだ。

だが、「Linuxのforkはメモリが共有され、ほとんど一瞬で終わる」という点を利用すると改善の余地がある。 それは、実行可能なRubyスクリプトをライブラリ化する、という方法だ。

ZshからRubyを呼び出す場合、どうしてもRubyを呼び出すたびにRubyによるコンパイルをかけざるをえない。 当初は10000回コンパイルされていたのだが、500回のループをZshではなくRubyで行うようにすれば20回で済むようになる。だが、それでも20回のコンパイルが必要だ。

しかし、呼び出すスクリプト自体をRubyに変えてしまえば、実行しようとするスクリプトをライブラリとしてロードするという方法がとれるようになる。 ライブラリとしてロードすると、そのコンパイルは呼び出し元スクリプトをロードしたときに行われる。 もちろん、呼び出しの目的は呼び出すだけであり、直接そのライブラリの機能を使うわけではない。だが、この状態からforkすると、「コンパイル済みコードがメモリ上にあるRubyプロセス」が出来上がる。

この時点でスクリプトを実行する方法は「メソッドを呼び出す」(あるいは、その機能を果たすオブジェクトを作ってメソッドを呼び出す)だけである。 繰り返し呼び出すループを書くのも、単にRubyのループを書いて、そこで繰り返しメソッドを呼び出すなりオブジェクトを作るなりすれば良い。 呼び出し元スクリプト側では並列分だけforkしたあと、Process.waitallでもしていればいいわけだ。

これはZshに対して、「Rubyスクリプトのコンパイルが1度だけでいい」「execする必要がない」というメリットをもたらしている。 どちらも結構コストの高い処理であるから、繰り返し実行する場合は非常に大きなコストになり速度を低下させる。「処理自体は軽いのだが果てしなくループする」タイプのスクリプトに対してこの方法は本当に効く。 なぜならば、そのようなスクリプトに対してはコストの高い呼び出しをしているとコストのほとんどは呼び出しで占められ、実行コストは小さいためにスクリプト自体を高速化しようとがんばったところでほとんど無意味だし、逆に呼び出しコストを軽くすると劇的に速くなるからだ。

systemd-nspawnでManjaro LinuxからArch Linuxする

systemd nspawn

なんかSystemdを毛嫌いする人が多いのだけど、結構使いやすくて便利な機能が多いので、私は好きだ。Xサーバーみたいだと思う。

systemd-nspawnはcrgoupsを利用したLinuxコンテナである。 LXCよりもずっとシンプルな実装で、かつ簡単に使うことができる。 全然知られていないけど。

とりあえずArchする

Manjaroにもarch-install-scriptsがあるためpacstrapできたりする。 なので、初回インストール前には

# pacman -S arch-install-scripts

とやっておく。

そしたらコンテナを作る。 こちらは新規コンテナを作るときにやる作業。

# pacstrap -i -c ~/Container base base-devel

Arch Linuxをインストールしたことのある人ならわかると思うのだけど、 最低限baseがないと機能しない。そして、AURを利用する場合はbase-develも含んでおかないといけない。

あとはログインする。 これは、起動時に実行するもの。

# systemd-nspawn -b -D ~/Container

これでコンテナを起動することができる。終了する場合、コンテナ上で電源を切る。 終了は少し時間がかかる。

# poweroff

LXCと違って自動的にブリッジインターフェイスもセットアップされ、起動しただけでネットワークがちゃんと機能する状態になる。 LXCと比べても随分と話が早い。

ManjaroだとArchを構築するのは簡単だし、もちろんArchやAnterogosでも簡単だけど、そうでないディストリビューションがどうやってコンテナ上にOSをインストールするか、については各々調べて欲しい。 私はArchが使えれば満足なので、コンテナ上で他のディストリビューションを使おうとは思わないし、現状、Manjaro以外をホストにしようとも思わないからだ。

おまけ。この環境からPowerlevel9kするために

ちょっとつまずいたのでおまけ。 標準ロケールがen_US.utf8になっているため、Powerlevel9kのPowerline記号が出ない。

そこで、/etc/locale.genを編集してja_JP.UTF-8 UTF-8をアンコメントし、

# locale-gen

そして、/etc/locale.confを編集してLANGja_JP.UTF-8にしてから

# localectl set-locale LANG=ja_JP.UTF-8

これでちゃんとPowerlevel9kのアイコンが出るようになる。

Powerlevel9k * モリサワフォント

Zsh * Powerlevel9k を使っていて、なおかつモリサワパスポートユーザーである人なんて多分この世に数えるほどしかいないと思うので、需要は限りなく0に近い記事を書かせてもらうことにする。

Powerlevel9kで使われるU+F015(ホームマーク)やU+F17C(Linuxマーク)はPrivate Use(外字)領域であり、 文字として定義されていない。 そして、モリサワフォントはこの領域を使用しており、U+F015は「言信」という文字(実際は一文字)に割り当てられており、 モリサワフォントを導入するとAwesomeフォント(Nerd font)に優先されてしまうため、有効に機能せず、文字化けしてしまう。

解決方法は結構シンプルで、FontConfigで

のようにしてNerd fontをprependするだけである。

この問題のハマりポイントは、「Nerd fontのグリフを持っているCicaを指定したときにNerd fontグリフ部分を使ってもらえない」ことである。 だから、Cica一本に頼っていた場合はNerd Fontを別途導入する必要がある。

Zshでの連続的呼び出しに環境変数を使ってみる (Zshのガベージコレクション)

Zshは極めて強力なシェルだが、大規模プログラミングにおいて使われることは少ない。 だが、Orbital designにおいてはシェルスクリプトは強力な武器だ。できれば積極的に活用していきたい。 そうなると、Zshにおいて明らかでない、あるいは公知ではないことと付き合っていかなければならない。

単純に言えば今回は

のような処理を行うスクリプトを、invoke_workerがファイルを読み込むのではなく、事前に読み込んでおくことでワーカーの処理時間を短縮したいということだ。

のようにしたいということだ。

だが、問題は「これがメモリを食いつぶさないか」ということである。

意図と効果

普通のスクリプトの場合、この方法はほとんど効果をもたらさない。もしかしたらマイナスになるかもしれない。

そもそもこれらの情報が「単純にファイルとして読み込むだけ」の設計になっているところも工夫のなせる技なのだが、必ずしもそのようにできるわけではない。 特にクラスタ仕様になっているとファイルアクセスが遅いかもしれないし、その違いを吸収するためにさらに別の方法をとるかもしれないのだ。

ワーカーは起動数も多く、当然ながら処理としては重い。 逐次実行されるワーカー部分であまりその処理を担わせたくない。 特に設定のほうは起動される全てのワーカーにとって共通である。 これを環境変数にするメリットは大きい。

Linuxのfork(2)はコピーオンライトだ。 configは文字列であり、起動されるワーカーではその文字列をパースすることになるから、この$config環境変数が変更されることはない。 つまり、この環境変数は実体はひとつであり、常に同一の実体が参照される。コピーされることもないので速度が上がる。ディスクIOとメモリへのコピーが2回目以降省略できるのだ。

ただし、環境変数で渡す文字列は「システムコールがCライブラリである」ためにC文字列(の配列)であり、\000が含まれていると文字列がそこで終わってしまう。 私は勘違いと慎重さを欠いたことから赤っ恥をやらかしてしまった。

データのほうは、ほぼ単純に、ワーカー実行中に時間がかかる(かもしれない)データの取得を裏でやっておきたい、ということである。 これも環境変数にしてしまえばワーカーはリード時間をとられない。所要時間の総量は変わらないが、裏でやることで逐次実行部分に含めることを避けるということである。

問題と検証

だが、これは

というのが100万回実行されるということだ。 しかも、これはループのたびに異なる値になる。

もしZshにガベージコレクタがなければ100万件のデータを抱えてしまうことになり、これはメモリ消費量的にまずい。

というわけで、「Zshは変数を上書きしたらメモリを開放してくれる(ガベージコレクションしてくれる)のか?」という疑問を解き明かす必要ができた。

この調査は割と簡単で

とし、

のようにしてメモリ消費量を監視すれば良い。

ちなみに、100Mを指定しているが、/dev/urandomは一度に読めるのは32MiBまでである。

80340
215640
80332
80332
80348
43344
80340
80340
80332
80332
215636
80340
80332

だいたい2倍程度と見ていいと思うのだが、ときどき3.5倍程度まで増加する。 ただ、だいたい2倍ということはかなり迅速にメモリを回収してくれている印象だ。

しかし、実際のワーカーはこんなに長時間実行はしないので、実際のワーカーの実行時間に近い感じにしてみよう。

108932
80340
195300
80340
215628
80340
211472
111616
80332
178644
43344
215644

回収しきれないタイミングが増えてメモリ使用量にばらつきは生じているが、回収ペースを上回ってメモリ消費量が果てしなく増えていくようなことはないようだ。

結論

  • Zshにはガベージコレクタがある
  • Zshでパラメータを上書きすると、ローカル変数か環境変数かによらず迅速にメモリは解放される
  • IOコストが高いなどで逐次的に実行するコストを削減したい場合、コントローラで環境変数にする作戦はなかなか有効

追加の注意点

フルスケールするように設計されているワーカーの場合、CPUコア数を使い切るだけワーカーを起動していると、結果的に裏で色々するためのコンテキストスイッチコストが高くついて全体では遅くなる可能性もある。 というか、ワーカーの実行がそれほど時間のかからないものであるならばwaitの時間は短くなり、waitの時間が短くなるほどスケール阻害要素としては大きくなる。

エンジニア&ワナビーに贈る名著7選

はじめに

昔Twitterで似たようなタグがあったような気がするのだけど、 私はコンピュータ関連書籍(雑誌込み)には300万円くらいはつぎ込んでいるので、その中で「これは色褪せない、他にはない、素晴らしい!!」と思ったものを挙げたい。

私が今まで読んできた中でボロボロになるまで読んだ本たちだから、だいたいの本は古く、そして絶版・入手困難になってしまっている。

このほかにも見どころがあって、色褪せない本というのはあるのだが、今回は「名著」と言い切れるような必読書のみに絞って挙げてみた。

ハッカーズ大辞典

いわゆる「おもしろ用語集」のような本。

用語自体が技術的知識になる、という側面は少ないのだけれど、 昔のハッカーたちがどんな棋風で、どんな出来事で、どんなふうに接し、振る舞ってきたのかがわかる「文化本」という意味合いが大変に強い。 そして、ハッカーマインドを理解するにもこの本は欠かせない。

ここに登場する語のほとんどは現役ではなく、実際に使われることは多くはない。 だが、ハッカーは大概、この本のことは知っているし、ここに登場する用語や背景のことは知っている。 これらのことは元ネタである “Jargonfile” で呼ぶことが多いが、実際にはこの和訳本のことを示していることがほとんどである。 このJargonfileのオリジナルはインターネット上で読むことができるが、和訳も大変イケているので、ぜひ翻訳本をお勧めしたい。

だが、残念ながらこの本は絶版である。 改装版が出ていることを知らなくて、私は今でも探しているくらいだ。 (私は翻訳初版しか持っていない)

インターネットの起源

インターネットはどのように誕生し、どのような苦労があったのか、 そのときどのような信念があったのか、それを窺い知ることができる名著。 翻訳が少し雑なのが気になるが、貴重な当事者の証言である。

インターネット陰謀論を吐きたがる人には一度は読ませたい本だ。

こちらも絶版プレミアだが、Kindle版があるのが救い。

プログラミングPerl

「ラクダ本」といえばこの本。 Perlを学ぶ人だけでなく、プログラミングを学ぶ全ての人にとって一読の価値のある名著であり、特に正規表現を理解するには (オライリーの「正規表現」以上に)この本の助けが必要となるだろう。

PerlはCほど難解ではないが、隠しきれない低レベル感がある。 ひとつひとつの概念を丁寧に解説してくれるので、プログラミングについて理解する良い下地になる。 「書いてあることをそのまま実行する」ことに頭が行くタイプの人には向いていないだろうが、理解して地力を高めていくということが分かる人には地力育成法としてかなり良い本だと思う。

上下巻なのだが、VOLUME2はリファレンスであるため、「なくてもよい」感が強く、VOLUME2のほうは事実上の絶版。 VOLUME2の巻末の用語集は結構おもしろいのだが。

Perlクックブック 第2版 VOLUME1

Perlを実用的に活用するための本、なのだが、クックブックなので基本的にはテクニック集だと思えばいい。 だったらわざわざ挙げるほどではない、と思うかもしれないが、割とクックブックって良いものが少なくて、推挙できるのはこれぐらいのものだ。

このクックブックにはふたつの面がある。

ひとつは、ラクダ本で学ぶことができる基礎によって理解を深めても、実際になにかを実現しようと思ったときにどうすればそれが実現できるのかということを教えてくれる教科書としてだ。

そして、もうひとつはここに書かれていることを理解できるかどうかが、プログラミングに対する理解度をはかるものになるということだ。 小さな課題をテクニックを駆使して解決しているため、それによって解決できることはわかるのだが、レベルが十分に上がっていないとなぜそれによって解決できるのかがわからない。 読み物として読んだときにするっと理解できるようになったとき、自分のレベルが向上したことを実感できるだろう。

VOLUME2はPerlに特化した部分が多いので、VOLUME2はあまり必要ないかもしれない。 いずれにせよ絶版本で、入手は難しい。

Hacking:美しき策謀 第2版 ――脆弱性攻撃の理論と実際

誤解してほしくないのは、これによって攻撃ができるようになるような類の本ではない。 この本はそもそもかなり小さくて薄い本なので、そこまで充実の中身はないのだ。

だが、多くの人が「なんとなく言葉と、用語集の説明文程度で知っている」脆弱性攻撃の中身を、簡潔かつ的確に教えてくれる。 この知識は脆弱性攻撃のみに有効なわけではなく、コンピュータの低レイヤーを理解する補助教材としてかなり有効だ。 低レイヤーが苦手な私はこの本に随分助けられた。

ここで扱っている内容は非常に難易度が高く、実際に学ぼうとするとかなり困難を伴う。 もちろん、この本の記述範囲で理解できるはずもないのだが、なんとなく理解し、興味をもつには良いだろう。

新The UNIX Super Text 上 改定増補版,

私がLinuxをちゃんと学び直すときに使った教科書だ。

2003年刊行なのだが、内容は1997年のオリジナルからほとんど変わっていない。 結果的に、2003年時点でも大部分が「そのままは使えない」内容となっており、現在はそのまま使える知識などないに等しい。

だが、「何が基礎で、何が今につながり、それをどうすれば活用できるのか」ということを考えながら読むと、基礎を学ぶには最適なものになる。

実際、Mimir YokohamaのLinux基礎やコンピュータ基礎のカリキュラムづくりは、この本での内容をかなり参考にしている。 実際のところそのまま使える部分はほとんどなく、現代の技術に置換えただけで説明が完了するものもないため、流用できる内容はほとんどないのだが、どのようなことで構成し、何に触れるか、基礎としてどのようなことを学ぶことが地力の育成につながるか、ということを考える上で大変参考にさせていただいている。

この本の残念なところは、著者に一名、ちょっといい加減なことを偏見込みで書いている人がいることだろうか。

まつもとゆきひろ コードの世界‾スーパー・プログラマになる14の思考法

Ruby設計者のまつもとゆきひろさんの本。シリーズとして「コードの未来」「言語のしくみ」という本もあるのだけど、やはり名著といえばこの「コードの世界」だと思う。

技術書というよりは、文字通り「コードの世界」を紹介した本であり、特に難しいと感じる人の多いプログラミング言語にとっての文字コードの「内部コード」と「外部コード」の違い、正規表現エンジンの挙動と違い、並列実行などについてinsiderの視点で解説されており、楽しく読める上に読んでいるとプログラミングに関する理解も深まる。

「コードの未来」も併せて読みたい良書だが、こちらは技術を紹介する色合いが強いため、必読とまで勧められる感じではない。だが、お勧めではある。

ConoHaとArch LinuxではじめるLinux

ごあいさつ

Hi, there! はるかみです。

この記事はConoha Advent Calendar 2018の7日目として書かれたものだよ。 いままでChienomiを見たことある人もない人も楽しんでいってね。

基本的にChienomiはedgeな記事を書くことが多いけれど、Advent Calendarのときだけは初心者向けの記事を書いたりしているんだ。 Chienomiでは最近で最もアツかったのは高EQ AIに関する記事だよ!

本当はConoHa WINGに関する記事を書こうかと思ったけど、Advent Calendarで書くようなものじゃないと思ったんだ。 考えていたものは検証に5, 6日必要だとわかったから協賛でもしてもらわないと無理だとわかったんだよ。

それにConoHa WINGでConoHa Advent Calendarのハードルも下がって、今年はWINGに関する記事がたくさん載るだろうからね。え?毒が少ないって?さすがに同じAdvent Calendarの記事に毒を吐くのは来年にとっておくよ。

あなたはLinuxを使っているだろうか。

最近はLinuxというとドヤりツールになっていたり、あるいはミーハーなものになっていたりもする。 あとは、仕事のための箔付けだろうか。

それはLinuxのなんたるかがわかっていない…と思うのだが、ここではそんな話はおいて、とりあえずLinuxを触ってみたいという人のお手伝いをしよう。

この記事にかかれていることはかなりの部分、過去の記事や他で書いたことと重複してしまうのだが、Advent Calendarの記事ということでご容赦願いたい。

今回はLinuxを全く使ったことのないWindowser向けにエクスプレスで進めていく。 スキル不足が直接に迷惑になるサーバー構築ではなく、またデスクトップ用途でもない。

なお、Linuxそのものを体験して評したいのならばメインマシンにLinuxをインストールするよりない。 LinuxのUXはWindowsのそれよりはるかに優れているが、それはさすがにVPSでわかるようなものではない。

また、副次的に性能の低いコンピュータを使っている人の場合、月1000円から2000円程度で強力なコンピュータにオフロードできる、という面でも話していこうと思う。

SSHを用意する

Windows 10では2017 Fall Creator UpdateからOpenSSHが標準採用になっている。ちなみに、2018 Aprilではサーバーも入っている。 とりあえずまだWindows 10ですらない、という人のことはあまり考えたくないので、そこから話を進めよう。

まずはcmdを検索、あるいは“プログラムを指定して実行”からcmd

Windowsでcmd.exeを探す

ssh -VでOpenSSHを確認。

C:\Users\Harukamy>ssh -V
OpenSSH_for_Windows_7.6p1, LibreSSL 2.6.4

ssh-keygenで鍵を作成する。 Microsoftが提供するWindowsアプリでありながらUnixスタイルとWindowsスタイルが混在してとてもわかりづらいことになる。 OpenSSHが使うディレクトリは相変わらず%HOME%\.sshなのだが、Explorerでドットファイルが作れないのでコマンドライン上で行う。

>mkdir .ssh

その上でSSH鍵を生成する。

>ssh-keygen -f .ssh/conoha_rsa
Generating public/private rsa key pair.
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in .ssh/conoha_rsa.
Your public key has been saved on .ssh/conoha_rsa.pub.
The key fingerprint is
SGA256:XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX harukamy@HACKMAN
the key's randomart image is:
+---[RSA 2048]----+
|                 |
|                 |
|                 |
|                 |
|                 |
|                 |
|                 |
|                 |
|                 |
+---[RSA 2048]----+

このパスフレーズは秘密鍵を暗号化しておき、使用するときに解除して使用するためのパスフレーズである。 システムが十分に安全かつ強固に保護され、運用されているのであれば(物理的に盗まれることも、ネットワークごしに盗まれることも、ディスクをコピーされたとしても使われることも)ないのであればパスフレーズはなくても構わないし、まず考えられない程度に強固なのであればほどほどに強固なパスフレーズでも構わないだろう。

これでホームディレクトリ以下.ssh/conoha_rsa(秘密鍵)と.ssh/conoha_rsa.pub(公開鍵)のペアが作成される。

Explorerではとてもホームディレクトリにアクセスしづらいので、そこをなんとかしておこう。 ExplorerでC:\Users\ユーザー名に移動し、“クイックアクセス”を右クリックして“現在のフォルダーをクイック アクセスにピン留め”を選択する。

あと、適切なエディタがないのも困るので、インストールしておくといい。 無難なのはみんな大好きNotepad++。

ConoHaでサーバーを立てる

ConoHaでの契約については公式のページをみてほしい。

それではConoHaにログインし、“サーバー追加”からサーバーを追加しよう。 練習用なら512MBで良いだろうし、パフォーマンスオフロードを期待するなら1GB以上にしよう。 OSはもちろん、Arch Linuxである。

ConohaでArch Linuxインスタンスを立てる

Rootパスワードは本当に強固なものにすること。 ここはあまり心配のない部分だが、それでも24文字以上くらいにはして欲しいところだ。

オプションを開き、接続許可ポートを設定する。 IPv4/IPv6ともSSHのみを許可するように設定する。 IPv6のない環境からアクセスするのであればIPv4のみでも構わないし、IPv6でのアクセスが確実な接続形式をとっているのならIPv6のみのほうが良い。

ConohaでポートとSSHキーの設定

そしてSSH Keyセクションは “キーを新規作成” を選択し、“登録方法”に“インポート”を選択する。 そして“パブリックキー”のところに、作成した~/.ssh/conoha_rsa.pub (.pubファイル!!!)の内容をコピペする。

この時点で鍵登録しておくとSSHのパスワード認証が無効化された状態でインスタンスが立つので安全な状態になる。

インスタンスを作成し、起動したら、ConoHaのサーバー一覧からサーバーを開くと“VPS設定”からI逆引きホスト名を知ることができる。

それでは例えばここがv0-0-0-0.a00a.tyo0.static.cnode.ioだと仮定しよう。

SSHでログインする

ではいよいよWindowsに戻ってログインしよう。 OpenSSHの-iオプションに秘密鍵を指定する。引数はSSHのホストだが、その前にユーザーが必要だ。

>ssh -i .ssh/conoha_rsa root@v0-0-0-0.a00a.tyo0.static.cnode.io

ログインできたらexitして一旦SSHを抜ける

# exit

もう少し楽にログインできるように設定をしておこう。 .sshディレクトリにconfigというテキストファイルを作成する。拡張子はない。 UTF-8+LFで編集してくれるエディタを使うのが良いかもしれない。

このファイルは次のような感じだ。

Host conoha-root
  HostName v0-0-0-0.a00a.tyo0.static.cnode.io
  Port 22
  User root
  IdentityFile .ssh\conoha_rsa

これで

>ssh conoha-root

とするだけでログインできるようになる。

OpenSSHが使えない場合

TeraTermを使う方法が公式で紹介されている。

TeraTermの使い方公開鍵の使い方が紹介されている。

ユーザーを作成する

Windowsでは歴史的経緯から曖昧だが、rootユーザーというのは全権を持つ「神」であり、普段使うべきではない。 それどころか、rootのシェルプロセスがあるだけでも望ましくないくらいだ。

Archはインストール時にユーザーを作成しない。自ら作成する必要がある。

ではログインして作業しよう。 ユーザー作成コマンドはuseraddだが、オプションとしては-U(ユーザープライマリグループを作成する), -G(グループを指定する), -m(ホームディレクトリを作成する)を使用する。 このユーザーは管理ユーザーとなるのでwheelグループに加えておこう。

# useradd -U -G users,wheel -m conohachan

ユーザーのパスワードを設定する。とても強固なものが良い。

# passwd conohachan

ユーザー用の鍵を登録しよう。ここではOpenSSHを前提に進める。 Windowsでもうひとつcmdを立ち上げ、先程と同じ要領でキーを作る。

>ssh-keygen -f .ssh/conoha-user_rsa

configを追加する。今度は鍵とユーザーが異なる。

Host conoha
  HostName v0-0-0-0.a00a.tyo0.static.cnode.io
  Port 22
  User conohachan
  IdentityFile .ssh\conoha-user_rsa

鍵をアップロードする。まだrootでしかログインできないので、rootで送る。

>scp .ssh/conoha-user_rsa.pub conoha-root:.

これでConoHaのrootホームディレクトリにコピーされるので、これをSSHに戻ってセットアップする。 まずはユーザーの.sshディレクトリを作る

# mkdir ~conohachan/.ssh

そして、authorized_keysというファイルとして配置する。

# mv conoha-user_rsa.pub ~conohachan/.ssh/authorized_keys

このままだとrootユーザー所有ファイルになってしまうので、直しておく。

# chown -R conohachan:conohachan ~conohachan

.sshディレクトリはオーナーのみアクセス可能であることが求められるため、パーミッションを修正する。

# chmod 700 ~conohachan/.ssh

これでユーザーとしてログイン可能になったはずだ。

>ssh conoha

初期設定

まだrootのセッションも閉じないでおこう。 この状態では管理作業ができるのはrootだけなので、conohachanにも許すようにしたいところだ。

/etc/sudoersというファイルを編集するのだが、これは直接編集してはならない。 visudoというコマンドを使う。エディタにVIが入っていないのでエディタも指定してあげる必要がある。

# EDITOR=nano visudo

下の方にこんな行がある。

# %wheel ALL=(ALL) ALL

このコメントアウトを外しておく。次のように。

%wheel ALL=(ALL) ALL

オーケー。Ctrl+Oして保存し、Ctrl+Xで終了しよう。

ConoHaでは最近、script側でアップデートするようなので不要に思えるけど、一応アップデートしよう。この作業は定期的にしなければならない。

# pacman -Syu

カーネルパッケージ(linuxというパッケージ)が更新対象に含まれていた場合は再起動する。SSHのセッションは切られる。

# reboot

もう少し使いやすく…

とりあえずここからはLinuxを長年使っている身として「それなりに使いやすい環境を整える」ところをやっておきたいと思う。 特にArch Linuxはミニマルなので足りないと感じるものは色々あるだろう。

パッケージを揃える

まずはユーザーログインする。

>ssh conoha
Enter passphrase for key 'C:\Users\harukamy\.ssh\conoha-user_rsa':

$

ちょっとrootでの作業が続くのでrootになる。

$ sudo bash -l
[sudo] password for conohachan: 
# 

サーバーなら必要ないのだけど、まずはユーザーで電源切ったり再起動したりできるようにしておこう。pacmanはArch Linuxのパッケージ管理ソフトウェアであり、ソフトウェアをインストールしたりアンインストールしたりアップグレードしたりできる。

# pacman -S polkit

これでsystemctl poweroffsystemctl rebootがユーザーでできるようになる。

VI, vim, Zshはなくてはならないソフトウェアだ。あと、ターミナルデュプレクサも欲しいのでtmuxも入れておこう。 Zshはgrml-zsh-configパッケージをインストールするとすごく使いやすくなる。 あと、このあとyayを入れる関係でgoとgitも入れておく。

# pacman -S vi vim vim-plugins zsh grml-zsh-config tmux go git

いい感じになってきた。ここで一旦rootを抜け、tmuxを起動する。

# exit
$ tmux

tmuxはプレフィックスキーを押したあとになにかキーを押すとtmuxに対する指示になるようになっている。 デフォルトのプレフィックスキーはCtrl+bで、?を入力することによりキーバインドの一覧が表示される。

とりあえずcが新しいウィンドウを作成するコマンドなので、Ctrl+b Ctrl+cと入力しよう。

これでわかりにくいがふたつのウィンドウができた。nコマンドによりこのウィンドウを行き来できる。

pacmanが扱うことができるのはArch Linuxの公式パッケージだけだ。 AURという、非公式の(しかし、運営自体は公式に行われている)パッケージも扱いたいので、yayというソフトウェアをインストールする。 手順は

  1. Gitを使ってyayのリポジトリをコピー
  2. yayディレクトリに移動
  3. makepkgでパッケージを作成
  4. pacmanで作成したパッケージをインストール
$ git clone 'https://aur.archlinux.org/yay.git'
$ cd yay
$ makepkg
$ sudo pacman -U *.pkg.tar.xz

これでAURのパッケージもインストールすることができる。 もし、yayに不満ならばついでにもうひとつのAURヘルパーであるtrizenもインストールしておこう。pacmanと違い、AURヘルパーはユーザーとして実行する。

$ yay -S trizen

yayやTrizenは公式のパッケージも扱うことができる。

見やすく、使いやすく

まずはすごく簡単な話として、Bashなど投げ捨ててZshにしよう。 Bashなんてゴミだ。

まずは.zshrcを作っておく。

$ touch .zshrc

オーケー。Zshにしよう。

$ chsh
Changing shell for conohachan.
Password: 
New shell [/bin/bash]
> /bin/zsh

chshはログインシェルを変更するだけなので、今のシェルは変更されない。 一刻も早くBashやZshに変えたいので、Zshでログインしよう。

$ zsh -l
%

Poifect! grml-zsh-configをインストールしているのでとても快適に仕上がっているはずだ。 とりあえず途中でわからなくなったら、わかるところまで打ってからTAB連打で切り抜けられる。オプションやオプション引数なんかもだ。 あと、f/b/b<TAB>foo/bar/bazに展開する、なんてこともできるようになる。

さらにZshを強化して、Zshから離れられない体にしてやろう。

$ yay -S zsh-completions zsh-syntax-highlighting

Syntax Highlightを使用するため、.zshrcに次のような記述を行う。 vimが使えるならvimを使えばいいし、ダメならnanoでもいい。

grml-zsh-configはヒストリを辿ったときに「既に第一ワードを入力している場合は第一ワードを確定として、途中の場合は第一ワードの検索開始時カーソル位置までを確定として辿り、カーソルは末尾に移動する」という挙動になっているのだが、「常にカーソル位置までを確定として履歴を辿る」という機能も欲しいのではないだろうか。 というわけで、PgUp/PgDownでそのような検索ができるように.zshrcを追記する。

うーん、beautiful!

さて、ここからはちょっと複雑なことをする。 わかりやすく美しいZshプロンプトのPowerlevel9kを使いたいと思うのだが、これはWindowsだとひと手間ふた手間ある感じだ。

とりあえずインストールだけはしておこう。

$ sudo pacman -S zsh-theme-powerlevel9k

ここからは一旦ログアウトして(各シェルのログアウトしたあとSSHからログアウトするのを忘れずに)Windowsだ。まずはGit for Windowsをインストールする。

これで様々な問題を解消できるようになる。別にMSYS2を入れてもらっても構わないのだが、Git Bashが各種設定を済ませてあるので話が早い。

そして、次にCicaフォントをインストールする。 完全なPowerlineグリフを持っているので話が一番てっとりばやい。このフォント、グリフが豊富で見やすく、制限された状況で本当に便利だ。

で、Git Bashを起動して、右クリックからのOptionsで、フォントをCicaにする。ここまでやっておかないと後で困る。 それではGit Bashからログインしてみよう。

$ ssh conoha

通常Git Bashでも.exeは省略できないのだが、sshはGit Bash側で定義されており、省略できる。

minttyになったことでだいぶ見やすくなったのではないだろうか。Cicaフォントだし。 で、powerlevel9kなのだけど、とりあえず私がサーバーで使っている設定を晒そう。

これはVIモードで使うことを前提にしているので、一般化すると次のような感じか。

で、powerlevel9kなのだけど、とりあえず私がサーバーで使っている設定を晒そう。

grml-zsh-configを使っている関係で先にprompt offするのは必須。 FOREGROUNDとBACKGROUNDの色はお好みで、という感じだ。 Zsh上で(つまり、ログインしたConoha上で)

% for i in {000..255}; do print -P "$i %K{$i}     %k"; done

とやれば、番号ごとにどんな色か把握できる。 もちろん、もっと好みに設定を変更しても構わないだろう。

これも.zshrcに記述する。

この設定は作業中のミスをなくすために行っているもので、実のところ私は普段はPowerlevel9kを使っていない。 だが、SSHから入ったときだけPowerlevel9kになるようにしており、ホストごとに色を変えてある。このことにより、「ローカルホストかリモートホストかを間違える」事故を防止している。

実際、普段はgrmlデフォルト

このホストにSSHで入るとこうなる。

フォントが設定されていないcmd.exeから入ると表示が乱れている。右側のウィジットが次行に表示されているので使えないこともないが…

Git Bashなら正しく表示される。

Powerlevel9kの利用は好みの問題だと思うけれど、Git Bash + Cicaという組み合わせはやって損がないのではないだろうか。

Powerlevel9kの利用は好みの問題だと思うけれど、Git Bash + Cicaという組み合わせはやって損がないのではないだろうか。

自動アップグレード

とりあえず毎日朝6時にアップグレードするようにしてみよう。 Arch LinuxのinitであるSystemdというものを利用する。SystemdにはSystemdタイマーというジョブスケジューラがあるので、これを使うのだが、説明はとても難しいのでとりあえず例示にとどめよう。

rootとして/etc/systemd/update.serviceを作成する。

% sudo nano /etc/systemd/update.service

続いて/etc/systemd/update.timerを作成する。

% sudo nano /etc/systemd/update.timer

時は来たれり

バッチリだ。ここまで来れば、 サービスや他者に迷惑をかけない範囲であれば 君が学んだことを存分に発揮できる場が出来上がったはずだ。

例えばvimを練習したいのなら

% vim vim-training-file

とかやればいいし、Pythonでプログラムを書きたいなら

% vim myfirst.py

とかやればいい。

Linuxについて教えると話は無限に長くなるし、そもそもここまでの一連の作業でそれなりにLinuxに慣れる要素もあったので、Advent Calendarの記事としてはこれくらいで良いではないかと思っている。 この記事のソースファイルはこの行が606行目だし。

というわけで、世の中の人がちょっとでもLinuxに、そしてコンピュータに関心を持ってくれれば幸いだ。 ついでに、こんなふうに簡単にサーバーを立てて、練習やアウトソースにも使えるConoHaは素晴らしいサービスです!(おべっか)

Linuxについての突っ込んだ話はこのChienomiでしているから、関心がある人はぜひチェックして欲しい。 コンピュータやLinuxについて学びたい、教えて欲しいという人はぜひMimir Yokohamaへどうぞ。

それでは今年もこのへんで。はるかみ☆でした♪

21.5インチFHDと32インチ 4kディスプレイをLinuxで混ぜる

なにをしたか

あらまし

私はディスプレイは「随時買い足す」スタイルできた。 それも、主にリサイクルショップで買い集める形だ。

台数が多く、並行作業も多いので、接続数の関係上どうしてもディスプレイが増えざるをえない。

そうした中、ずっとメイン環境を支えてきたのがLGの22EN33及び22EN43である。 支えてきた、と言うと良さそうに聞こえるが、私にとっては最悪なディスプレイである。 輝度調節がおかしいし、色味も最初からぶっとんでいて調整の意味がない。挙げ句、ドット抜けはあるし、ちょっと触れただけでも傷はつくし、アダプタは激しくコイル鳴きするし、一度は液晶抜けするし、LGのサポートは「何も問題はない」と突っぱねるし、もう二度とLGのディスプレイは買わないと心に決めるくらいはひどかった。 似たようなサムスンのS22B300は非常に素晴らしいディスプレイなので、サムスンがPCディスプレイをやめたのが残念でならない。

基本的に輝度や色味などのぶっとび度合いは22EN33のほうが悪いが、傷がついたりドット抜けしたり壊れたりとトラブルが多いのは圧倒的に22EN43である。そして、その22EN43が、ついに画面全体に乳白色の何かを浮かべるようになってしまった。

困ったものだと思っていたところ、なんだかちょうどよくアウトレット品の4kディスプレイ、AcerのET322QKがえらい安くで出ていたので即決してきた。

解説

これは、もうちょっと説明がいるだろう。

私のディスプレイは圧倒的に21.5インチFHDが多いが、これはFHDディスプレイとしては安いためである。叩き売られることも多いし、中古も潤沢だ。

基本的にはやや小さいが、DPIとしては101ないし102程度であるため、これ以上大きいと96を下回ってしまう。解像度的には無難な線だ。

4kに変更したい、というのはずーーーっと前から思っていたこと(10万円くらいの4kディスプレイが出始めた頃から)なのだけど、その場合27インチを本命としていた。 これは、視線移動量と視点距離を考えたときにこれ以上大きくなってほしくないからだ。 一方、21.5インチや24インチの場合、4kになることで密度が上がり、必然的に多くの情報を表示できることから、より色々と表示できるし、ウィンドウのクォータータイリングも現実的になる…はずなのだが、24インチや21.5インチの4kではあまりにも表示サイズが物理的に小さいため、結局左右タイルが限界であり、あまり情報量が増えない。 27インチもまぁまぁきついが並べるには限界サイズである。

私のディスプレイは基本的にメイン2+サブ1という使い方なのだが、今回は事情が事情だし、2枚は買えない。 そこで1枚だけ置き換えるのだが、そうするとメインディスプレイ同士で表示サイズが著しく違うという事態が生じる。

32インチはちょっと大きすぎるが、おけないこともない(32インチ2枚は机のサイズを考えても現実的でないくらいは厳しい)し、DPI差が小さく、妥協できるセッティングが出しやすい――このことはこの記事のこのあとの話で延々触れる。

ちなみに、アウトレット(展示品)というといまいち感があるが、ディスプレイの場合保証があったところで対応されづらいのが現実である上、対応されることのないドット抜けや表面の擦り傷というのがあって賭けみたいなところもあるので、動いている実物をチェックした上で買えるのはむしろメリットだと思っている。

今回は、これまで理解はしていたが、実際に混ぜてみたことで改めて実感したことを述べていこう。 もちろん、Linux前提である。

小さい? 大きい?

実測値としてはLG 22EN43は幅47.7cmで1920px (102dpi)、 ET322QKは幅69.3cmで3840px (140dpi) である。

102 / 140 = 0.728571427571… であるため、ドットは72.857%(約3/4)に小さくなったことになる。

逆に、ET322QKをFHD表示にした場合は145.71%に拡大されることになる。これは、単純に21.5インチディスプレイから同一解像度(FHD)のまま32インチディスプレイに変更した場合と同様のことである。

これは一辺を見た数字だし、基本的にコンピュータ上で表示されるものというのはボックス状なので、面積で言うと53.08%まで小さくなっているのでだいたい「半分になった」という感覚だし、FHDのままだと212.31%と「倍になった」感じがする。もちろん、ディスプレイの表示面の面積自体倍以上に大きくなっている。

これをまぜたとき、FHDで統一するともちろん4kディスプレイのほうが物理的に大きいぶん大きく表示される(倍以上に!!)のだが、実はこちらはあまり気にならない。 「大きいテレビで引き伸ばされた画面を見る」というようなことに慣れているからだろうか。実際、その画面を見ると「ギザギザでぼんやりしているなぁ」と私は思うのだが、でもそこまでみづらいということもない不思議だ。

ところが、FHDで適性なサイズにしている状態で4kに表示させると表示サイズが半分になっていながら表示する空間は4倍ある(表示可能な量は4倍にしかなっていないのだが、「半分のサイズで表示されている」「空間は4倍になった」というそれぞれ別の感覚が相乗効果を発揮する)のでやたらがらんとして見えるし、やはり適正サイズの半分というのは小さすぎる。 高密度になっているので意外と文字も読めるは読めるのだが、しかしながら非常にきつい。4kを4kとして運用する以上、元のままのスケールではちょっとやっていられない。

ちなみに、32インチのディスプレイは問答無用で大きい。一枚だけ使うにしてもかなり距離がないと大きすぎるくらいで、マルチディスプレイするサイズではないな、と感じる。

混ぜる場合どうスケールさせる?

4kのほうがいいディスプレイだし、物理的にも大きいので4kをメインに考えるべきだろうと思うのだけど、 72.857%ということは、元の状態でスケールしていなかったとしたらだいたい1.4倍にするとFHD側の元の状態と同じ物理サイズになる。1.5倍だとちょっと大きい。

ところが、1.4倍にスケールさせてしまうと、FHDの論理ピクセル数は1370となるため、HD(FWXGA)と同等になる。縦は771ピクセルである。 21.5インチのHDディスプレイというのは実在したが、ちょっと狭い。ウィンドウをタイルして並べるとやたら文字も大きく表示領域がまるで足りない感覚になる。

だから、間をとって1.2倍(あるいは1.25倍)というのがよさそうではある。フォントサイズは少し大きめにしたほうがいいかもしれない。4k側で文字が小さく感じるかもしれないし、部品が多少小さくなるのに比べて文字が小さくなる影響は大きいからだ。

1.2倍スケールの場合FHDの論理ピクセル数は横1600ピクセル、1.25倍スケールの場合1536ピクセルになる。1.25倍だとちょっと狭いが、1.2倍ピクセルなら「なんか表示が大きい」程度で済ませることもできそうな感じである。 MacなんかはUIが大きくぎっしり表示されるので、それが気にならない人は普通にいるだろうし、悪くないかもしれない。

試した結果は結局「間をとる」という無難な結論になってしまった。

ちなみに、今回の場合21.5インチFHDが2枚で32インチ4kが1枚という構成であるためにあまりFHD側を無視するわけにもいかなかったが、これが4k2枚でFHDが補助ディスプレイであるという話であれば1.4倍スケールでも別に構わないだろう。1370ピクセルあればウィンドウを常に最大化してしまえばそんなに気にならない、というか、そもそもラップトップが実DPIに合わせてスケールするとそれよりも小さくなるのが普通なので(私のThinkPad X1 Carbon(14インチ FHD)は148DPIでスケールされているため論理ピクセル数は1228である)表示スペースが足りずにはみだすようなことはあまりない。

それぞれスケールできない?

できない、らしい。

Windowsだとディスプレイごとに「拡大率」という値を設定できるようになっている。 この拡大というのはまんまスケーリングを意味しているので、ここで175%を設定すると論理1ピクセルに対して1.75ピクセルをカウントするようになる。

だが、この設定が今のところLinuxでは上手くできない。 最もスケーリングが細かくできるのはKDE Plasmaだが、それでもディスプレイごとに独立した設定はできないようになっているようだ。

xrandrを使うことで設定自体は可能だが、少数の値を設定してしまうとフォントがすごく汚く表示されることになる。

だから、現時点ではディスプレイごとのDPI差を適切に埋める完璧な方法はない、ということになるだろう。

フォントだけ合わせるという方法

今回の場合、51.6%に縮小されるもののUIのサイズとしてたいていの場合は51.6%というのは私にとっては許容できるサイズに収まった。

そこで、私がとった方法がこれだ。

実DPIによる影響が最も大きいのは「文字サイズ」であるため、LinuxでもUIスケーリングとは別にフォントはスケーリングできるようになっている。

そして、フォントのスケーリングの構造はちょっとめんどくさい。

フォントの場合96を1として、設定されたDPIの倍率にスケールされる。 つまり、144DPIを設定した場合、144 / 96 = 1.5 なので、1.5倍にスケールされる。

フォントにおける1は1ピクセルであり、1ポイントでもあるのだが、両者は同時にスケールされることになり、基本的には同一視できる。 FontConfigは144DPIを設定した場合、16pxを求めても、16ptを求めても、24実ピクセルで描画する。 問題はビットマップフォントを使う場合だが、その話は割愛する。

基本的に115.2DPIにすれば1.2倍スケールとなる。120DPIで1.25倍スケールだ。 UIと比べ柔軟に設定できるので、このあたりを参考にバランス良い設定になりそうなDPIを設定すると文字側は調整できる。

私は今のところ120-136DPIの範囲で様子を見ている感じだ。 KDE Plasmaの場合、ほとんどのアプリケーションはPlasma Workspace側で設定されたDPIに従うが、ConkyはFontConfig設定ファイルを尊重するため、Conkyのサイズ調整を目的に異なった値を設定する方法もある。

あとは、積極的にフォント側DPIを設定してからUIスケーリングでバランスをとる、という方法もある。 この方法はもっと実DPIに差がある場合の解消方法として使える。 また、フォントのみで解決する場合は細かなUIスケーリングがいらないため、「Hi-DPIのためにKDE Plasmaを使わなくてはならない」という状況を避けられる。 (KDE Plasmaは0.1倍単位でUIスケールできる)

もはや、DPIとかピクセルとかポイントとかいう、定義が明確であるはずの言葉が相対的なものになってしまっていて意味がわからないが。

なお、フォント設定でスケールする場合に特に重要なこととして、「普段GTKデスクトップを使っていて、スケーリングのためにKDE Plasmaにスイッチした人」は、.xprofileなどでexport QT_QPA_PLATFORMTHEME=qt5ctとかしているのであれば、それをやめないとKDEの設定がちゃんと反映されず、GTK2アプリケーションにも反映されない。

また、この方法を取る場合、パネルだけはCinnamonもPlasma Workspaceも高さがピクセル単位になっているため大幅に小さくなってしまう。このため、パネルの高さは再調整が必要だ。 私の場合、サブディスプレイ上にパネルを置いているため問題はなかった。

ブラウザのスケーリング

ウェブブラウザはちょっと特殊な事情を持っているようだ。

Chromium系(ChromeもVivaldiも)ブラウザはフォントのDPI値が約110%以上(103以上?)であるとき、そのDPI値に合わせて10%単位でスケールするようだ。 これはブラウザをズームしたときと同じ挙動だが、困る場合がある。

これによってパーツがはみ出してみづらい場合があるが、これについてはまだズームを落とせばいいので許せる。 問題はフラゲ(フラッシュゲーム)である。 見た目が汚くなる上に動作が遅くなって非常に辛い。

なお、Firefoxはまた事情が違うのだが、layout.css.devPixelsPerPx1にすれば自動スケールは行われなく成り、-1にすると自動的にスケールされる(多分、UIスケールによるのだが、DPIによるのかもしれない)。この機能に関してはlayout.css.dpiも絡む。

実際、メイン/大きな4k * 1 + サブ/小さなFHD * 2 ってどう

だめ。 どうしたってみんな4kを取り合ってしまう。

なにをするにも大概大きい4kっていうのは便利で、できればそこに置きたいという気持ちが強い。 みっちり書かれている文章だとそうでもない(FHDの全画面表示でもテキスト量が多すぎる)けれども、なにかしら情報が付属していたりマルチペインだったりするのが現代なので、たいていのアプリケーション及びコンテンツが4kを奪い合う。

サブは私の場合メール, Discord, Twitterなんかになるのだけど、これらは基本的にリアルタイムで見続けるようなものでもないからそれぞれ全画面化してサブに置いているものの、4kだったらモニタリング機能とか作ってタイルして色々表示させてもいい。

だから特に必要ないものも含めてたいていのアプリケーションは大きな4k(もちろん、適切な大きさの)を欲しがる。 21.5 FHDを回転させて縦にするとバランスはいいが、表示できるものはさらに少なくなる。

32インチを複数置くのは難しいので、やはり27インチ4k*2 + 21.5もしくは24インチFHDというのがバランスがいいと思う。 逆にサブを32インチ4kにして少し離してモニタリングに使う手もあるけど。

Acer ET322QKってどう (2018-12-03 追記)

基本的には悪くないと思う。 少なくとも22EN43/22EN33のように色味がおかしくて輝度もおかしくて視野角も異様に狭いといった問題はない。 特別良いということもないけれど、かといって目立った問題があるわけでもない。

特別良いというわけではなく、色味も標準(というフラット設定)ではフラットではないため、アートワークの作業をするクリエイターにはとても耐えないし、ゲーマーにも無理だろうけれど、 動画視聴程度であれば遅延が気になるということはないし(ただビデオカードのほうは4kなのでちょっと重いけど)。

色味も、特に優れたところはないけれど、別に使えないことはない。一応sRGB 100%らしいので、カラーキャリブレーションすれば結構使えるのかもしれない。

目立った問題としては入力端子が3系統(HDMI 2.0×2, DP 1.2×1)であることだろう。 台数が多いとなるべく集約したいので、端子はなるべく欲しい。 私の環境だとDVI-Iが多いけど、別にDVI-ItoHDMIは可能なのでHDMIで良しとして…

メーカー モデル ポート
IO DATA EX-LD4K271DB D-Sub, HDMI(2), HDMI 2.0, DP
IO DATA KH2750V-UHD D-Sub, HDMI(2), HDMI 2.0, DP
BenQ EL2870U HDMI 2.0(2), DP
LG 27UK650-W HDMI(2), DP
iiyama ProLite B2875UHSU B2875UHSU-B1 DVI, D-Sub, HDMI 2.0, DP
JAPANNEXT JN-IPS27FLUHD HDMI 2.0(2), DP(2)
DELL S2817Q HDMI(2), DP, miniDP
ASUS VP28UQG HDMI 2.0(2), DP

JAPANNEXTがIPSで消費電力も最大35Wと低いのに安くてなんか強い。 それはともかくとして、以前のように端子数5を越えるものは減っている感じだけど、3というのは結構少なめ。 端子数4は普通に狙えるので、そこは残念ポイントな感じがする。

最大の難点は、起動が遅いということだろう。 EIZOとかも遅いので、品質の問題ではないけれど、結構遅い。そして、切り替えも遅い。信号がなくなってから再び信号を捉えるまでが長い。

「待てばいいじゃん」と思うかもしれないが、実は KDE Plasmaでは深刻な問題になる

KDE Plasmaで思わぬ問題 (2018-12-03 追記)

KDE Plasmaの場合、ディスプレイに対してディスプレイの接続方法ではなく、「ディスプレイの認識上の番号で」識別する。 KDE Plasmaはディスプレイを中途半端に重ねることも可能で柔軟なのはいいのだが、応答の早いLG及びサムスンのディスプレイはすぐつくのだが、このときKDE Plasmaは「ディスプレイが2台しか接続されていないように見間違う」。

つまり、左から

  • LG HD
  • ET332QK
  • サムスン HD

と並んでいて、パネルはサムスンの上にあるのだが、 このときこの並び順に最初にKDEにログインした時点では認識されている。 だから、パネルは3番ディスプレイにある。

ところが、一時ブランクスクリーンになって復帰すると、ET332QKの認識が遅れるためにサムスンが2番になり、ET332QKが3番になる。 結果としてサムスンとET332QKの壁紙が入れ替わり、パネルはET332QK上に移動してしまう。 さらに、なぜか中心座標を見失ってしまって、Conkyが1920pxずれる。

3台であれば右にあるディスプレイをプライマリディスプレイにすることで1番を固定すればET332QKが最後にくるように固定できるから問題は軽減される。 だが、アンバランスな配置のせいかPlasmashellがバグることが多い。さらに、どうしても左側のディスプレイをy:1081に固定するのが難しい。y:0になってしまう。

また、マルチディスプレイではKDEはフルスクリーンにしたときにパネルの表示がおかしくなる。 パネルの表示の上に古いパネルの表示がかさねられたようになる。つまり、以前同アプリケーションでフルスクリーンにしたときと同じ状態になる。 確実になるわけではないが、一度発生するとフルスクリーンにするたびに再現しつづける。

結局、私はCinnamonに戻した。 フォントのスケーリングを中心としてUIスケーリングしないことにしたため、これでも問題はない。

CinnamonのフォントスケーリングはDPIではなく倍率になっている。 0.1倍単位だが、1.25倍で120DPI, 0.1倍あたり9.6DPIというのを基準に考えれば良いだろう。 今の状況を考えるとこちらのほうが素直だろう。

このままではQTアプリケーションが小さいので、.xprofileQT_SCALE_FACTORを設定しておくと良いだろう。 1.2とか1.25あたりが無難な値になるだろうか。

ところがCinnamonでも… 原因はDP (2018-12-05 追記)

Cinnamonなら大丈夫と油断していたところ、Cinnamonでもブランクスクリーンに落ちるとおかしなことになってしまった。 パネルがおかしくなるといったことはないのでKDE Plasmaよりはマシではあるものの、好ましい状態ではない。

どうも他のディスプレイでは発生しない症状として、「電源がオフになると切断される」らしく、問題はディスプレイの電源を切っても発生する。 そして調べていくと、「DPの仕様」らしいとわかった。なるほど、確かに他の2台はminiDP→DVI-Iで接続しているのでDPではささっていない。

WindowsだろうがLinuxだろうが、ディスプレイのホットプラグで問題が生じないなんてことはないので、これは大迷惑である。ディスプレイを共有して作業していることなんて普通にあるのだし… 実際、この挙動は相当強く嫌われているようだ。

なんとかしようとがんばって/etc/X11/xorg.conf.d/90-mhwd.conf

Section "Device"
    Identifier     "Device0"
    Driver         "nvidia"
    VendorName     "NVIDIA Corporation"
        Option "NoLogo" "1"
        Option "UseHotplugEvents" "false"
        Option "AllowEmptyInitialConfiguration" "true"
EndSection

などと書いてみたものの残念ながら効果はなし。

ただ、この場合問題ははっきりしているので、本気になればやりようはある話だと思う。 とりあえずは私の場合ディスプレイの電源を切らないように設定してしのいでいるが、困るのは「通し作業のときにディスプレイを切って節電する」という方法がとれないことだと思う。

そのうち何か考えて対応したい。

がんばって解決した人がいるようです (2018-12-16追記)

Twitterでのやりとりを経てエヌユルさんがxrandrを使う方法で解決した旨ブログにかかれていました

実はこの方法、私にとっては既知で、以前のスケールとDPIのアーティクルを含めて「あんまよくないので言及を避けていた」方法だったりする。 しかし、参考にしてもらえるなら、もっとちゃんと説明すればよかったな、この方法でよかったなら悩ませずに済んだのに…と割と後悔している。

手順、及び結果はどうブログの記事の通りである。 ちなみに、ディスプレイ位置が上限に合わせられてしまうのは「0,0にディスプレイを欲しがる」からで、左のディスプレイが4kなら問題ないのだが、そうでないとFHDディスプレイを上にあげたがる。 Plasma Workspaceだと勝手に修正されてしまったりする。

私が言及を避けたいと思う理由は次の通り

  • ディスプレイをネイティブ解像度以外にしたときのようなもやっと感がある
  • xrandrのスケーリングはFTより後段にあるため、字の描画が大変汚い
  • Plasma Workspaceはひょんなことでこの設定をリセットしてしまうのでえらいことになる(パネルが吹っ飛んだりする)。 これは、ワークスペース切替時、アクティビティ切替時、ロック時などに発生しがち
  • DPのホットプラグ切断による問題がより深刻化する
  • 私としてはUIサイズはそれほど気にしないがフォントサイズの落差が辛い、ということを問題にしているので、FHD側を1/4角にするというのはフォントサイズの設定において事情が変わらない(単に元はFHDが4倍角だっただけの話なので、DPIをだいたい中間に設定するという話から動かない)

UIスケーリングに関しては、現代においては「ブラウザ(特にBlink系)がフォントDPIに従って勝手にスケールしやがるので、中間DPIを設定しておけばだいたい許せる結果になる」というのが私の感想である。 画像を見たり、VSCodeとかAtomを使う分には割とどうとでもなるので(ディスプレイを4k/FHD間で動かすのは大変だけど)、「フォントサイズさえ妥協できるサイズにしとけばいいや」が私の現状の結論。 もちろん、言うまでもなく「ディスプレイごとに適切スケールさせろ」と言いたいところだけど、未だにNvidiaがLinuxでマルチヘッドディスプレイに対して雑な対応を続けているあたりを考えると、多分無駄な主張になるだろう。 世の中マルチヘッドディスプレイが当たり前になっていっているわけでもないし。

あと、本題とは関係ないが

世の中のwebサイト巨大ディスプレイに最適化されてなさすぎですね.

これについてはDPIと画面サイズとスケーリングとピクセルの話で書いているけど、基本的に現代においては「1ピクセルが物理的1ピクセルを意味しない」というスケーリングの方向であり、 14インチのThinkPad X1 Carbonですら横の論理ピクセルは1288pxである。12.5インチのThinkPad X280では1047pxしかない。 この方法は、そもそも「物理的にピクセル数が増えても論理ピクセル数は増えない」というものなので、XPS13の4kを使ったところで、論理ピクセル数は1200pxに満たないのだ。

私はFCとしては120dpiに設定しているので、ブラウザは1.2倍にスケールするのだが、それでも4k側だと3200pxも幅があることになる。 さすがにこれを「想定しろ」というのは無理な注文だと思っている。 4kを使うならウィンドウをタイルする、で良いのではないだろうか。大きな4kディスプレイを持っている人はある程度知識がある人のほうが多いし、安全側に倒すならそちらを優先した設計はできない。

どちらかといえば私が考慮すべきなのではないかと考えるのはChromium及びFirefoxのテーマだ。 あれらは全くスケールしないため、4kで最大化すると画像サイズが足りずすっかすかになる。

Baloo File Extractorの大暴走

顛末

BalooはKDE5のファイルインデックス機能。 かなり性質は違うものの、部分的に見ればKDE4のNepomukを置き換える機能だと私は見ている。

先日、突然デスクトップが非常に重くなった。操作に対して数秒反応しないということを繰り返す。 私はConkyで常に状態を見ているのだが、Baloo File ExtractorがCPUを2.5%(=ロード1.0)使用しており、 IOも非常に高い。しかし、止まるほどではない気がするのだけど…と思い、嫌な予感がしてjournalctlしてみたら

11月 19 08:29:06 hydrangea baloo_file[2401]: KDE Baloo File Indexer has reached the inotify folder watch limit. File changes will be ignored.
11月 19 08:29:06 hydrangea baloo_file[2401]: KDE Baloo File Indexer has reached the inotify folder watch limit. File changes will be ignored.
11月 19 08:29:06 hydrangea baloo_file[2401]: KDE Baloo File Indexer has reached the inotify folder watch limit. File changes will be ignored.
11月 19 08:29:06 hydrangea baloo_file[2401]: KDE Baloo File Indexer has reached the inotify folder watch limit. File changes will be ignored.
11月 19 08:29:06 hydrangea baloo_file_extractor[2677]: qt5ct: using qt5ct plugin
11月 19 08:29:06 hydrangea baloo_file[2401]: KDE Baloo File Indexer has reached the inotify folder watch limit. File changes will be ignored.
11月 19 08:29:06 hydrangea baloo_file[2401]: KDE Baloo File Indexer has reached the inotify folder watch limit. File changes will be ignored.
11月 19 08:29:06 hydrangea baloo_file[2401]: KDE Baloo File Indexer has reached the inotify folder watch limit. File changes will be ignored.
11月 19 08:29:06 hydrangea baloo_file[2401]: KDE Baloo File Indexer has reached the inotify folder watch limit. File changes will be ignored.
11月 19 08:29:06 hydrangea baloo_file[2401]: KDE Baloo File Indexer has reached the inotify folder watch limit. File changes will be ignored.
11月 19 08:29:06 hydrangea baloo_file[2401]: KDE Baloo File Indexer has reached the inotify folder watch limit. File changes will be ignored.
11月 19 08:29:06 hydrangea baloo_file_extractor[2677]: inotify_add_watch(/home/haruka/.config/fcitx/dbus) failed: (No space left on device)
11月 19 08:29:06 hydrangea baloo_file_extractor[2677]: inotify_add_watch(/home/haruka/.config/fcitx/dbus/4b235cc9521d448a9769a6f507904e37-0) failed: (No space left on device)
11月 19 08:29:06 hydrangea baloo_file[2401]: KDE Baloo File Indexer has reached the inotify folder watch limit. File changes will be ignored.
11月 19 08:29:06 hydrangea baloo_file_extractor[2677]: QFileSystemWatcher::removePaths: list is empty
11月 19 08:29:06 hydrangea baloo_file[2401]: KDE Baloo File Indexer has reached the inotify folder watch limit. File changes will be ignored.
11月 19 08:29:06 hydrangea baloo_file_extractor[2677]: QFileSystemWatcher::removePaths: list is empty
11月 19 08:29:06 hydrangea baloo_file[2401]: KDE Baloo File Indexer has reached the inotify folder watch limit. File changes will be ignored.
11月 19 08:29:06 hydrangea baloo_file[2401]: KDE Baloo File Indexer has reached the inotify folder watch limit. File changes will be ignored.
11月 19 08:29:06 hydrangea baloo_file[2401]: KDE Baloo File Indexer has reached the inotify folder watch limit. File changes will be ignored.
11月 19 08:29:06 hydrangea baloo_file[2401]: KDE Baloo File Indexer has reached the inotify folder watch limit. File changes will be ignored.
11月 19 08:29:06 hydrangea baloo_file[2401]: KDE Baloo File Indexer has reached the inotify folder watch limit. File changes will be ignored.

地獄だった。 要はBalooがinotifyを食い尽くしてしまっていて、カーネルレベルでのエラーを(他を巻き込みつつ)無限に繰り返している、と。

というわけでBalooを止める。完全に。

$ balooctl disable
$ rm -rf .local/share/baloo
$ systemctl reboot

インテグレーテッドシームレスUXの代償

最近はOSが統合的な環境を提供するというのはひとつの流れになっていると思う。 やり始めたのはAppleだと思うけど、ユーザーの囲い込み勝負になっていて、WindowsだってなにかしようとすればWindowsのソフトウェアが自動的に起動する。 そのインターフェイスにもCortanaを使わせようとするし、各コンポーネントが密結合し、「全体でひとつ」に見せようとしてくる。

これが良いことなのかどうかは、ちょっと私には判断しかねる。 少なくとも理想的な挙動を考えればシームレスで統合されているのは美しいことだ。 だが、現実はそうはいかない。気に入らないソフトウェアや気に入らない挙動、そしてもっと好きなソフトウェアというのはどうしたってあらわれるものだから。 KDEが統合的かつ多角的に機能を提供してくれることは、私は好ましいことだと思っているが、ではそれに満足しているかというと、実際のところKDEPIMですら「余計なもの」だと感じている。KDE TelepathyではなくPidginを使っているし、KMailでなくClaws Mailを使っているし、Akonadiに至ってはいらないとすら思っている。

そして何より気持ちわるい。 AppleやMicrosoftやGoogleが統合的に機能を提供しようとするのは、ユーザーのUXのためではないし、単なる囲い込みのためでもない。 ユーザーの情報を集約し入手するためだ。 FacebookがなんでもかんでもFacebookを経由して利用させ、かつFacebookを常に開いておくように要求するのもそのためだ。 そういう意図を持っているのがわかっているのに、情報を集める機能があるというのは、私はすごく気持ち悪いと思うのだ。

KDEコミュニティはそのようなことはないだろう。なんといっても、情報を集約したところでその使い途がない、というかそもそもそんなサーバーがない。 サーバーがあったところで、ではそのデータは誰の所有物かという問題になる。 だからKDEに情報収集機能があってもそれほど問題はない…はずだが、それでも私はNepomukも気持ちわるいと感じていたし、Balooもそんなに歓迎していない。

そもそも、私の感覚からいえば、ファイルインデックス系の機能というのは無駄なコストだ。

基本的にファイルは属性に応じてちゃんとヒエラルキーを持って管理しているし、「フォルダをまたいで特定の条件でファイルを抽出したい」というケースはかなり稀だ。 もちろん、全く役に立たないとは言わない。その稀なケースでは役に立つわけだから。

だが、支払うコストがそれに見合ったものではない。 基本的にファイルインデックス系の機能は常に非常に多くのアクセスを行うし、CPU時間も長い。 つまり、ファイルインデックス機能が機能するために必要とするIO及びCPUのコストは極めて高いのだ。

ご存知の通り、Windows Updateは「Windows Updateをするべき余地がない」ことが確定しない限り非常に重い動作になる。 どれほど高性能なコンピュータを使っていても、ほぼ使い物にならない(マウスカーソルも止まるし、メニューも開けない、文字入力もひどいラグが発生する)状態になる。 常にWindowsを立ち上げっぱなしの人であればそれほど気にならないだろうが、Windowsをそれほど起動しない人にとっては、Windowsは常に操作をうけつけない印象になる。 これはアップデートのための話になるが、もちろんアップデートのためにこのようなアクセスを行うことは優れたデザインではない。

このような、操作を明らかに妨げ、コンピュータが使い物にならなくなるような、利用可能な時間が制限されるような、ディスクデバイスの寿命を縮めるような、コンピュータが著しくストレスを生じる性能であるかのように思わせるようなコストを払ってまで必要な機能ではない、と私は思うのだ。

KDEに関してはNepomukでも同じようなことを経験したはずだ。CPUを食いつぶし、IOを食いつぶし、メモリを食いつぶしてコンピュータが使いものにならず、どれほど崇高な理想を掲げたところでコンピュータが使いものにならなくなればそれは意味がないということを思い知ったはずだ。 Nepomukは結局ほとんどのプログラムに利用されることなく終わったし、KDE5には継承されなかった。 にもかかわらずBalooを採用した。いや、Nepomukでの失敗を踏まえて改善したものを投入したのかもしれないが、そもそもNepomukがなぜ失敗したのかということを理解していない、結局わかっていない。 実際のところBalooについて調べると「お前を消す方法」で溢れてしまうのがその証左だろう。

「優れたUXはあれこれお節介を焼くことではなく、余計なことは何もしないことである」ということに、 一体いつ気がつくのだろうか。

Libreofficeが超絶重くなった

Libreofficeがドキュメントを開くとものすごく重くなった。だいたいフリーズというレベルである。

どうもglibとの組み合わせによるようで、今年の頭くらいには発生していた問題だったようだ。 私の環境ではいままで顕在化してこなかった。

CPUが2.50%で張り付いている。 私のマシンは40コアなので、要はコア占有状態ということだろう。

glibの問題ということでUIテーマを変更すれば解決するようだ。 具体的には$SAL_USE_VCLPLUGIN環境変数により使用するUIエンジンを強制する。 選択肢は優先度順に

  1. gtk3
  2. gtk
  3. gtk3_kde5
  4. qt5
  5. kde4
  6. gen

であるようだ。

で、glibの問題なので要はデフォルトでgtk3が使われてしまうけれど、gtk3を使わせなければ良い、と。

私の環境はそもそもKDE Plasmaベース (デスクトップはCinnamon) なので、KDEを使わせたいのだが、 現状Arch Linuxのlibreofficeはビルド時に--enable-qt5していないため、qt5が使えない。 もちろん、kde4は今や使えない。gtk3_kde5してしまうと結局同じ問題が発生する。 (gtk3との違いはファイルダイアログを表示すればわかるだろう)

そこで、SAL_USE_VCL_PLUGIN=gtk libreofficeとすれば正常に動作する。gtkでなくgenでも良い。

以前から割とgtk3テーマのlibreofficeは重かったので、もしかしたら常に強制しても良いのかもしれない。

ここらへんの情報はArchwikiでも古くて間違っているので困る。記述も雑だ。

Libreofficeは滅多に使わないのだが、請求書とか発注書とかはLibreofficeで書いている。 MS Officeと同程度にはやっぱりストレスがたまる。

この手のソフトウェアとしてLibreofficeよりも良い選択は恐らくない。AbiWordもCalligra Officeも機能的あるいは実用的に遠く及ばない。 にしても、やっぱりLibreofficeできれば使いたくないところだ。 紙面ベースのレイアウトをする場合はHTMLもそんなに快適ではないのでやむなく使ってはいるが。 (この手の書類は見た目だけの問題で意味的に整理する必要は全くないし)

とりあえずこうしてUIエンジンをかえられることを知っておくと今後もなにかの役に立つかもしれない。