憂鬱な午後のひととき
v4fmaddps
AVX512_4FMAPS命令群の一つ. とても変わっていて5個のzmmレジスタと16byteのメモリを使って積和演算をするようだ.
v4fmaddps zmm5, zmm0, [mem]
とすると
zmm5[i] += zmm0[i] * mem[0] + zmm1[i] * mem[1] + zmm2[i] * mem[2] + zmm3[i] * mem[3]
となる(float演算. i = 0, 1, ..., 15). 二つ目のレジスタでzmm0を指定するとzmm1, zmm2, zmm3を入力に使う.
添え字は31を越えたらラップアラウンドする.
マニュアルには"zmm2+3"という表記で最初何かと思った. intrinsicとしては__m512x4という型が増えているようだ.
f4fnmaddpsは足し算ではなく引き算用.
Re: AVX512_4VNNIW
binutilsの最新版で対応していたのでそれを見ながら動作確認.
多分ちゃんと動いてる(cf. Enable Intel AVX512_4VNNIW instructions).
pull reqをくれた人はIntelの非公開バージョンのXEDで試したらしい.
マニュアルにOp/EnがT1_4Xのときは16byte読むとあるのでoffsetを16で割るというのでよいようだ.
AVX512_4VNNIW
XbyakにAVX512_4VNNIWとAVX512_4FMAPSに対応するためのpull reqが来た.
取り入れたいところだがcompressed displacementの挙動がどうなのかよくわからなくて生成コードが正しいのか判断できない.
nasmやIntel sdeも対応してなかったのでどうしよう.
体調不良
今回の風邪は酷かった. 全然治らなくて気持ち悪くて10日経ってもまだ不調.
暗号通貨読書回#4
Equihashの話. 一般化誕生日問題やWagnerの問題は年明けぐらいに別の人の話で聞いた.
hash関数に望まれる性質が変わっていって面白い.
第17回数学カフェ
数論回. 面白かったのだけど会場係のため38度の熱でも休むわけにはいかず辛かった.
「高さ入門」の講義で川口周さんのお名前がでてきてびっくり.
Re3:getelemenptr for i192*
レジスタサイズを越える整数型ポインタの読み書きを全て避けるようにしたら無事aarch64でも動くようになった.
よかった. HiKeyでペアリングが6.2msec. teplaだと16.2msec.
鼻水が酷くてしんどい. 帰りの電車で悪寒や吐き気がものすごくなって途中下車した.
何年か振りにひどい状態.
『マイナス・ゼロ』(広瀬正)
名前は聞いたことがあったけど初めて読んだ.
めちゃくちゃ面白かった.
中盤, やけにあっさり別れてしまったり, 戻れなくなったりしたけど最後見事に収斂した.
すごいな.
Re3:getelemenptr for i192*
ようやく原因が分かった.
llcとopt + llcとで出力コードが異なる現象だった(これは予想外. optが影響を与えるとは思わなかった).
define void @store0_to_p3(i192* %p)
{
%p1 = bitcast i192* %p to i64*
%p2 = getelementptr i64, i64* %p1, i64 3
store i64 0, i64* %p2
ret void
}
// llcだけの場合
% llc-3.8 -O3 a.ll -o - -march=aarch64
store0_to_p3:
str xzr, [x0, #24]
ret
// optしてからllcの場合
% opt-3.8 -O3 a.ll -o - | llc-3.8 -O3 -o - -march=aarch64
store0_to_p3:
str xzr, [x0, #32]
ret
ちなみにoptの出力結果は
% opt-3.7 -O3 -o - -S a.ll
define void @store0_to_p3(i192* nocapture %p) #0 {
%p21 = getelementptr i192, i192* %p, i64 1
%p2 = bitcast i192* %p21 to i64*
store i64 0, i64* %p2, align 4
ret void
}
attributes #0 = { nounwind }
せっかくi192*をi64*にcastしてi64* 3個分にしているのにi192*に合成されてしまった.
optの範囲ではsizeof(i192) = 192bitだからだろう.
するとllcのときにaarch64では+32することになってしまう.
LLVM-devではdatalayoutを正しく設定すればよいと返事があり, とりあえずたとえば
target datalayout="e-m:o-i64:64-i128:128-n32:64-S128:i192:192"
のようにすればaarch64でも期待通りになることは確認した.
けど, 各CPUごとに用意するのもどうかと思うしi192*は使わない方向で進めよう.
タッチペン用ソフト
MetaMoji Note LiteとBamboo Paperを試してみる.
似たようなソフトなのに書き心地が違う.
まだ慣れてないので細かい字を書くのは難しいけど面白い.
Re2:getelemenptr for i192*
時間をあまりかけていないけどまだ動かない.
i192*のload, storeも128bitアライメントされてないといけないのかと, それも修正したのに答えがずれる.
同じLLVM コードをライブラリにして読んだときと, 直接コンパイラに渡して動かしたときとで違う.
なんのミスをしてるのだろう.
NHK凄ワザ 最速自転車プロジェクト
恐ろしくつまらなかった.
想定外のアクシデントが続出というが, 大会前に一度でも試乗していれば気がつきそうなものばかり.
というか本当にぶっつけ本番だったのだろうか. 大会を舐めてるとしか思えなかった.
あと, 他のチームの描写がほとんどない. 140km/hを出したトップの車体や走りぐらいは出すだろうと思ったのにそれすら無かった.
「日本すごい」っぷりしか描かれず気持ち悪い.
先日見たABUロボコン2016もマレーシアvsインドネシア(だったかな)の準決勝がカットされていた.
こちらも同様の感想.
Re: getelemenptr for i192*
getelementptrを使うときはi64*にcastしてから計算させるようにした.
これで動くと思ったがまだ駄目だ.
今度はなんだろう. ああもしかしてload i192*も128bitアライメントされていることを前提としたコードになるのか?
するとそこもそれを仮定しないコードに修正するのか.
でも, そうするとアライメントされてるときにちょっと無駄なコード生成になってしまいそう.
ARM64のときだけ特別な処理をするのか? どうしよう.
getelemenptr for i192*
getelementptrの挙動を確認する.
define i192* @fff(i192* %p)
{
%p1 = getelementptr i192, i192* %p, i32 1
ret i192* %p1
}
が他のいくつかの64bit CPUではp + 24を返すがARM64環境だけp + 32になる.
llc-3.8 c.ll -O3 -o - -march=x86-64
fff:
leaq 24(%rdi), %rax
retq
llc-3.8 c.ll -O3 -o - -march=ppc64
fff:
addi 3, 3, 24
blr
llc-3.8 c.ll -O3 -o - -march=mips64
fff:
jr $ra
daddiu $2, $4, 24
llc-3.8 c.ll -O3 -o - -march=aarch64
fff:
add x0, x0, #32
ret
mclのaarch64対応
Makefileと定義済みマクロによるCPU特定部分を修正したらあっさり動いた.
LLVMを使ったARM64コードもちゃんと動く. すばらしい.
pairing[msec] / gcc 4.9.2 + llvm 3.7 on HiKey
GMP | GMP/Montgomery | LLVM | LLVM/Montgomery |
13.8 | 10.7 | 11.3 | 6.3 |
同じ環境でteplaが16msecだったのでよい感じ.
ただ192bit楕円計算の単体テストが落ちる. i192*ポインタを1増やすと256bit増えるせいのようだ.
なぜだろう.
そういう仕様っぽい. ARM Cortex-A Series Programmer’s Guide for ARMv8-Aに128 bitsにアライメントせよとある.
LLVMコード生成の部分を修正しないといけないな.
しつこくKaratsuba
Montogomery乗算のやつ, sqr用のも作って測定してみた.
mont vs mul/sqr + red on Skylake
bit | 256 | 384 | 640 | 768 |
mont | 78 | 141 | 500 | 716 |
mul | 33 | 68 | 192 | 258 |
sqr | 33 | 72 | 160 | 227 |
red | 64 | 111 | 338 | 464 |
768bitのときでようやくsqr + redがmontより速い.
あと(ここには出てないけど)やはりLLVMはレジスタ溢れしたときがが辛い. 極端に遅くなる.
RSAなら意味はありそうだけど楕円/ペアリングではこの方針はうまくいかなそうだな.
昔
御意見は光成滋生<herumi@nifty.com>までお願いします