OS X(clang) で C++ を書いている時にデバッグする方法いろいろ
プロファイラ
valgrind が(ほぼ)使えないので、gperftools を使う。
$ brew install gpreftools
でインストール可能。プロファイリングを有効にするには
$ g++ your.cpp -o your.out -lprofile
とコンパイル時にリンクするだけ。
プロファイル出力先は
$ CPUPROFILE=your.prof ./your.out
で実行時に指定する。
ここを読めばだいたい分かる。
ビジュアライズ
プロファイル出力はそのままでは読めないので、pprof コマンドで読む
$ pprof your.out your.prof
で対話的シェルが起動する。help で細かい使い方はわかるはず。
よく使うのは top とか web とかか。top は時間占有率(?)の高い関数がみえるし、
web は svg でコールグラフを描画して、ブラウザでオープンしてくれる。
しかし、もうちょっと便利に見たいので qcachegrind を使う
$ brew install qcachegrind
qcachegrind は callgrind の出力を見やすく表示してくれるツール。
callgrind 形式に gperftools の出力を変換する必要があるので
$ pprof --callgrind your.out your.prof > callgrind.prof
で変換。
$ qcachegrind callgrind.prof
で開く
関数名が16進数になってる...
既知の問題らしいので https://code.google.com/p/gperftools/issues/detail?id=562 に従って
コンパイル時のオプションを
$ g++ -Wl,-no_pie -g your.cpp -o your.out -lprofile
に変更。
これでも全部の関数は見えない。-g3 とかも試してるけれど効果無さそう。
LiveClip という chrome app を作りました
動画を見てもらうのが早いのですが、Chrome で開いている Web Site の好きな部分を、フチ無しのPopup Window で表示できるという Chrome App です。
なにが嬉しいの? という感じかもですが、
- youtube, ニコ動 など popup window 表示に対応してない動画サイトでも小さな window で表示できる
- しかも、どの window よりも最前面で表示される (dev channel のみの機能)
- 更に、拡大縮小しても動画再生が可能(操作は不能になります)
という機能があります。ようは、"小さい画面でも動画を画面端で再生しっぱなしにしたい" という欲求のために作ったソフトウェアです。
Chrome App と Chrome Extension が協調して動いているので
- LiveClip (App)
- LiveClipExtension (Extension)
の二つのインストールが必要です。
App の方を起動すると、超簡易なブラウザが起動します。ニコ動などログインが必要なサイトは、このブラウザで、ログイン処理をしておいて下さい。Chrome 本体と App では Cookie の管理が異なって居るためです。
画面が小さいPCだと、表示領域を有効につかえて便利です。
石狩DCに行ってきた
もう2週間もたってしまったけれど、先日さくらインターネットの石狩データセンターツアーに参加してきた。
倍率も高かったらしく自分としては参加させて頂いたという感じ。
さくらさんには、DCが完成する前に対談*1に呼んでもらっている上に、僕としては北海道在住も長いので、石狩DCは以前から行ってみたくて仕方がなかった。勝手に車で近くまで行ってみたりもしたけれど、当然中の見学はできないので、やっと念願叶ったという気持ちである。
参加者の感想blogは詳細なのが揃っているので、僕が関心した2点に絞ってお伝えする。
石狩DCは進化し続けていた
外気導入による冷却コストの削減とか、そもそも北海道に本州資本が大型DCをたてちゃうとか、かなり先進的な試みにみえた石狩DCであるけれど、その先進さは建てただけでは終わってないなかった。順調に2号棟の利用も開始されていて、その規模も大きくなっているし、技術的にも以前には聞かなかったものが増えていた。(アイルキャップとか600mm幅ラックの採用とか、他の人のレポートを参考にして欲しい。)
個人的には直流給電のラックが屋外の実験コンテナ*2から、正式採用になっていたのが印象的だった。*3
各サーバーに電源ユニットを置かなくて済むメリットは容易に想像できるけれど、同時に、直流で運用するとなる感電とか、火花がちるとかいろいろ問題がありそうで、よく正式導入できたなという気がする。
懇親会で鷲北研究所所長に直接伺ったところ、直流による弊害はコンテナのなかでの運用を通じて洗い出して行ったようで、ノウハウがいろいろと詰まっている雰囲気を感じた。
直流給電もまだ進化の途中で、石狩の広大な土地を利用したメガソーラー(自社運用を検討しているらしい)と直流接続するとか、超電導直流送電*4とか夢にあふれている。普段ソフトウェア開発にしか目の向かない自分としては、まさにインフラ構築の巨大なプロジェクトを見た気分であった。
2日目が楽しすぎる
2日目のオプショナルツアーは今年からだと思うのだけれど、前半は石狩湾新港地域の社会科見学という感じでとてもおもしろい。
さくらインターネットの田中社長自らバスガイドとして新港地域の案内をしてくれる。一見ただの工業団地ではあるのだけれど、巨大な風力発電所あり、LNG基地あり、大型発電所建設予定地*5、海底ケーブルの陸揚局と見どころはたくさんある(ライジングサンロックフェスティバルの会場になる空き地とか佐藤水産の工場なんかもある)。それぞれの施設がもつ逸話を田中社長がお話されるという趣きで大変楽しい。石狩DCに配電している変電所二箇所の見学などもあり、ただのプレハブとトランスが見えてるだけなんだけど、みんな盛り上がっているというおかしな企画でもあった。
石狩湾新港地域の社会科見学なんてそうあるものではないし、田中社長の語り口が非常に丁寧でとても楽しい時間が過ごせた。
バスツアーのあとは、1日目につづいて石狩DCの中に入って前目には見られなかった部分の見学をする。非常にレアな施設の見学も有り、またラックの近くまで寄って中身を見せて貰ったりする。実際にホットアイルの中にはいって暖かさを体感したり、さくらの専用サーバー*6が動いているラックをみたりする。実際に小さくて可愛いNECのE120d-Mが並んでるのをみると、これひとつ契約すればこの空間が専有できるのかー。ちょっと欲しい。という気分になれる。
かなりつめ込まれた感じの日程ではあったけれど大変楽しい2日目であった。
まとめ
参加している人々もそれぞれ面白いバックグラウンドを持っていて話していて参考になることが多いし、直接さくらの人とお話できるのでいろいろ裏話も聞ける楽しいツアーだった。まる二日間久々にテクノロジー好きに囲まれて過ごした気がする。
他の人のtwitterなどでご存知のかたも多いと思うけれど、予定のない時間は各々食い倒れツアーを開催していてそちらも、大きな見どころだろう。住んでいるので個人的には当たり前なのだが、札幌は美味しいものが沢山あるのでそれを目当てにくるのもよろしいのではないだろうか。きっと住んでみたくなる。
そういえば、北海道に長く住むといういう意味では、石狩DCに勤めるのも面白いかもしれないと思わせるツアーでもあった。現場のアイデアが活かされて進化していく職場があって、着いて行ってもいいかなと思える社長が見えるところにいるというのは良いことだと思う。
*1:http://research.sakura.ad.jp/2010/11/12/cloudexpo2010/
*2:http://wirelesswire.jp/Todays_Next/201111152054.html
*3:http://www.sakura.ad.jp/press/2013/0321_hvdc/
*4:http://www.city.ishikari.hokkaido.jp/citizen/life/teitanso05052.html
*5:http://www.hepco.co.jp/ato_env_ene/energy/fire_power/ishikari_ps.html
ruby の log は遅い
タイトルはちょっと釣りで、ruby を dis るのが目的ではない。
今書いてるコードで、log が入る計算がやたら遅いので、RubyInline で C の呼び出しにしたらだいぶ速くなった。これはちゃんと計測しなくてはということで、書いたのがこちら。
require 'benchmark' require 'inline' class Test inline do |builder| builder.include('<math.h>') builder.c <<-EOF double log_c(int i) { return log(i); } EOF end end Benchmark.bmbm do |x| t = Test.new rands = [] 10_000_000.times do rands << rand(1000) end x.report('ruby') do rands.each do |int| Math.log(int) end end x.report('inline') do rands.each do |int| t.log_c(int) end end end # Rehearsal ------------------------------------------ # ruby 9.840000 0.000000 9.840000 ( 9.842299) # inline 2.650000 0.010000 2.660000 ( 2.667835) # -------------------------------- total: 12.500000sec # user system total real # ruby 10.410000 0.010000 10.420000 ( 10.437814) # inline 2.420000 0.000000 2.420000 ( 2.422468)
ただlogの計算をするだけなのに、5倍くらい速度がちがう。
最終的な実装はどっちにしろ "math.h" の log だろうと思うのに、大変不思議。
ruby の Math モジュールのソースコードを読んでみる
static VALUE math_log(int argc, VALUE *argv) { VALUE x, base; double d0, d; rb_scan_args(argc, argv, "11", &x, &base); Need_Float(x); d0 = RFLOAT_VALUE(x); /* check for domain error */ if (d0 < 0.0) domain_error("log"); /* check for pole error */ if (d0 == 0.0) return DBL2NUM(-INFINITY); d = log(d0); if (argc == 2) { Need_Float(base); d /= log(RFLOAT_VALUE(base)); } return DBL2NUM(d); }
おお。不正な引数のために、いろいろ頑張ってる。
これのどこが 5 倍も遅くしてるのか調べたい気もするけれど、今日はここまでにしておこう。
ちなみに、RubyInline で作った log 関数に -1 や 0 を与えると、それぞれ、NaN と -Infinity が返ってくるので、わりと実用に困らない。Math モジュールも工夫の余地があるかも知れない。
最初 Gist に書いたんだけど、埋め込み用のJSがエスケープされてしまう... blog に移れということかなあ。
OSX + screen + rbenv でハマった話
osx で rbenv を使っているのだが、screen と併用すると screen から起動した shell で正しく rbenv が動かなかったので対応メモ。
設定ファイルを正しく
rbenv を利用するには ~/.zprofile, ~/.bashprofile などに
export PATH="$HOME/.rbenv/bin:$PATH" eval "$(rbenv init -)"
と書く必要がある。
各種設定ファイルが呼び出される順番は
https://github.com/sstephenson/rbenv/wiki/Unix-shell-initialization
に詳しい。
(PATHの値が変わらなければ)一度呼び出せば良い物なので、zshrc, zshenv などに書く必要はない。
screen
screen から shell を起動した時は、設定ファイルのうち
- ~/.zshenv
- ~/.zshrc
は呼び出すが、~/.zprofile は呼び出さない。
http://masutaka.net/chalow/2012-11-19-1.html
に詳しい。呼び出すようにもできる。(login-mode で shell を起動できる)
zprofile は呼び出さないのだが、環境変数 PATH は screen から開いた shell に引き継がれる。
なので、改めて zshenv/zshrc で rbenv のための PATH が設定されなくてもきちんと動く。
/etc/paths の罠
というわけで、~/.zprofile に設定を書けば上手く動くはずなのに、screen から起動した shell では環境変数 PATH の順序がおかしい。これでしばらくハマったのだが、実は /etc/zshenv に
# system-wide environment settings for zsh(1) if [ -x /usr/libexec/path_helper ]; then eval `/usr/libexec/path_helper -s` fi
と書いてあって、これが PATH の順序をおかしくしていた。path_helper は /etc/paths に書いてある値をPATHの先頭にもってくる。
/etc/paths とか /etc/zshenv を書き換えても良いのだけれど、/etc 以下をあんまりいじりたくないので、brew で zsh をインストールし直す。
$ brew unlink zsh $ brew install --disable-etcdir zsh
これで /etc 以下の設定ファイルを無効にできる。
教訓
- shell の設定ファイルはよく理解して使いましょう...
株式会社はてなを退職しました
先週末の5/24日付で、株式会社はてなを退職しました。2008年のインターンに申し込んだのが、ちょうど5年前の今頃の季節で、以来、インターン採用、修士修了、新卒入社、結婚、第一子誕生と、人生のなかでも大きなイベントの多くをはてなと過ごして来ました。
仕事の上では、
などなど、書きだすときりが無いくらい多様な仕事に関わること出来ました。どの仕事も、沢山のユーザーさんからのフィードバックがある楽しい仕事でした。
若干いろいろな事に手を出しすぎて自分の専門分野を絞る事ができなかったとも言えますが、次の職ではその辺をどうにかしたいと思っています。CTOに、"深く技術を学ぶなら2,3年潜らないとねえ" みたいな事を言われた事もあって、それぐらいちょっと深く潜って勉強して見るつもりです。
- 頼れる優秀な同僚
- 京都ならではの広い机と、最新の開発環境
- ベンチャーとは思えないホワイトな労働時間
- 毎日出る社食と、無限のお菓子・飲み物
と、エンジニアの仕事環境としてはあまりないものだと思います。
一方で、"Web進化論"で書かれていたような、あるいは 2003 - 2005 年ごろの伝説的なへんな会社は、だいぶ普通の会社になっていて、あのビッグウェーブに乗れなかったのは少し残念でもあります。それは、上に書いた良い労働環境とは相反するものですし、入社の時点で以前と違うことは了解できていたので、無い物ねだりとしか言えないものです。
同僚にも本当に恵まれることが出来ました。スタープレーヤーが居なくなった後のはてなにも優秀な人が沢山いて、切磋琢磨という言葉が実にふさわしい環境でした。そしてなにより、よい友人を得ることが出来ました。アルバイトやインターンだった人々も含めてはてなで関わった方々は実に魅力的で、風変わりで、そして優秀でした。これからも、どうぞよろしくお願い致します。
そんな、すばらしい環境で、楽しい同僚達と、もっと長く一緒に仕事をするのも悪い選択肢では無かったと思います。しかし、以前から挑戦したかった事をやるべきタイミングが来たので、ここでお別れすることにしました。
とても楽しい4年間でした。昔から大好きだと思っていた会社で最初のキャリアを始めることが出来たことを光栄に思います。
同僚のみなさん、ほんとうにありがとうございました。
Automator のデバッグ
前回の記事で躓いたひとも多そうなので、補遺。
ショートカットキーから実行しない
文字列を選択して、コンテキストメニューを出すことでも サービス は呼び出せる
文字列を選択して、メニューバーからサービスを呼び出すことも出来る
サービスはタイミングや、呼び出してるソフトウェアとの相性によって起動できたり出来ないことがある。なので、起動できないタイミングでショートカットキーを押しても何も起こらない。
最初は、コンテキストメニューなどから呼び出して実際呼び出せるタイミングなのか知っておくとよい。