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

vi大好きなのでvimを入れます。
sudo apt install vim
また、~/.vimrcを、
set encoding=utf-8
set fileencodings=iso-2022-jp,euc-jp,sjis,utf-8
filetype indent off
という内容で作成しました。これにより、
  • 日本語のファイルを認識させる。デフォルトのコードがUTF8になり、JIS、EUC、SJISコードのファイルも自動認識して編集できるようになる。
  • 18.04からvimが賢くなってファイルの拡張子に応じて自動でインデントしてくれるようになったが、自分はエディタが勝手に何かするのが嫌いなのでそれを止める。
を設定しています。

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

普段研究で作成する文書類はすべてubuntuで書いています。TeX系のソフトウェアが安定して使えるかは重要。
sudo apt install texlive-lang-cjk
sudo apt install texlive-fonts-recommended
sudo apt install texlive-fonts-extra
普段、platexでコンパイルして、dvipdfmxでpdfにして、evinceで見ています。xdvikは使わないので入れないことにしました。日本語フォントを埋め込むときは dvipdfmx -f ptex-ipa.map hogehoge.dvi としてます。

その他文書作成関連のソフトウェアをついでに入れました。
sudo apt install gv
sudo apt install nkf
sudo apt install gnuplot
sudo apt install tgif
sudo apt install gimp
sudo apt install inkscape
sudo apt install mimetex
sudo apt install latexdiff
sudo apt install diffpdf
sudo apt install pdfarranger
sudo apt install krop
sudo apt install pdftk-java
sudo apt install pinta
pdfarranger, kropm pdftk-javaはいずれもpdfの編集ツール、pintaはペイントツールです。

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

vmware toolsは、vmwareのゲストで
  • デスクトップのリサイズ、
  • ホストOSとのクリップボード共有(文字列のコピペが出来るようになる)、
  • フォルダ共有
などを実現するもので、ゲストOSへのインストールはほぼ必須です。vmware標準で提供されるものは無視してopen-vm-toolsを入れるのがお薦めです。20.04と同様、22.04でも自動的にインストールされ、デスクトップのリサイズもクリップボード共有も最初から動作していました。もしそうなっていなければ、
sudo apt install open-vm-tools-desktop
としましょう。

共有フォルダは、vmwareの「VM→Settings→Option→Shared Folders」をAlways Enabledにし、Addで適当なフォルダを共有フォルダに指定、再起動。
sudo vmhgfs-fuse -o allow_other -o auto_unmount .host:/ /mnt/hgfs
で/mnt/hgfs以下にマウント出来ました。永続的にmountするには、/etc/fstabで
.host:/ /mnt/hgfs fuse.vmhgfs-fuse allow_other,auto_unmount,defaults 0 0
と書くとよいでしょう。

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

2年に一度のubuntuのLTS (Long Time Support) である22.04LTS、インストール日記を書くのが恒例になってるので、今年も書きます。

22.04は、4月21日にリリースされました。たぶん日本時間の23時35分頃。
インストール用のisoファイルは、http://releases.ubuntu.com/22.04/からubuntu-22.04-desktop-amd64.isoをダウンロードしました。

インストールは、Linux版のVMwareで行ったので、メニューの項目が英語になってます。File→New Virtual Machine→Create a New Virtual Machine→Typical (recommended)
→I will install the operationg system later→Linux→Ubuntu 64bitの手順で仮想マシンを作成。ディスクはデフォルトの20Gじゃ少ないので512Gに増やしました (ここを多くしても実際に仮想マシン内で使用しない限りホストマシンのディスクを圧迫することはありません)。メモリはとりあえずデフォルトの4Gで (こちらは大きくするだけホストマシンのメモリを食います)。VM→Settings→CD/DVDでダウンロードしたisoをマウントし起動。
  • 言語は「日本語」を選び、「Ubuntuをインストール」をクリック。
  • キーボードレイアウトは「Japanese」「Japanese」
  • 「通常のインストール」を選ぶ。
  • 「Ubuntuのインストール中にアップデートをダウンロードする」、「グラフィックスとWi-Fiハードウェアと追加のメディアフォーマットのサードパーティ製ソフトウェアをインストールする」をチェック
  • 「ディスクを削除してUbuntuをインストールする」を選ぶ。
  • 「インストール」をクリック。
  • TimeZoneは「Tokyo」を選ぶ。
  • 「ログイン時にパスワードを要求する」をチェックしたままに。
インストールは問題なく終了しました。

とりあえず端末を出すには、右下のBCGの痕みたいなアイコンをクリックして「端末」を選びます。右クリックして「お気に入りへ追加」するといいでしょう。

日本語をかな漢字変換で入力するには、インストール直後の一回だけ、右上の「ja」をクリックして、「日本語(Mozc)」を選ぶ必要があります。

2022/01/13(木)M1 macの区間演算は遅い?

昨年3月に手に入れていたM1チップ搭載のMacBook Air、今頃開封して設定して遊んでいました。OSをMontereyにして、arm64なterminalでhomebrewをインストールしてarm64版のhomebrewを入れて、brew install gcc, brew install boostしたくらいです。とりあえずkvのプログラムは、
g++11 -O3 -I(kvのあるとこ) -I/opt/homebrew/include -L/opt/homebrew/lib hogehoge.c
とかすれば動くようになりました。

で、なぜか区間演算が異常に遅いことに気付きました。とりあえず区間演算のベンチマークとして、
#include <iostream>
#include <kv/interval.hpp>
#include <kv/rdouble.hpp>

int main()
{
        int i;
        kv::interval<double> x;

        x = 1;

        for (i=0; i<1000000000; i++) {
                x = (x*x-3)/(x+x);
        }

        std::cout << x << std::endl;
}
みたいなのを使います。加減乗除を一回ずつ含んでいて、[1,1]と[-1,-1]を交互に繰り返します。本当は変なベンチマークテストみたいにいろんな値を取る写像を使いたかったのですが、区間演算だとすぐに発散して[-∞, ∞]になってしまい、ベンチマークとしてふさわしくないものになってしまいました。

これの実行時間を、ThinkPad X1 carbon (core i7 10510U, ubuntu 20.04, gcc 9.3)で計測すると、-O3で38.1秒程度でした。この状態では、丸めの向きの変更はfesetroundを使っています。kvライブラリには、Intelの64bit CPUのとき-DKV_FASTROUNDを付けるとfesetroundを使わずにSSE2の丸めの向きを制御するmxcsrレジスタに直接書き込むことによって高速化する機能があります。このときは、19.4秒と倍近くに高速化しました。更に、-DKV_NOHWROUNDを付けるとハードウェアによる丸めの向きの変更は一切行わず、twosumとtwoproductを用いて方向付き丸めのエミュレートを行わせることができます。このときは、35.7秒程度でした。

で、これをMacBook Air (M1, Monterey 12.1, gcc 11.2) で実行してみると、-O3でなんと142秒もかかってしまいました。fesetroundが重いのかと思い、aarch64なCPUに対しても-DKV_FASTROUNDが使えるようにkvを改造し(次期kv-0.4.55で入れる予定)実行してみると、114秒といくらか改善したものの、まだまだ遅いです。で、-DKV_NOHWROUNDだと、なんと23.8秒と劇的に改善しました。方向付き丸めのエミュレーションはかなり複雑な計算をしていて、こんなに速いはずはないのですが。まとめると、次のような感じです。
-O3-O3 -DKV_FASTROUND-O3 -DKV_NOHWROUUND
X1 carbon38.119.435.7
M1 MBA14211423.8
両PCの速度の比は、3つ目の35.7vs23.8が一番体感と一致します。丸めの変更でなにか大きなブレーキがかかっているのでは、と疑わざるを得ないような結果です。

そこで、次のような実験をしてみました。変なベンチマークテストのベンチマークに毎回丸めの向きの変更を挿入してみます。fesetroundの実装に影響されないように、アセンブリ埋め込みの最速と思われる実装にします。
#include <stdio.h>
#include <stdint.h>

int main()
{
	int i;
	double x;

#ifdef __aarch64__
	uint64_t reg;
	uint64_t regs[4];

	asm volatile ("mrs %0, fpcr" : "=r" (reg));
	regs[0] = (reg & ~(3ULL << 22)) | (0ULL << 22); // nearest
	regs[1] = (reg & ~(3ULL << 22)) | (2ULL << 22); // down
	regs[2] = (reg & ~(3ULL << 22)) | (1ULL << 22); // up
	regs[3] = (reg & ~(3ULL << 22)) | (3ULL << 22); // chop
#endif

#ifdef __x86_64__
	uint32_t reg;
	uint32_t regs[4];

	asm volatile ("stmxcsr %0" : "=m" (reg));
	regs[0] = (reg & ~(3UL << 13)) | (0UL << 13); // nearest
	regs[1] = (reg & ~(3UL << 13)) | (1UL << 13); // down
	regs[2] = (reg & ~(3UL << 13)) | (2UL << 13); // up
	regs[3] = (reg & ~(3UL << 13)) | (3UL << 13); // chop
#endif


	x = 0.5;
	for (i=0; i< 1000000000; i++) {
#ifdef __aarch64__
#ifdef ROUND_CHANGE1
		asm volatile ("msr fpcr, %0" : : "r" (regs[0]));
#endif
#ifdef ROUND_CHANGE2
		asm volatile ("msr fpcr, %0" : : "r" (regs[i%4]));
#endif
#endif

#ifdef __x86_64__
#ifdef ROUND_CHANGE1
		asm volatile ("ldmxcsr %0" : : "m" (regs[0]));
#endif
#ifdef ROUND_CHANGE2
		asm volatile ("ldmxcsr %0" : : "m" (regs[i%4]));
#endif
#endif
		x = 1 / (x * (x - 1)) + 4.6;
	}
	printf("%g\n", x);
}
埋め込んだ丸め変更命令に2種類あって、
  • -DROUND_CHANGE1 丸め変更命令を埋め込むが、丸めの向きはずっとnearest
  • -DROUND_CHANGE2 丸めの向きをnearest->down->up->chopと周期的に変更
としてみました。これの実行時間は、次のようになりました。
-O3-O3 -DROUND_CHANGE1-O3 -DROUND_CHANGE2
X1 carbon6.436.446.53
M1 MBA6.296.2915.04
X1 carbonだと、ほとんど速度は変わりません。M1だと、丸め変更の命令があっても丸めの向きがずっと一定ならば影響は認められませんが、丸めの向きが毎回変更される場合に顕著な速度低下が認められます。何らかのwaitが入ってしまっている感じです。ここまで遅いと、M1チップでの精度保証の方法を考え直さないといけないかも。線形計算のように丸めの向きの変更が頻繁でないケースは問題ないでしょうけど、非線形計算のように頻繁な丸めの向きの変更が必要な場合は、エミュレーションに頼る他ないかもしれません。

なお、これはaarch64なアーキテクチャ全般に見られる傾向かどうかが気になったので、3万円のchromebook (Lenovo IdeaPad Duet Chromebook, MediaTek Helio P60T) で試してみたら、
-O3-O3 -DROUND_CHANGE1-O3 -DROUND_CHANGE2
IdeaPad Duet15.820.720.9
とまた違った傾向を示しました。誰か、富岳で試してくれないかなあ。

ARMでのベンチマーク追加 (2022/6/30追記)

でのベンチマークを追加してみました。
-O3-O3 -DROUND_CHANGE1-O3 -DROUND_CHANGE2
X1 carbon6.436.446.53
M1 MBA6.296.2915.04
IdeaPad Duet15.820.720.9
Ampere Altra6.696.699.70
Gemini PDA19.723.028.8
Ampere AltraではM1 MBAほど遅くはなっていないのが分かります。

なお、とある方から富岳のA64FXでのベンチマークを聞かせてもらったのですが、少し異常な感じの結果(とても遅い)だったので何か測定ミスの可能性もあり、ここへの掲載はとりあえず控えます。
OK キャンセル 確認 その他