2022/06/13(月)Ubuntu LinuxでVMware Workstation pro/playerを使うときの注意

割と長いこと(15年くらい?)、windowsにVMwareを入れて(というかVMwareしか入れない)、そこにFreeBSDやLinuxを入れて、その中で生活する、という生活を続けてきました。LinuxなどのPC-UNIXはハードウェアの違いを吸収する力が弱く、windowsをハードウェアの違いを吸収するためだけに使う、という考え方でした。しかし、ここ2年くらい、Linux (Ubuntu) の完成度は十分高くなり、デスクトップなら当然、ノートPCでも、普通にインストールすれば大体普通に動くようになってきました。そこで、ホストとゲストを逆転させて、PCには基本的にUbuntuを入れてそこにLinux版のVMwareを入れ、どうしてもwindowsを使いたいときだけ仮想で飼っているwindowsを使うようになりました。

UbuntuでVMwareを使うときの特別な設定を備忘録も兼ねて書いておきます。誰かの役に立つかもしれないので。

ゲストが異常に重くなる現象への対策

特に複数ゲストを起動したときなどに、ゲストがほとんど操作不能なレベルで重くなってしまい、そのときホストではkcompactd0というプロセスのCPU使用率が100%になっている、という現象が見られることがあります。数分待つと解消しますが、またすぐに再発します。これは多くの人が悩まされ決定的な対策はなかなか見つからなかったのですが、
にあるように最近対策が見つかりました。rootで(sudo suとかした後に)、
echo 0 > /proc/sys/vm/compaction_proactiveness
とすると立ちどころに収まります。永続的にこれを設定するには、/etc/sysctl.confに
vm.compaction_proactiveness=0
と書き加えて再起動すればいいようです。

Ubuntu 22.04でVMware Workstationを使う

現時点でVMware Workstationの最新版は16.2.3-19376536ですが、これはまだUbuntu 22.04の新しいカーネルに対応していないようで、初回起動時のカーネルモジュールのコンパイルでエラーになってしまい、起動することができません。そのうち対応するでしょうけど、とりあえず、
にあるように、
git clone https://github.com/mkubecek/vmware-host-modules
cd vmware-host-modules
make clean
make
sudo make install
sudo modprobe -a vmw_vmci vmmon vmnet
sudo service vmware restart
で起動するようになりました。

NATを使ったとき、断続的にネットワークがON/OFFを繰り返す

ゲストOSのネットワークをNATにしたとき、ゲストOSの種類には関係なく、断続的に(10秒周期くらい?)ゲストのネットワークがON/OFFを繰り返す、という困った現象に遭遇しました。Ubuntu 22.04にVMware Workstationを入れたときに発生したのですが、別のマシンにUbuntu 22.04とVMware Workstationを入れて発生しないケースもあったので、発生する条件はよく分かりません。 (2022/6/15追記: その別のマシンでもこの現象を確認しました。当方の環境では、Ubuntu 22.04にしたことで2/2で発生。) 検索してみると、
このようにかなり以前からこの現象は発生していたようです。いろいろ検索したところ、解決策を見つけました。
によれば、vmware-natdがDHCPのleaseを頻繁に行っており、それ自身はIPが変わらなければ問題ないが、それが仮想マシンのネットワークの頻繁な切断を引き起こしてしまうのが原因らしい。実際、ホストの/var/log/syslogにはゲストのネットワーク切断と同期して
May 21 17:43:44 exa kernel: [14661.785888] userif-3: sent link up event.
May 21 17:43:47 exa kernel: [14664.977941] userif-3: sent link down event.
May 21 17:43:47 exa kernel: [14664.977949] userif-3: sent link up event.
May 21 17:43:52 exa kernel: [14669.758177] userif-3: sent link down event.
May 21 17:43:52 exa kernel: [14669.758186] userif-3: sent link up event.
May 21 17:44:00 exa kernel: [14677.442456] userif-3: sent link down event.
May 21 17:44:00 exa kernel: [14677.442465] userif-3: sent link up event.
May 21 17:44:03 exa kernel: [14680.650489] userif-3: sent link down event.
のようなログが残っていました。そこで、前の節で入れたカーネルモジュールのvmware-host-modules/vmnet-only/userif.cに、強引ですが
*** userif.c.original   2022-05-15 22:05:24.140904301 +0900
--- userif.c    2022-05-21 17:43:37.199281561 +0900
***************
*** 1002,1007 ****
--- 1002,1010 ----
        return -EINVAL;
     }
  
+    /* never send link down events */
+    if (!linkUp) return 0;
+ 
     if (userIf->eventSender == NULL) {
        /* create event sender */
        retval = VNetHub_CreateSender(hubJack, &userIf->eventSender);
のようにlink downイベントを発生しないようにパッチを当ててモジュールを再インストールしたら、問題は解決しました。

おわりに

おそらく、VMwareがバージョンアップしたら不要になる情報かもしれませんが、自分がこれらの情報に行き着くまでに結構苦労したので、こうしてまとめておけば誰かの役に立つかもしれないと思い、こうして情報を残しておきます。

2022/05/13(金)Ubuntu 22.04のBLAS (dgemm) をベンチマーク

以前、Ubuntu 20.04のBLAS (dgemm) をベンチマークという記事を書きましたが、Ubuntu 22.04で同じことをやってみた、という記事です。

BLAS, LAPACKとは何か、個々のBLASの特徴などは、20.04のときの記事を見て下さい。前回と同様、Reference BLAS, ATLAS, OpenBLAS, BLIS, MKLの5つのパッケージをaptでインストールし、dgemmを呼び出して計算時間を計測するプログラムを使って、update-alternativesの機能でlibblas.soを切り替えながらベンチマークを取り、計算時間を比較します。前回と大雑把な傾向はほとんど変わっていないのですが、MKLのパッケージが怪しげな挙動を示した(ような気がした)ので備忘録として書いています。

各BLASのインストール方法

  • Reference BLAS
apt install libblas-dev
  • ATLAS
apt install libatlas-base-dev
  • OpenBLAS
apt install libopenblas-base
apt install libopenblas-dev
  • BLIS
apt install libblis-dev
  • MKL
apt install intel-mkl
最後のMKLですが、aptの実行中に
Use libmkl_rt.so as the default alternative to BLAS/LAPACK? [yes/no]
と聞かれます。これには「no」と答えました。「yes」と答えると、「-lblas」を付けてコンパイルしたものはlibblas.soがリンクされずにMKL(libmkl_rt.so)がリンクされてしまってupdate-alternativesでlibblas.soの実体を切り替える作戦が不可能になってしまいました。何か自分が勘違いしてるのかも知れません。

これらのライブラリは、
update-alternatives --config libblas.so-x86_64-linux-gnu
とすると
There are 5 choices for the alternative libblas.so-x86_64-linux-gnu (providing /usr/lib/x86_64-linux-gnu/libblas.so).

  Selection    Path                                                   Priority   Status
------------------------------------------------------------
  0            /usr/lib/x86_64-linux-gnu/openblas-pthread/libblas.so   100       auto mode
  1            /usr/lib/x86_64-linux-gnu/atlas/libblas.so              35        manual mode
  2            /usr/lib/x86_64-linux-gnu/blas/libblas.so               10        manual mode
* 3            /usr/lib/x86_64-linux-gnu/blis-openmp/libblas.so        80        manual mode
  4            /usr/lib/x86_64-linux-gnu/libmkl_rt.so                  1         manual mode
  5            /usr/lib/x86_64-linux-gnu/openblas-pthread/libblas.so   100       manual mode

Press <enter> to keep the current choice[*], or type selection number:
と表示され、libblas.soの実体をsymbolic linkで切り替えることができます。libblas.so.3の方も同様に
update-alternatives --config libblas.so.3-x86_64-linux-gnu
There are 5 choices for the alternative libblas.so.3-x86_64-linux-gnu (providing /usr/lib/x86_64-linux-gnu/libblas.so.3).

  Selection    Path                                                     Priority   Status
------------------------------------------------------------
  0            /usr/lib/x86_64-linux-gnu/openblas-pthread/libblas.so.3   100       auto mode
  1            /usr/lib/x86_64-linux-gnu/atlas/libblas.so.3              35        manual mode
  2            /usr/lib/x86_64-linux-gnu/blas/libblas.so.3               10        manual mode
* 3            /usr/lib/x86_64-linux-gnu/blis-openmp/libblas.so.3        80        manual mode
  4            /usr/lib/x86_64-linux-gnu/libmkl_rt.so                    1         manual mode
  5            /usr/lib/x86_64-linux-gnu/openblas-pthread/libblas.so.3   100       manual mode

Press <enter> to keep the current choice[*], or type selection number:
と切り替えることができ、前回と同様、両方を同じものに切り替えて実験を行いました。

ベンチマーク

dgemmの実行時間計測に使ったプログラムは、以下のようなものです。前回の20.04のときと同じです。
#include <stdio.h>
#include <stdlib.h>
#include <time.h>

// prototype declaration
void dgemm_(char *transA, char *transB, int *m, int *n, int *k, double *alpha, double *A, int *ldA, double *B, int *ldB, double *beta, double *C, int *ldC);

int main(int argc, char **argv)
{
	int i, j;
	int m, n, k;
	int size;
	double *a, *b, *c;
	double alpha, beta;
	int lda, ldb, ldc;
	struct timespec ts1, ts2;

	size = atoi(argv[1]);

	m = size;
	n = size;
	k = size;

	a = (double *)malloc(sizeof(double) * m * k); // m x k matrix
	b = (double *)malloc(sizeof(double) * k * n); // k x n matrix
	c = (double *)malloc(sizeof(double) * m * n); // m x n matrix

	for (i=0; i<m; i++) {
		for (j=0; j<k; j++) {
			a[i + m * j] = rand() / (1.0 + RAND_MAX);
		}
	}

	for (i=0; i<k; i++) {
		for (j=0; j<n; j++) {
			b[i + k * j] = rand() / (1.0 + RAND_MAX);
		}
	}

	for (i=0; i<m; i++) {
		for (j=0; j<n; j++) {
			c[i + m * j] = 0;
		}
	}

	alpha = 1.;
	beta = 0.;
	lda = m; 
	ldb = k; 
	ldc = m; 

	// dgemm_(TransA, TransB, M, N, K, alpha, A, LDA, B, LDB, beta, C, LDC)
	// C = alpha * A * B + beta * C
	// A=M*K, B=K*N, N=M*N
	// Trans: "N"/"T"/"C"
	// LDA = number of row of A

	clock_gettime(CLOCK_REALTIME, &ts1);
	dgemm_("N", "N", &m, &n, &k, &alpha, a, &lda, b, &ldb, &beta, c, &ldc);
	clock_gettime(CLOCK_REALTIME, &ts2);

	printf("%g\n", (ts2.tv_sec - ts1.tv_sec) + (ts2.tv_nsec - ts1.tv_nsec) / 1e9);

	free(a);
	free(b);
	free(c);

	return 0;
}
単なる比較のための、単純な三重forループによる行列積のプログラムは、以下の通り。これも前回と同じ。
#include <stdio.h>
#include <stdlib.h>
#include <time.h>

double **alloc_matrix(int n, int m)
{
	double **a;
	int i;

	a = (double **)malloc(sizeof(double *) * n);
	a[0] = (double *)malloc(sizeof(double) * n * m);
	for (i=1; i<n; i++) {
		a[i] = a[0] + i * m;
	}

	return a;
}

void free_matrix(double **a)
{
	free(a[0]);
	free(a);
}

// a: n x m, b: m x s, c: n x s
void m_m_mul(double **a, double **b, double **c, int n, int m, int s)
{
	int i, j, k;
	int i1, j1, k1;

	for (i=0; i<n; i++) {
		for (j=0; j<s; j++) {
			c[i][j] = 0.0;
		}
	}

	for (i=0; i<n; i++) {
		for (j=0; j<s; j++) {
			for (k=0; k<m; k++) {
				c[i][j] += a[i][k] * b[k][j];
			}
		}
	}
}

int main(int argc, char **argv)
{
	int i, j, n;
	double **a;
	double **b;
	double **c;

	struct timespec ts1, ts2;

	n = atoi(argv[1]);

	a = alloc_matrix(n,n);
	b = alloc_matrix(n,n);
	c = alloc_matrix(n,n);

	for (i=0; i<n; i++) {
		for (j=0; j<n; j++) {
			a[i][j] = rand()/(1.0 + RAND_MAX);
			b[i][j] = rand()/(1.0 + RAND_MAX);
		}
	}

	clock_gettime(CLOCK_REALTIME, &ts1);
	m_m_mul(a, b, c, n, n, n);
	clock_gettime(CLOCK_REALTIME, &ts2);

	printf("%g\n", (ts2.tv_sec - ts1.tv_sec) + (ts2.tv_nsec - ts1.tv_nsec) / 1e9);

	free_matrix(a);
	free_matrix(b);
	free_matrix(c);

	return 0;
}
これらは、
cc -O3 dgemm.c -lblas
cc -O3 forloop.c
のようにコンパイルします。ただし、dgemm.cの方のコンパイルをするときに、update-alternativesの選択をMKL以外にする必要がありました。MKLの状態でコンパイルすると、libblas.soがリンクされずにlibmkl_rt.soがリンクされてしまって、update-alternativesによる事後切り替えが不可能なbinaryができてしまいました。これもまた自分の勘違いかも。

さて、ベンチマークの結果は以下のようになりました。使ったCPUはcore i7 1195G7 (ノートPC) で、前回と異なるので絶対値には意味がないかも。
result.png

前回と似たような結果ですね。最速はOpenBLAS, BLIS, MKL。小サイズでMKLが妙に遅いのも同じ。

2022/04/30(土)ubuntu 22.04 インストール (リンク集)

2022/04/30(土)ubuntu 22.04 インストール (10)

その他入れた細々としたもの。
sudo apt install openssh-server
これでsshログイン出来るようになります。
sudo apt install git
sudo apt install curl
このへんはまあ必要か。
sudo apt install unar
これを使うと、日本語ファイル名を含んだzipファイルを展開したときに文字化けしないです。

後は個人的に必要なもの。
sudo apt install lv
sudo apt install checkinstall
sudo apt install ghex
Firefoxだけで過ごしたいところですが、ときどきに必要になるのでchromiumも。
sudo apt install chromium

ホームディレクトリにある「ダウンロード」等を英語表記に

ホームディレクトリに作られる「ダウンロード」などのディレクトリが日本語だと何かと不便なので、英語表記に直します。ターミナルで、
LANG=C xdg-user-dirs-gtk-update
として、「Don't ask me this again」をチェックして「Update Names」をクリックします。これでホームディレクトリが
ダウンロード  デスクトップ  ビデオ    ミュージック
テンプレート  ドキュメント  ピクチャ  公開
から
Desktop    Downloads  Pictures  Templates
Documents  Music      Public    Videos
に変わりました。元に戻すにはLANG=Cなしで単に「xdg-user-dirs-gtk-update」。

ctrl←→caps

ctrlとcapsを入れ替えるのが好きな場合は、
sudo apt install gnome-tweaks
を入れてgnome-tweaksを起動し、キーボードとマウス→追加のレイアウトオプション
→Ctrl Position→CtrlとCaps Lockを入れ替える、とします。

gnome terminalの設定

gnome terminalで「→」などの文字の幅がおかしい場合は、右クリック->設定->互換性 で「曖昧幅の文字」を「全角」にします。

また、22.04になって、gnome terminalが妙に縦に間延びして表示されるようになってしまいました。20.04の表示に近づけようと、右クリック->設定->文字 で「フォントを指定」をチェックし、フォントを「IPAゴシック 13」に設定しました。

2022/04/30(土)ubuntu 22.04 インストール (9)

何かとお世話になることが多くなった、dockerを入れます。
sudo apt install docker.io
で20.10.12が入りました。
sudo usermod -aG docker kashi
みたいにしてrootにならなくても使えるようにしました。

また、vmwareではなく実機の場合ですが、NVidiaのGPUがあればnvidia-dockerを設定するとdockerの中でGPUが見えて便利です。設定方法を書いておきます。まず、NVidiaのビデオドライバが入っていて動いている必要があります。
nvidia-smi
と叩いてGPUのstatusが出れば問題ないでしょう。もし動いていなければ、
ubuntu-drivers devices
を実行し、そこに出てきたお勧めのドライバーを、
sudo apt install nvidia-driver-510
のように入れます。

nvidia-dockerは、
distribution=$(. /etc/os-release;echo $ID$VERSION_ID)
curl -s -L https://nvidia.github.io/nvidia-docker/gpgkey | sudo apt-key add -
curl -s -L https://nvidia.github.io/nvidia-docker/$distribution/nvidia-docker.list | sudo tee /etc/apt/sources.list.d/nvidia-docker.list
sudo apt-get update
sudo apt-get install -y nvidia-docker2
sudo systemctl restart docker
のようにインストールします。
docker run --gpus all --rm nvidia/cuda:11.0-base nvidia-smi
で、dockerの中でnvidia-smiが動くことを確認しましょう。
OK キャンセル 確認 その他