憂鬱な午後のひととき

5月30日_

WalB

明日からのOpen Source Summit 2017の6/1 11:00に会社の人が発表する予定.

せっかくなので昔作ったスライドを手直しして置いた.

5月26日_

pkg-config

すぐ忘れるのでメモ. たとえばbls.pcというファイルを作る.

Name: bls
Description: test
Version: 1.0
Cflags: -I../../include
Libs: -lmcl

CflagsはCFLAGS, LibsはLDFLAGSに対応. cgoの先頭に

// #cgo pkg-config: bls

と書いておくとenv PKG_CONFIG_PATH=(bls.pcのあるパス) go ...でbls.pcを参照してくれる.

5月25日_

ebisu_optimized.cpp vol.4

『Optimized C++p』のp.68とp.69で引数がstd::stringかconst std::string&かで後者の方が遅くなった. その原因はsの出現するところで参照外しうんぬん~とあるのでそんなわけはあるまいに, とasmコードを出力させてみた. 本のコードだとstd::stringのデストラクタが発動して差異が分かりにくかったので

int remove_ctrlA(std::string s)
{
    int a = 0;
    for (size_t i = 0; i < s.size(); i++) {
        if (s[i] >= 0x20) {
            a += s[i];
        }
    }
    return a;
}
int remove_ctrlB(const std::string& s)
{
    int a = 0;
    for (size_t i = 0; i < s.size(); i++) {
        if (s[i] >= 0x20) {
            a += s[i];
        }
    }
    return a;
}

の二つのコードを見てみる. sの参照部分は同一なので著者の仮定が正しいならこの二つの関数のループ内で後者の方が不要な処理をしていることになる. Visual Studio 2010は持ってないので一番近いVS2012で試した. コンパイルオプションはcl /Oy /Ox /Ob2 /EHsc /GS- /Qpar /D_SECURE_SCL=0 /DNDEBUG /FAscの出力コードを成形したもの.

// remove_ctrlAの方
.LL4:
  cmp     rdx, 16
  jb      .LN14
  mov     rax, QWORD PTR [rbx]
  jmp     .LN15
.LN14:
   mov    rax, rbx
.LN15:
  cmp     BYTE PTR [rax+rcx], 32
  jl      .LN3
  cmp     rdx, 16
  jb      .LN22
  mov     rax, QWORD PTR [rbx]
  jmp     .LN23
.LN22:
   mov     rax, rbx
.LN23:
  movsx   eax, BYTE PTR [rax+rcx]
  add     edi, eax
.LN3:
  inc     rcx
  cmp     rcx, r8
  jb      .LL4
// remove_ctrlBの方
.LL4:
  cmp    r9, 16
  jb     .LN13
  mov    rcx, QWORD PTR [rdx]
  jmp    .LN14
.LN13:
   mov   rcx, rdx
.LN14:
  cmp    BYTE PTR [rcx+rax], 32
  jl     .LN3
  cmp    r9, 16
  jb     .LN21
  mov    rcx, QWORD PTR [rdx]
  jmp    .LN22
.LN21:
  mov    rcx, rdx
.LN22:

  movsx  ecx, BYTE PTR [rcx+rax]
  add    r8d, ecx
.LN3:
   inc   rax
   cmp   rax, r10
   jb    .LL4

レジスタの割り当ては異なるけどコード自体は同一. 多分本には載っていない呼び出し側でsを作るときに何か別の要因があったのだと思う.

それにしても思ってたより余計な処理をしてるなあ. 16と比較してるのは文字列がstd::string内部にあるかそうでないかで場合わけしてるせいのようだ(_BUF_SIZE = 16).

// msvc/.../include/xstring
    bool _Large_string_engaged() const
        {    // returns whether the large string mode (allocated memory) is engaged
        return (this->_BUF_SIZE <= _Myres);
        }


    value_type *_Myptr()
        {   // determine current pointer to buffer for mutable string
        return (_Large_string_engaged()
            ? _Unfancy(_Bx._Ptr)
            : _Bx._Buf);
        }
5月24日_

jnlマクロ

Intel icc 17でxbyakがエラーになるという指摘. 条件分岐命令のjnlがBessel関数のlong double版jnlと同名でそれがマクロで定義されていることがあるかららしい.

Special-Functionsを見ると, j0やらj1やy1とか変な名前の関数があるんだなあ. erfやlgammaとかは見たことあったけど. あ, でもBessel関数は見たことあるはずだよな. 多分そのときもなんでこんな名前つけてるのだろうと思ったはず. 忘れてるけど.

5月23日_

Vagrant for WalB

ブロックデバイスレベルのバックアップシステムWalBのサンプルのためにVagrantでいろいろ設定する.

CentOSとUbuntu両方で動作確認するのがなかなか面倒だった.

5月22日_

『プロフェッショナルSSL/TLS』読書会

今回は5章. 少しずつ進める.

5月21日_

Visual Studio with cmake

VS2017からは[ファイル]→[開く]→[フォルダ]でCMakeList.txtがあるフォルダを開くと自動的にcmakeに対応するらしい.

とりあえずmclを最低限動くようにした(CMakeLists.txt).

5月16日_

肩の痛み

少しよくなってきた気がする. 朝4時過ぎじゃなく6時ぐらいまで寝られた.

5月15日_

Goで関数の呼び出し回数を見る

coverを使えばよいらしい. テストのできるところで

go test -coverprofile=c.out -covermode=count .
go tool cover -html=c.out -o c.html

でc.htmlができるのでブラウザで開いて該当関数の上にマウスカーソルを置くとポップアップで回数が表示される. 標準でこういうのが入ってるのすごいなあ.

5月13日_

Octaveでワイヤフレームの3次元グラフ

初めて使ってみた.

x=linspace(-2,2,20);
y=linspace(-2,2,20);
[xx,yy]=meshgrid(x,y);
colormap(gray);
mesh(xx,yy,xx.^2+yy.^2);

こんな感じで隠線処理されたワイヤフレームのグラフを書けた. 線を太くする場合には

h=mesh(xx,yy,xx.^2+yy.^2);
set(h,"linewidth",2);
set(gca, "linewidth", 2, "fontsize", 20);

こんなふうにすればよいようだ. ただ画像をPDFで保存すると微妙にゴミが入ってる.

5月12日_

機械振興会館での会議

帰り東京タワーがきれいだった.

5月11日_

ebisu_optimized.cpp参加

ゆるい. 次回からいよいよC++のはなしかな.

5月10日_

リハビリ

可動域はだいぶ増えたが, 明け方の痛みはあまり変わらない. むしろリハビリの次の日は相当痛い. はやくよくならんもんかな.

5月9日_

C#でDLL呼び出し

固定長配列をclassにするかstructにするかいろいろ試行錯誤して悩んで結局structとrefですますことにした. unsafeも使わない(bn256.cs). メモリコピーのロスは問題になってから考えよう. これはGoの方が諦めが悪いというか, C#が割り切ってるというか. その違いがおもしろい.

classはそのインスタンスを隙間無く詰める方法が分からなかったので断念.

使う側がrefを明示的に書くのも面倒だったのでAddなどがちょっと変則的になってしまった.

Fr x;
x.Add(y, z); // x = y + z

これはなんか分かりにくいなと思ったGoのGMPバインディングと同じインタフェースだ.

うーむ, なんか悔しい.

C#はoperator+()があると自動的にoperator+=()を使えるのだな. C++より洗練されている.

5月7日_

Goのunsafe.Pointer

メモリイメージが同一と分かっているけど別のクラスになっているものの配列があって, いちいちコピーしていたのだけどunsafe.Pointerを使えばそれは避けられるらしい.

type A struct {
    x [2]int
}
type B struct {
    y [2]int
}
v := make([]A, 10)
w := *(*[]B)(unsafe.Pointer(&v))

A[0]とB[0]のポインタを出力してみて同一なのが確認できた(unsafe.go).

5月6日_

C#で固定長配列のポインタ

Cのstruct A { int x[4]; };の配列のポインタを受け取るCの関数void f(A *a, size_t n);をC#からアクセスしたい.

unsafeとfixedを組み合わせたら次のようにしてできた.

public const int size = 4;
public struct A {
   public unsafe fixed uint v[size];
};
[DllImport("test.dll")]
static unsafe extern void f(A* a, long n);
A[] a = new A[5];
unsafe {
   fixed (C* p = &a[0]) {
      f(p, 5);
   }
}

unsafeの中でポインタを取得するときにfixedで囲んでアドレスを渡すようだ. a[1]がきっかりsizeof(A)だけ次のポインタになっていることは確認できた.

後はこれをうまくラップすればよさそう.

5月5日_

世界を変えた手紙』(キース・デブリン著 原 啓介訳)

パスカルとフェルマーがかけの計算で手紙のやりとりをして確率の計算をしたというのは小学生のときに読んだ何かの啓蒙書で見たことがあったけど, その詳細は知らなかった. カルダノも3次方程式の解の公式を公表したぐらいしか知らなかったが, 彼のエピソードもいろいろおもしろい.

この時代の著名人は数学の範囲にとどまらず哲学や物理や政治や医者などいろいろやっててすごい.

5月4日_

pkg-config

Command cgoを見ていたら見つけた. こんなのがあったのか. 恥ずかしながら初めて知った.

5月1日_

mclのgetStr, setStr

operator<<やoperator>>などまとめてリファクタリング. テストを通すまでにめちゃくちゃ時間がかかってしまった. ちょっと無駄になんでもできるインタフェースにしてしまったせいかもしれない.

でもあれもこれもと欲しくなることがあるのでしかたないかなあ.


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