憂鬱な午後のひととき


8月30日_

ファイル名のUnicode正規化で気を付けること

Unicodeでは同じコードポイントでも異なるバイト列になっていることがある. そのため人名などの検索では事前にNFCなどによって正規化してから行うことが多い. ところがファイル名も同じ感覚でやってしまうと困ることがある.

なぜならWindowsでは, ファイルシステム上結合文字列と合成文字列を区別しているから. たとえば次のC++のコード

#include <stdio.h>
#include <string>
#include <fstream>

int main()
{
    const wchar_t tbl[][10] = {
        { 0x01d6 },
        { 0x00fc, 0x0304 },
        { 0x0075, 0x0308, 0x0304 },
        { },
    };
    for (const wchar_t *file : tbl) {
        std::wofstream f(file, std::ios::binary);
    }
}

を実行するとカレントディレクトリにǖ(U+01D6)というコードポイントのファイルが3個できる. 3個ともNFCすると同じコードポイントになるのにファイルシステムとしては別のものなのだ.

// python
import unicodedata
for x in [u'\u01d6', u'\u00fc\u0304', u'\u0075\u0308\u0304']:
    print hex(ord(unicodedata.normalize('NFC', x)[0]))
 >python t.py
 0x1d6
 0x1d6
 0x1d6

それからNFCは一部の文字を別のものに置き換えてしまう. 有名なのでは神(U+795E)と神(U+FA19)がある. こういう名前のファイルを作ることはできるがNFCすると同じものになる.

import unicodedata
for x in [u'\u795e', u'\ufa19']:
    print unicodedata.normalize('NFC', x)
 >python t.py
 神
 神

冒頭で書いたように「神」で検索して「神」がマッチしても問題になることは少ない(少なくとも取りこぼすことはない)けど, 異なるファイルを同じと思ってしまうと問題だ.

Macのファイルシステムではファイル名はNFDされたものが使われる. だからWindowsとMacで「同じファイル名」というのをどう定義するかとても難しい. そもそもそれらのファイル名文字列全体が同じ集合ではない.

というわけで対象によってどのように文字を扱うかを変えないといけないのがとても悩ましい.

8月28日_

VMwareでsuspend

しばらく前からVMwareのゲストOSをsuspendしようとすると, 「この仮想マシンへのサスペンド要求は、 対応する VMware Tools スクリプトが正常に実行されなかったため失敗しました。(略)」 というメッセーが出るようになっていた. もう一度suspendさせると正常にできるのでほっておいたが, ゲストOSで

sudo vmware-toolbox-cmd script suspend disable

とすればよかったようだ(無視してるのだからいいのかは知らない).

8月26日_

『ダーリンの頭ン中』(小栗左多里&トニー・ラズロ)

英語と違ってひらがなと発音がほぼ一対一に対応している日本語. ただ連声や鼻母音ぐらいの例外だけと思っていたけど, 結構いろいろ音は違うらしい. 「するめ」の「す」と「です」の「す」とか. へえ, そうなんだ.

>日本語には「手首から先」や「足首から先」を表す言葉がないよね
そんなことは無いと思う. まさに「手」や「足」がそこを表す言葉だよね. 足の首(上の方)だから足首なんだし.

デバッグ

結構てこずってたけど18日のバグの原因がやっと判明. ちょっと疲れた.

8月23日_

『盤上の夜』(宮内悠介)

うーん, 残念ながら期待してたのとちょっと方向が違って私にはあまりピンとこなかった. 傍点強調は, それに何か意味があるのか立ち止まって考えてしまうので多用されると読むリズムがくずれて辛い.

8月22日_

vector_execution_policy

Changes to vector_execution_policyを教えてもらった. 20日に書いたように, やっぱParallelアルゴリズムの実行ポリシーにvecのみも必要だよという提案. スケジュール的に現状のTSは用語の一部だけが反映されている感じ.

いろいろ議論はされていたようだが, マルチコアプログラミングよりSIMDの方が有利なケースなんてざらにあるだろうになんでvecが抜け落ちたのか.

8月20日_

C++ parallel TS Working Draft

ざっくりとした説明というか訳を書いた. 以前yohhoyさんが新しい並列for構文のご提案で書かれたときとまたちょっと変わってる.

指定できるポリシーがseq(シーケンシャル)とpar(並列)とpar_vec(並列+ベクトル)だけ. ベクトル化だけやってくれればいい, スレッドはこちらで制御したいケースってあると思う. 単なるvecは必要だよなあ.

8月18日_

デバッグ

なんか落ちるらしいので調査依頼がきて調べる. コードが悪いのかコンパイラが悪いのか. でかいコードなので突き詰めるの大変だなあ.

8月16日_

TSXのバグ

HSW136. Under a complex set of internal timing conditions and system events, software using the Intel TSX (Transactional Synchronization Extensions) instructions may result in unpredictable system behavior.
HSW1. TSX instruction Due to Erratum HSw136, TSX instructions are disabled and are only supported for software development. See your Intel representative for details.

今のところTSXオフにするしかないらしい. 鳴り物入りの機能だったのに大変だ.

8月15日_

プロファイル

ある処理がとても重たいのだけど何が原因だかわからない. しかし入力数を線形で増やすと処理時間がO(n2)っぽい挙動をしていることが分かった. O(n)なはずなのでどこかがおかしなことしてるのだろう.

こういうのはプロファイラなどのツールで平均化されてしまった値を見るだけではわからない. 複数の手段を用いて推測するのが大事だな.

8月14日_

hotspots

システムで何が時間を食ってるのかみたい場合, やっぱりGUIでやりたい. VTune Amplifier XEがとても便利だった. コマンドラインでも使うことができる.

amplxe-cl -collect hotspots -analyze-system <ターゲット>

とかやってできたファイルを別のマシンに持って行ってそちらでGUIでポチポチもできる.

特定のアドレスが食ってると分かったらその場所を探す. そのプロセスdaemonのmapsを見るとどのモジュールの中かある程度分かる.

cat /rpoc/<pid>/maps

アドレスとマップされてるモジュールの範囲から, 11日のようにoffsetを求めてdisasして追いかければよい.

8月13日_

daemonのcore

daemonはcoreファイルの出力権限が無かったりすると出ない. /proc/sys/kernel/core_patternで出力先を変えられるので

sudo sh -c 'echo /tmp/core.%e.%p > /proc/sys/kernel/core_pattern'

などとするとよい. ついでにアドレスがASLRによりランダムになると分かりにくいのでデバッグのときだけ /proc/sys/kernel/randomize_va_spaceを0にするとよいかも.

8月12日_

dmesgのsegfaultのerrorの意味(その2)

dmesgに出てるerrorの4はエラーの種類を示していてlinux/arch/x86/mm/fault.cに書かれている.

/*
 * Page fault error code bits:
 *
 *   bit 0 ==    0: no page found       1: protection fault
 *   bit 1 ==    0: read access         1: write access
 *   bit 2 ==    0: kernel-mode access  1: user-mode access
 *   bit 3 ==                           1: use of reserved bit detected
 *   bit 4 ==                           1: fault was an instruction fetch
 */

これらのbitのorとなっている. 4 = 0b100はbit 0が0なのでpageが割り当てられていない, bit 1が0なのでreadエラー, bit 2が1なのでuser-modeのアクセスだったことが分かる.

典型的ないくつかの例を出してみよう.

// NULL読み込み
int a = *(int*)0; // error 4 =  no page found + read access + user-mode access
// NULL書き込み
*(int*)0 = 3; // error 6 = no page found + write access + user-mode access
// read onlyなメモリへの書き込み
char *s = "abc"; s[0] = 5; // error 7 = protection faulse + write access + user-mode-access

これだけでも知ってると何かと役に立つかもしれない.

8月11日_

dmesgのsegfaultのerrorの意味(その1)

プログラムを走らせたら

a.out[32428]: segfault at 0 ip 00007f9a268917e4 sp 00007fffec8338e0 error 4 in libc-2.19.so[7f9a26823000+1bc000]

となった. さてこれから分かるのはなんだろう. まずlibcの中で落ちたことは分かる. segfault at 0なのでNULLアクセスしたらしい.

libcが7f9a26823000からmappingされているのでipとの差を求めればオフセットがでる.

print hex(0x00007f9a268917e4-0x7f9a26823000)
0x6e7e4

/lib/x86_64-linux-gnu/libc-2.19.soを逆アセンブルして0x6e7e4のあたりを見よう.

dis /lib/x86_64-linux-gnu/libc-2.19.so ; objdump -CSlw -M intelのalias
000000000006e7e0 <_IO_fclose>:
_IO_new_fclose():
/build/buildd/eglibc-2.19/libio/iofclose.c:40
   6e7e0:   41 54                   push   r12
   6e7e2:   55                      push   rbp
   6e7e3:   53                      push   rbx
/build/buildd/eglibc-2.19/libio/iofclose.c:54
   6e7e4:   8b 17                   mov    edx,DWORD PTR [rdi] ; ここ
/build/buildd/eglibc-2.19/libio/iofclose.c:40
   6e7e6:   48 89 fb                mov    rbx,rdi

fclose()の中でrdiが0で読もうとしたことが分かる. 実は元のコードは

#include <stdio.h>
int main()
{
    fclose(NULL);
}

というものだった.

8月9日_

二度寝

最近夜中に目が覚めることが多くて慢性的な寝不足なんだけど, 寝たいときに寝られなかった. 今日はあまりに疲れてぐたっと寝た. というか体が動かなかった. 久しぶりにぐっすり寝たという感じ.

8月8日_

本社創業記念祭

キッズルームというのがあった. 本社の方のお子さんが何人か預かってもらってるというので行ってみた. みんな走り回って元気だなあ.

8月7日_

vEB tree

以前, @iwiwiさんのCache-Obliviousデータ構造入門を聞いて面白かったのでvEB treeがどんなものか写経しながら勉強する. TokuDBが採用しているFractal Tree indexがそれベースと聞いていたし. だけど, Wikipediaによると初めはcache-obliviousだったけど, 今はBε木の拡張だと書かれていてなんだってー, という感じ. 今度はそちらを勉強してみるか.

8月2日_

『長い冬』(ローラ・インガルス・ワイルダー 鈴木哲子訳)

なんか実家帰ってる度についつい読み返してしまう. ついでではないけど『玻璃の天』(北村薫)も. どちらもたまたま冬の話だ. 読んでるときは暑さを忘れる. 夏の「鰍沢」だな.


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