憂鬱な午後のひととき

9月30日_

The Art of HPC for CS輪読会

久しぶりに参加.

JRに乗るとなんか疲れる. メトロの回数券買おうとしたらいくらメニューを探しても見つからなくて, 呼び出し押したとたん, 「回数券は買えません」という文字が目に入る.

9月22日_

mulVec

楕円曲線やGTのマルチスカラー演算をようやく実装. 微妙な場合わけが多くて手間取った. リファクタリングしなきゃ.

9月21日_

Road to Devcon 4.0 ~ Security & Privacy

タイトルはDevcon 5じゃないのかな. 集約署名の話をした. 懇親会はいろいろな人が声を掛けてくれたので珍しくしゃべった.

9月14日_

xbyak v5.81

loop命令とかいろいろ古くて遅い命令サポートしてほしいというissueがあったので細々と対応する. 無くてもいいと思うんだけどな.

9月13日_

MediaPad M5 Pro 10.8

小さい画面は嫌なので大きめを探すとなかなか無い. WebAssemblyのベンチマークを取ってみたけど1年前のiPhone XRの1/6ぐらいの速度なんだな. ちょっと残念.

9月11日_

歯医者

最近冷たいものを飲むと歯がしみるので歯医者へ. なんともなってないので知覚過敏かなとのこと. 歯磨きをゆっくり丁寧にしよう. 無意識にかみしめないようにもしないと.

9月6日_

2019年 暗号と情報セキュリティワークショップ

いろいろ勉強になりました. 終わってからISEC委員会参加して帰宅. 疲れた.

9月3日_

macOSでmimallocを使う

ラボユースの人に, 開発してるellipticCurve/test.cppがMacよりも, そのMac上のvirtualマシン上のUbuntu上で動かす方が速いんですが何故でしょうと聞かれた.

私も試してみたら再現した(MacBook Pro 13インチ2018 2.3GHz Core i5, VirtualBoxではなくdockerを利用).

Apple LLVM version 10.0.1 (clang-1001.0.46.4)
on mac(素のMac)
>g++ -O3 -DNDEBUG test.cpp -lgmpxx -lgmp && ./a.out
[*] order test: OK
[*] Fp isEq test1: OK
[*] Fp isEq test2: OK
[*] Fp benchmark
        time = 0.288760usec
[*] EC benchmark
        time = 5.346814usec

Ubuntu 18.04 on docker(19.03.1) on mac(Mac上のUbuntu)
gcc version 7.4.0 (Ubuntu 7.4.0-1ubuntu1~18.04.1)
>g++ -O3 -DNDEUBG test.cpp -lgmpxx -lgmp && ./a.out
[*] order test: OK
[*] Fp isEq test1: OK
[*] Fp isEq test2: OK
[*] Fp benchmark
        time = 0.155400usec
[*] EC benchmark
        time = 2.898436usec

上記プログラムはGMPを使ってるのだけれども, 計算主体のプログラムで2倍速度が違うというのは尋常ではない. GMPのバージョンは同じ. mpz_classを多用しているのでどうもMacのreallocが遅いようだ(instrumentsで調べたら一番食ってた). それでMicrosoftのmimallocを試したらどうだろうと思ったけどダイナミックリンクを使う方法はMac上でうまく動かなかった(cf dynamic overriding on macOS seems broken). 仕方がないのでプログラム上で直接mimallocを使うように修正する.

GMPはmp_set_memory_functionsを使うとメモリ関数を入れ換えられる. とりあえずやっつけでこんなコードを追加した. dynamicリンクは嫌なのでlibmimalloc.aを直接リンクする.

#ifdef USE_MIMALLOC
/*
    g++ -O3 -DNDEBUG -I <mimalloc>/include <mimalloc>/build/libmimalloc.a -lpthread -lgmpxx -lgmp
*/
#include <gmp.h>
#include <mimalloc.h>
static struct UseMiMalloc {
    static void* mi_realloc_wrapper(void *p, size_t, size_t n)
    {
        return mi_realloc(p, n);
    }
    static void mi_free_wrapper(void *p, size_t)
    {
        mi_free(p);
    }
    UseMiMalloc()
    {
        puts("set GMP memory functions before using mpz_class");
        mp_set_memory_functions(mi_malloc, mi_realloc_wrapper, mi_free_wrapper);
    }
} g_UseMiMalloc;
#endif

GMPが要求するreallocとfreeの引数が異なるのでwrapper関数を渡す. staticなmpz_classが作られる前に先に実行しておかないといけない. そうするとMac上でも速くなった.

malloc比較
Mac標準 Ubuntu on Mac Mac標準 + mimalloc Ubuntu on Mac + mimalloc
Fp 0.289 0.155 0.126 0.152
Ec 5.347 2.898 2.291 3.014

Ubuntu on Macのmimallocは気持ち遅くなってるようだ. 別のUbuntuマシン(not Mac Core i7-7700)で試したらmimallocの方が速かった(多分こちらのほうが正常な挙動なのだろう). Linuxでは-lpthreadのリンクも必要だった.

malloc比較2
Ubuntu Ubuntu + mimalloc
Fp 0.088 0.067
Ec 2.068 1.881

今回, malloc単体の速度は調べてないのだけれどもMac標準のmallocは遅すぎる印象(ちゃんと調べるべき). tcmallocだとどうだろう. MacとLinuxを使っていて同じプログラムなのになんか遅いなと思ったらmallocを調べるとよいかもしれない.


御意見は光成滋生<herumi@nifty.com>までお願いします