PHP
しばらくPHPのお勉強. 入門のページを見てhello worldなどをしつつ. シェルとCが混ざったような感じの言語なんだな.
PHP
しばらくPHPのお勉強. 入門のページを見てhello worldなどをしつつ. シェルとCが混ざったような感じの言語なんだな.
肩がえらく凝ってしんどい.
最近ずっと気を付けていたのだけどな. 在宅勤務にしようと思ったら, 週末会社のビルの電気設備点検で停電のため自分のマシンの電源を落としていたのだった.
有給にしてTeXのページ設定をいろいろ調べる. 夕方, 会社の人にマシンの電源を入れてもらえばよかったと思いつく.
『正規表現技術入門』(新屋良磨, 鈴木勇介, 高田謙)
まるまる正規表現とオートマトンの本. 新屋さんにいただいた. ありがとうございます. 8章までざっと読んだ(Appendixはこれから). 最初は簡単なルールの紹介から, 拡張機能の説明と各種処理系での違いの列挙. NFAベースのものをVM型と呼んでいるのが一瞬戸惑ったけど理由が書かれている. 正規表現の歴史はよく調べたなあと感心する.
4章ではオートマトンやNFAからDFAを構成する方法の解説. それだけで独立して動作確認できる簡潔なPythonのコードなど参考になると思う. DFAの状態数爆発問題に対処するためのOn-the-Fly構成法などは, サイボウズ・ラボユースで新屋さんがJITコンパイル中に対応するためがんばってたなあと思い出す.
鬼雲の実装紹介は実際に作ると細かいところでいろいろ大変だというのが伝わってくる.
第7章の「正規表現の落とし穴」は正規表現をよく使う人は目を通したらよいと思う. ちょうど会社でもいくつか正規表現で想定していないパフォーマンス劣化問題があったところ.
『私たちは今でも進化しているのか?』(マーリーン・ズック 渡会圭子訳)
進化というのはとても長い期間をかけてゆっくり進化するものというイメージだったけど, それは違うという. 著者は, 鳴いていると寄生ハエにやられてしまうので5年で鳴かない体に変化した例を発見した. その辺りが一番面白い. 他にもいろいろ急激に進化している例を紹介している.
アメリカで流行ってるらしいパレオ主義(原始人の生活に戻ろう)を間違っていると批判する. それがこの本の主張の一つなのでしかたないけど, パレオ主義自体を知らないのでくどく感じる.
関数呼び出しのコスト
最近は関数呼び出しのコストは低いよね?という問いがあったので実測してみた[rel-jmp.cpp]. 擬似的なコードはこんな感じ.
calc: mul eax add eax, 12345 ret funcAddr: dq calc .lp: switch (mode) { case 0: mul eax add eax, 12345 break; case 1: call(calc); break; case 2: call([rip + funcAddr]); break; case 3: call(r8); break; // r8 = calc case 4: call([r8]); break; // r8 = funcAddr } sub(ecx, 1); jnz(.lp);
case 0はループの中で直接計算する. case 1はcalc関数を呼び出す. case 2はrip相対で関数アドレスを読んでcall. case 3はレジスタにcalcのアドレスを入れてcall. case 4はレジスタのアドレスにあるcalcアドレスを読んでcall.
inline | call rel32 | call [rip] | call reg | call [reg] | |
---|---|---|---|---|---|
clk | 5.35 | 5.15 | 5.52 | 5.03 | 5.02 |
Haswellや第4世代ではどれも殆ど差は無いのだけど0.3clk程度inlineよりcall regの方が速かった. ループ先頭のalignmentはしていない. してもあまり結果に差は無かった. callしたほうが速いと同じ現象が起きてるのかな.
もともと本来の趣旨はジャンプ先が常に同じならそれにかかる処理コストは隠蔽されるだろうという予想で, それは概ね当たっていたのだが, なかなか予想外の結果だった.
『不思議宇宙のトムキンス』(ジョージ・ガモフ ラッセル・スタナード 青木薫訳)
自転車に乗ってる人が横につぶれるシーン. 昔からあるのは知ってはいたがオリジナルのは初めて読んだ.
この本は記述が古くなった部分をスタナードさんが書き直したもの. 教授の娘モードの記述が気に入らなくてかなり変わったらしいが, 筋にそれほど絡んでるわけでもないので微妙. 中盤以降は話が行ったり来たり, 飛んだりでいまいちだった.
ニュートリノの説明する部分はまあまあよかったが, いきなりSU(3)を説明しだしたりちぐはぐ感もある.
unique_ptr, shared_ptr, weak_ptr周りの話. 次回は5/20.
TeXの索引のスタイルファイル
makeidx.sty: LaTeXパッケージにあるように, そこで取得できるdot.istを使って
mendex -c -g -S -s dot.ist ango.idx
のようにすると項目とページの間に点線を入れてくれる.
筋肉痛
久しぶりのサイクリングと山登りで筋肉痛になるかと思ったが, 意外と大丈夫だった. まああちこちミシミシいってる気はするけどそれほどでもない.
山登り
会社で合同お食事会というのがあって, 普段本社の方とそれほど関わり合いがあるわけではないのでよい機会と参加してみる. 行き先は名前は知ってるけど行ったことのない軽井沢. そこで一泊.
初めての方ともいろいろおしゃべりできてよかった. 自由時間に「今から小浅間山に登りますが, どうですか」と言われてせっかくなのでご一緒させてもらう. 東京にきてからは殆どハイキングとかしてないし.
まず二人で旅館の自転車を借りて標高1000mぐらいから出発. 蜂の茶屋(1400m)までひたすら上り坂. これが結構きつい. 15分おきぐらいに水分をとりながら黙々と1時間ちょい.
そこから歩いて登る. ところどころ残雪. 40cmぐらいありそうなところも. 誘ってくれた方はステッキにアイゼンと準備がいい. 私はランニングシューズでなんとかついていく. 山頂付近(1655m)はかなり急勾配で四つんばいになって登る. 昨日は雨も降っていたが今日は快晴ですばらしい眺めだった.
TeXのurlコマンド
長いURLを\urlコマンドに与えると折り返してくれなくて困って検索したら,
\usepackage[hyphens]{url}
とすればよいらしい. ハイフンのところで折り返してくれるようになるとのこと. ところが手元の環境でやるとエラーになった. なんだかよく分からないので最新環境にしてみるかとアップデートしたら何もコンパイルできなくなってしまった. TeXインストーラ 3を使ってるのだけど, どうもtexフォルダはできるのだがその下が空っぽ. 今までそんなことになったことはないのだが. 一度全部消してやり直したりしたのだけどどうもうまくいかない.
無駄に時間を使い, 結局諦めて前のバージョンに戻した.
で, urlはhyperrefよりも先にusepackageすればよいことが判明した.
// ok \usepackage[dvipdfmx]{hyperref} \usepackage{url} // error \usepackage[dvipdfmx]{hyperref} \usepackage[hyphens]{url} // ok \usepackage[hyphens]{url} \usepackage[dvipdfmx]{hyperref}
素人には近づきがたい.
mallocされた領域のサイズを取得する
標準関数にはないがgccならmalloc_usable_size, VCなら_msizeを使う. ただNULLを渡したときmalloc_usable_sizeは0を返すが_msizeはエラーになる. 先にポインタがNULLか否かを確認する必要がある.
ところでmalloc_usable_sizeは要求された値よりも大きい値を返すことがある. これはサイズを適当に丸めて処理しているから. 行儀はよくないがmanにはそのサイズまではアクセスしてもよいと書かれている.
#include <stdio.h> #include <malloc.h> int main() { for (int i = 23; i < 26; i++) { char *p = (char*)malloc(i); size_t s = malloc_usable_size(p); printf("malloc size=%d usable_size=%zd\n", i, s); p[s - 1] = '0'; free(p); } }
malloc size=23 usable_size=24 malloc size=24 usable_size=24 malloc size=25 usable_size=40
この環境ではsize=23, 25のときは24, 40byteまでアクセスしてよいようだ.
ただaddress sanitizerでmalloc_usable_size()の値までアクセスするとエラーになることがあったようだ. valgrindは3.5から大丈夫になっている[malloc_usable_size doesn't return a usable size]. address sanitizerも少し前から大丈夫になったようだ. 上記コードをvalgrind上で実行すると結果が変わる.
malloc size=23 usable_size=23 malloc size=24 usable_size=24 malloc size=25 usable_size=25
よく考えられている.
VCでメモリリークを探す
古典的なネタだけど久しぶりに必要になったのでまとめておく.
//#define _CRTDBG_MAP_ALLOC //#include <crtdbg.h> #include <stdio.h> void fff(); int main() { // この3行を追加する _CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF); _CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_FILE); _CrtSetReportFile(_CRT_WARN, _CRTDBG_FILE_STDERR); malloc(123); fff(); new int[4]; }
_CrtSetReportFileでファイルハンドルを指定することもできる. そして全てのファイルの先頭で#define _CRTDBG_MAP_ALLOCしてからcrtdbg.hをインクルードする. /Dマクロと/FIファイル名オプションを指定すればよい.
cl /MDd /D_CRTDBG_MAP_ALLOC /FIcrtdbg.h
デバッグライブラリを使うように/MDdか/MTdを指定する. こうするとリークしてるmallocの行番号がでるようになる.
Detected memory leaks! Dumping objects -> {89} normal block at 0x0000000000493E00, 16 bytes long. Data: < > CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD {88} normal block at 0x0000000000493DB0, 5 bytes long. Data: < > CD CD CD CD CD s.cpp(5) : {87} normal block at 0x000000000049A770, 12345 bytes long. Data: < > CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD t.cpp(13) : {86} normal block at 0x00000000004970F0, 123 bytes long. Data: < > CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD Object dump complete.
ただよく見ると分かるようにnewのリークは検知しているが行番号はでない. これに対応するにはnewに__FILE__と__LINE__を渡す必要がある.
/D"new=::new(_NORMAL_BLOCK, __FILE__, __LINE__)"
オプションを追加する. そうすると
Detected memory leaks! Dumping objects -> t.cpp(23) : {89} normal block at 0x00000000004C3E00, 16 bytes long. Data: < > CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD
ファイル名と行番号が出るようになった. ただしnewをマクロで置き換えてしまうので独自newや配置newはエラーになってしまう. そのファイルではnewを定義しないか, 必要なnewをNewなどに置き換えてNewを定義する(こちらのほうが安全か). このあたりはvalgrindやaddress sanitizerに比べてかなり不便.
一応VC独自のpush_macro, pop_macroを使って必要な箇所を囲む方法もある.
#pragma push_macro("new") #undef new namespace s { void *operator new(size_t) { return 0; } // ここでだけnewを元に戻す } #pragma pop_macro("new")
ちなみにcrtdbg.hを眺めてると一瞬_CRTDBG_MAP_ALLOC_NEWを定義すれば__FILE__, __LINE__つきのnewを使うように見える. しかし, それはcrtdbg.hで定義されたnewのファイル名と行番号が出るだけで何も意味がない. うっかり勘違いして作ってしまった名残なんだろうか.
These inlines do not add any information, due that __FILE__ is expanded to "crtdbg.h", which is not very helpful to the user.