まんぼう日記

takataka's diary

Ubuntu 14.04 LTS で Intel SSD 750 を使えるようにする

昨日今日は学園祭&研究室公開でした.たくさんの方にお越しいただき,ぐにゃぐにゃしたり眼からビーム出したりして頂きました (^^) ありがとうございます.

 

その合間に,先日GPGPU用マシンに挿した Intel SSD 750( cf. NVIDIA GeForce GTX TITAN X - まんぼう日記 )を使えるように設定する作業をちょこちょこやってまして,一応うまくいったので,メモっときます.

 

 

ただ,例によってあまりちゃんとわかってないまま作業して,余計な回り道をしたりしてます.さらに,以下の作業をやると微妙にPCの挙動がおかしくなってるかもしれない(研究室公開の裏でこそこそやってたので,ちゃんと調べる時間が…言い訳 (^^;)ので,あまり信用しないほうがよいです.

 

作業したマシンの環境などは,続 GPGPU用マシンにCUDAをインストール - まんぼう日記 とそのリンク先を参照してください.あ,OSは記事のタイトルどおり Ubuntu 14.04 LTS です.

 

 

 

Linuxカーネルを 3.19 にする

 

まず,Intel のサイトの情報:https://downloadcenter.intel.com/ja/download/23929/-Solid-State-Drive-NVMe-

を見ると,このSSDを使えるようにするには NVMe というドライバが必要 → Linux ではバージョン 3.19 のカーネルでそれが組み込まれたので,カーネルを 3.19 に上げないといけない,ということがわかりました.Intel Linux NVMe Driver Reference Guide for Developers というPDF文書に,そのやり方も書いてあります.

 

ところが,その手順通りに 3.19 にして再起動すると,

$ nvidia-smi
modprobe: ERROR: ../libkmod/libkmod-module.c:809 kmod_module_insert_module() could not find module by name='nvidia_346'
modprobe: ERROR: could not insert 'nvidia_346': Function not implemented
NVIDIA-SMI has failed because it couldn't communicate with the NVIDIA driver. Make sure that the latest NVIDIA driver is installed and running.

とか言われてしまいました.NVIDIA のグラフィックカードのドライバがちゃんと動いてないと.Theano でGPU使うプログラムを実行してみると,同じメッセージを出したうえでCPU上で動いてる様子….こ,これはヤバイ….たかたかだけでなく学生も CUDA & Theano で GPGPU してるマシンなので,使えなくなると超ヤバイ….ちうわけで大焦り  \(@_@\ ... /;_;)/ 

 

どないもならへんので,しばらく逃避して,ぐにゃぐにゃカメラの前でちびっこと走り回ります (^^) その後,もう一度調べてみると,Ubuntu では次のようにしてカーネルを更新することができるというのがわかりました.

$ sudo apt install linux-generic-lts-hoge

hogeは,コードネームの一部です.たかたかの場合,Ubuntu 15.04 Vivid Vervet のカーネルバージョンが 3.19 だということで,vivid にしてみました.

 

そしたら,nvidia-smi コマンドがちゃんと動くようになり,Theano で GPGPU するプログラムも以前のように動くようになりました(右往左往してるうちに NVIDIA のドライバも nvidia-346 から nvidia-352 に更新しちゃいました).これで一安心.SSDのデバイスファイル /dev/nvme0 と /dev/nvme0n1 もちゃんと存在してます.というわけで,再び研究室公開の仕事というか遊びというかに戻ります.今年もたくさんの卒業生が遊びに来てくれたので,いろいろ近況を聞かせてもらったり.

 

ファイルシステムを構築して mount する

研究室公開が終わって片付けも済ませたので,腰を据えて続きにかかります.

 

パーティションの作成

 

まずはパーティションを作成.複数パーティションに分けたいわけやないんやけど,上述のPDF文書を読むと,

Be sure the starting block of the used partition is divisible by 4096 bytes.

とか書いてあります.なんでや,と調べてみたら,こんな文書を見つけました: Partition Alignment - Thomas-Krenn-Wiki

 

SSD などのデバイスの性能を発揮させるためには,ファイルシステムブロックの境目が変なとこに行かへんようにせなあかん,ということのようです.そういうことならと,fdisk 使ってパーティションを作成します.

$ sudo fdisk -c -u /dev/nvme0n1
デバイスは正常な DOS パーティションテーブルも、Sun, SGI や OSF ディスクラベルも
含んでいません
新たに DOS ディスクラベルをディスク識別子 0x97038cec で作成します。
あなたが書き込みを決定するまで、変更はメモリ内だけに残します。
その後はもちろん以前の内容は修復不可能になります。

警告: パーティションテーブル 4 の不正なフラグ 0x0000 は w(書き込み)によって
正常になります

コマンド (m でヘルプ): p

Disk /dev/nvme0n1: 400.1 GB, 400088457216 bytes
ヘッド 64, セクタ 32, シリンダ 381554, 合計 781422768 セクタ
Units = セクタ数 of 1 * 512 = 512 バイト
セクタサイズ (論理 / 物理): 512 バイト / 512 バイト
I/O サイズ (最小 / 推奨): 512 バイト / 512 バイト
ディスク識別子: 0x97038cec

  デバイス ブート      始点        終点     ブロック   Id  システム

コマンド (m でヘルプ): n
Partition type:
   p   primary (0 primary, 0 extended, 4 free)
   e   extended
Select (default p): p
パーティション番号 (1-4, 初期値 1): 1
最初 セクタ (2048-781422767, 初期値 2048):
初期値 2048 を使います
Last セクタ, +セクタ数 or +size{K,M,G} (2048-781422767, 初期値 781422767):
初期値 781422767 を使います

コマンド (m でヘルプ): p

Disk /dev/nvme0n1: 400.1 GB, 400088457216 bytes
ヘッド 64, セクタ 32, シリンダ 381554, 合計 781422768 セクタ
Units = セクタ数 of 1 * 512 = 512 バイト
セクタサイズ (論理 / 物理): 512 バイト / 512 バイト
I/O サイズ (最小 / 推奨): 512 バイト / 512 バイト
ディスク識別子: 0x97038cec

  デバイス ブート      始点        終点     ブロック   Id  システム
/dev/nvme0n1p1            2048   781422767   390710360   83  Linux

コマンド (m でヘルプ): w
パーティションテーブルは変更されました!

ioctl() を呼び出してパーティションテーブルを再読込みします。
ディスクを同期しています。

 

念のため parted でも確認してみると...

$ sudo parted /dev/nvme0n1
GNU Parted 2.3
/dev/nvme0n1 を使用
GNU Parted へようこそ! コマンド一覧を見るには 'help' と入力してください。
(parted) unit b
(parted) p
モデル: 不明 (unknown)
ディスク /dev/nvme0n1: 400088457216B
セクタサイズ (論理/物理): 512B/512B
パーティションテーブル: msdos

番号  開始      終了           サイズ         タイプ   ファイルシステム  フラグ
 1    1048576B  400088457215B  400087408640B  primary  ext4

というわけで,めでたく開始ブロックがPDF文書の例と同じ 1048576B ( = 256 x 4096B) になりました.

 

mkfs して mount してみる

 

次は,mkfs コマンドでファイルシステムを構築します.ext4 でいくことにしました.

$ sudo mkfs.ext4 /dev/nvme0n1p1
mke2fs 1.42.9 (4-Feb-2014)
Discarding device blocks: done
Filesystem label=
OS type: Linux
Block size=4096 (log=2)
Fragment size=4096 (log=2)
Stride=0 blocks, Stripe width=0 blocks
24420352 inodes, 97677590 blocks
4883879 blocks (5.00%) reserved for the super user
First data block=0
Maximum filesystem blocks=4294967296
2981 block groups
32768 blocks per group, 32768 fragments per group
8192 inodes per group
Superblock backups stored on blocks:
    32768, 98304, 163840, 229376, 294912, 819200, 884736, 1605632, 2654208,
    4096000, 7962624, 11239424, 20480000, 23887872, 71663616, 78675968

Allocating group tables: done
Writing inode tables: done
Creating journal (32768 blocks): done
Writing superblocks and filesystem accounting information: done

 

ファイルシステムの作成ができたようなので,試しに手動で mount してみます.

$ sudo mkdir /hoge
$ mount /dev/nvme0n1p1 /hoge
$ mount
   :
/dev/nvme0n1p1 on /hoge type ext4 (rw)
   :
$ ls /hoge
lost+found

うん,問題ないようです.

 

/etc/fstab を書く

 

じゃあブート時に自動でマウントされるように /etc/fstab に書いときましょーってことになるんですが,/etc/fstab を眺めたら,今時は /dev/nvme0n1p1 みたいなデバイスファイル名を書くかわりに,UUID でデバイスを指定するのがよいそうな.知らんうちに進歩してます.

 

で,UUID は blkid コマンドで調べられるっていうんやけど,試してみても /dev/nvme0n1p1 のUUIDがわかりません.調べたら,/dev/disk/by-uuid で確認できるとのこと.実際に

$ ls -l /dev/disk/by-uuid

したら,UUID 出てきました.

 

というわけで,UUID を使って /etc/fstab を書いて,mount できることを確認.やれやれ,ようやくこのSSDが使えるようになりました.

 

 

ベンチマークとってみる

 

使えるようになったので,早速ベンチマークをとってみます.一般的なベンチマークの結果は探したらいろいろ出てくるでしょうから,ここでは自分たちの使用目的に即した状況で実験することにしました.ILSVRC2010の学習用画像120万枚を OpenCV の imread で読み込むのにかかる時間を調べます.比較対象は,今回SSDを挿したマシンの内蔵HDD,Western Digital の WD5003ABYZ ( WD Re SATA 6 Gb/s, 7200rpm, 容量500GB, キャッシュ64MB)です.

 

結果はこうなりました.

  • HDDから読み込むのにかかった時間: 9867s
  • SSD から(2回の平均): 2858s

 約3.5倍.こんなもんなんかどうか全然わからへんねんけど,まあ速いっすね 

(^^;