|
|
||
日記内の"morihyphen.hp.infoseek.co.jp"へのリンクは切れてます。必要な場合はお手数ですが int.main.jp へ書き換えをお願いします。
TODO: ファイル名確認を忘れないこと > 自分
「おでん」って何だっけ?おでんっぽい具をおでんっぽい汁に入れたらおでんとしか言いようがない気がしたが、
http://ja.wikipedia.org/wiki/%E3%81%8A%E3%81%A7%E3%82%93
を見ると明確な区別はなくて、「おでんっぽい具をおでんっぽい汁に入れたらおでん」でだいたいあってるように見えるな。
と、いう文をtwitterに書きかけた。一時期は「twitterに書くなんて脳の退化だから書くべきではない」とか言ってたが、結構気が付くと書いてるな…
twitterに書くようになるまでに至る経緯としては、
という感じかな…
もうちょっと頑張ろう…
なりません。
我々はブログエントリに恥ずかしいタイトルを付けるべきだろうか?
最近、人気webページのタイトルが、なんというか、「〜が何々すぎる、なんとかかんとか」という感じがあって、まあ、ぶっちゃけていうと、ウザい印象があったのだが、
http://b.hatena.ne.jp/articles/201112/7097
を読んで、印象ではない気がしたので、エントリのタイトルの長さをカウントしてみたところ、
2005年ランキング http://ebi.dyndns.biz/hateburanking/2005/ 1位: 19文字 2位: 27文字 3位: 6文字 4位: 9文字 5位: 32文字 平均: 18.6 2007年ランキング http://ebi.dyndns.biz/hateburanking/2007/ 1位: 40文字 2位: 27文字 3位: 15文字 4位: 8文字 5位: 40文字 平均 : 26.0文字 2009年ランキング http://ebi.dyndns.biz/hateburanking/2009/ 1位: 23文字 2位: 20文字 3位: 19文字 4位: 15文字 5位: 19文字 平均: 19.2 2010年ランキング http://ebi.dyndns.biz/hateburanking/2010/ 1位: 46文字 2位: 35文字 3位: 39文字 4位: 74文字 5位: 25文字 平均: 43.8 2011年ランキング http://ebi.dyndns.biz/hateburanking/2011/ 1位: 66文字 2位: 35文字 3位: 46文字 4位: 54文字 5位: 52文字 平均: 50.6
ここ2年で確実にタイトル長くなってるので、そういう傾向があるのは気のせいではないと思う。
(あと、2005年は、アップルとかWikipediaとか入っててなんか時代を感じる)
何故タイトル長くなるのか、は、
あたりかと思う。しかし、長くなる理由は、なんとなくわかるが、昔は、何故それをやっていなかったのか?とか、考えると、こういうタイトルの付けかたを普及させた人達は、ある種のパイオニアと呼ぶべきか。
それはいいとして、このとき、そういう長くて感情に訴えかけるタイトルについて「なんかイラっとする」という印象を持ってしまうのだが、これって何なのだろうな?
文章を書くときに、「わかりやすいタイトルを付けよう」というのは、重要なテクニックなのだから、ここ数年で、世間のライティングレベルが向上した、と、考えるべき場面、のはずなのだが、直感では、逆で「ネット住民はバカになっていってるのではないか?」という印象を持ちそうになる。(実際はどうか知らない)
実用上も、タイトル読むだけで、
わかってるほうがいいので、「Hogeを作るときの心構え」みたいなのよりも、「画期的にわかりやすいHogeを短時間で作る方法」の、ほうが、確実によいと思うのだが。
まあ、いくらか、思い当たる点が無いでもない。
が、どちらも常識にとらわれてる感があるので、そういう感情を抑えこんで、読む側および、アフィを貼る側双方のメリットを考えて、恥ずかしいタイトルを付けるという選択肢を考えてもよいかもしれない。
でも、自分が読む側に立ったときを考えると「タイトル地味でこんな内容かよ!」とかは、やっぱり面白さのスパイスとして欲しいところであるし、自分の技術的に、「大げさなタイトル付けなくても、ちゃんと最後まで読んでもらえる文を書くテクニックが欲しい」みたいなのがあって、あと上ふたつの常識とかがあって、なかなか難しいところである。
さて、我々は、ブログエントリに恥ずかしいタイトルを付けるべきだろうか?
まあ、その前に僕はもうちょっと書く回数を増やしたほうがいい。
http://nothingcosmos.blog52.fc2.com/blog-entry-151.html
なんかコメントに書こうとしたら書き込み制限とか言われて書けない…
http://d.hatena.ne.jp/laysakura/20111113/1321155826
これ単に依存発生している/していないという違いではないかな、と思う。
リンク先の、sse_mulps_addps_forwardingは、xmm{0,4}, xmm{1,5}, xmm{2,6} xmm{3,7} が、それぞれ依存作ってて、並列性が4あるけど、sse_mulps_addps_no_dependencyは、xmm{0,1,2,3}, xmm{4,5,6,7} で依存作っていて、並列性2しか無い。
なので、sse_mulps_addps_forwardingは、sse_mulps_addps_no_dependencyよりIPC高い、という話で、fowarding(?)とかの不思議な現象は発生していないはず。
実際、sse_mulps_addps_forwardingを
"mulps %0, %%xmm0\n\t"
"mulps %0, %%xmm1\n\t"
"mulps %0, %%xmm2\n\t"
"mulps %0, %%xmm3\n\t"
"addps %%xmm0, %%xmm4\n\t"
"addps %%xmm1, %%xmm5\n\t"
"addps %%xmm2, %%xmm6\n\t"
"addps %%xmm3, %%xmm7\n\t"
こう書いても、IPCそれほど変わらない。
で、avx_vmulps_vaddps_forwardingは、ループのイテレーションごとに、完全に依存が切れていて、IPC 2 + 分岐命令が入って、IPC 2 overになっているように見える。
あと、x86のmicro-fusionは、メモリオペランドを取るx86演算命令が、メモリアクセス+演算のuopsに分解されない、ぐらいの意味で、複数のx86命令が融合されることは無いはずです。(http://download.intel.com/jp/developer/jpdoc/248966-024JA.pdf の2.1.2.1.の「マイクロフュージョン」あたり)
以前から、mwaitは簡単に使えるようになったら嬉しいのではないか?と、思っていたのだが、社内で、「実際mwaitってどうよ?」とかメールが流れてたので、よい機会だからなんか試してみた。
http://int.main.jp/files/devmwait.tar.gz
/dev/mwaitをつくるドライバと、それを実験するユーザプログラムが入っていて、なんか時間とかを計測できます。
色々計測した感想としては、まあ、無理して使うほどのものでもないかなぁ…というところだった。
x86のマルチスレッドプログラムで、効率よくメモリポーリングを実現する仕組み。
複数のスレッドが通信しあってるとして、別のスレッドがフラグを立てるのを待つ、とかするのは、たまによくあるパターンである。
普通にメモリポーリングを書くと、
volatile int *ptr; while (1) { if (*ptr == check_value) break; }
というような処理になる。
これはふたつの点で問題がある
で、今のプロセッサは、コヒーレンシ維持のために、他のコアによるメモリの書きかえを専用ハードウェアで監視することが可能なので、「メモリ上のフラグが立つまで待つ」という処理は、ビジーループを回すよりも、もっと効率良く実装できるはずである。
これをなんとかするのがmonitor/mwaitで、プロセッサをスリープ状態に入れながら、メモリの書きかえを監視できるようになる。これを使えば、上の問題のうち、「電力の無駄」のほうは、改善できる。
使いかたは、
となっていて、
addr = 監視したいキャッシュラインのアドレス; while (1) { monitor(addr); if (*addr == check_value) break; mwait(c_state); if (*addr == check_value) break; }
と、いうような感じにする。
c_state は、x86のスリープの状態の指定で…えーと…よくわかってないので各自調べてください(マニュアルの3Aに書いてある気がする)。
また、mwaitは、割り込みが来てもスリープから帰ってくるので、デバイスを待つことも可能。
あとSMI割り込みが入ってもスリープから帰ってくるので、なんかよくわからんけどスリープが解除されることもある。
と、いうのがmwaitなのだが、この monitor + mwait はRing0(OS)からしか使うことができなくて、「う〜ん、あるのに使えないってもったいないなぁ」とか、ずっと思っていて、/dev/mwait作ってioctlするだけとかなんか、そんなのをよく妄想していたのだが、社内で「誰かmwait実測したことある人おらんか?」とかメールが来たので、よい機会だから作ってみた。
のが、上のファイルである。
使いかたは、
ioctlの使いかたはDO_MWAITすればよいくて、パラメータは、
int *addr; // 監視したいラインのアドレス
__u32 mask; // 監視したい値
__u32 mwait_eax; // monitor するときの eax の値(C stateの値。詳細はマニュアル2Aのmonitorのところ)
__u32 mwait_ecx; // monitor するときの ecx の値(0でよい。詳細はマニュアルのmonitorのところ)
__u32 interrupt_threashold; // 何回起きたときにsleepに入るか。小さいほど他のタスクにCPU時間を譲りやすい
};
とかやる。
計測プログラムが、user/test-mwait.cにあるので、それを見てもらえれば。
で、interrupt_threasholdだが、上で述べたように、ビジーループには、
というふたつの問題があるのだが、電力は、まあいいとして、mwaitを使っても、CPU時間が別スレッドに譲られるわけではないので、上のほうの問題が解決しないので、なんとかして他のスレッドに処理を譲れないかと思って色々試した値。
中の、待ちをする部分が、
trycount = 0; while (1) { monitor(req.addr); if (*req.addr == check_value) break; mwait(req.c_state); if (*req.addr == check_value) break; if (trycount > req.interrupt_threashold) { msleep(1); trycount = 0; } else { cond_resched(); } }
みたいな感じになっていて、ある程度失敗すると、msleepするようになっていて、この値を調整することで、なんとかならんかなぁ、というのを試していた。
結論としては、msleepするぐらいなら、futexで待ったほうが速いし安定する、という感じで、あんまりうまくいかなかった。
(Documentation/timers/timers-howto.txtによると、まあ、なんか色々あるらしいので、ひととおり試したが、どれもあまりうまくいかなかった)
で、社内のメールには、「Atom で動かして hoge [usec] ぐらいでなんとかならん?」とか書いてあったので、hoge [usec]にならんか、というのを試した。結論としては無理だった。
CPU は i5-2400S
user/test-mwait.c を動かして、
で、
を計測した。
大体、
(※ i = interrupt_threashold) ** 通信レイテンシ - busy loop : 0.15[usec] (200clk) - futex : 45-100[usec] (115000clk - 254000clk) - mwait(i == 1) : 2.8-3700[usec] (4800clk - 9240000clk) - mwait(i == 100) : 2.7[usec] (4500clk) ** 消費電力 (…あ、しまった…これディスプレイ含んでる…ディスプレイ50Wぐらいです…) - busy loop : 97W - futex : 89W - mwait(i == 1) : 89W - mwait(i == 100) : 89W ** カーネルビルド - busy loop : 143.4 secs (3.004 CPUs utilized) - futex : 111.3 secs (3.885 CPUs utilized) - mwait(i == 1) : 126.4 secs (3.420 CPUs utilized) - mwait(i == 100) : 146.8 secs (2.935 CPUs utilized)
みたいな感じで、
と、いうような感じだった。futexの100[usec]のオーバーヘッドが性能にクリティカルな場面だと、mwaitの2[usec]ってかなり許せない値の気がするし、電力とか、ビジーループしても、そんな無理するほど変わるというわけでもないし、まあ、無理して使うほどでもないかな…という感じだった。
あと、Atom-N550でもはかっていて、
** 通信レイテンシ - busy loop : 3.5[usec] (2200clk) - futex : 60-80[usec] (90000clk - 120000clk) - mwait : 7.1[usec] (7600clk)
とか、メモに書いてある。
ただ、Atomだとシステムコール呼ぶだけで3[usec]ぐらいかかるみたいなので、
clock_gettime + ioctl = 6[usec]
ぐらいのオーバーヘッドがある。
Linuxだとioctlは消せないが、clock_gettimeは消せるので、
実質 4[usec] ぐらいではないかと思う。
まあ、無理して使うほどでもないか、という感じだった。
PCがバッテリで動いていて、マルチスレッドで、100[usec]のオーバーヘッドが許せなくて、3[usec]のオーバーヘッドが許せる場合には、mwaitを使うのも選択肢のひとつとして考えてもよいかもしれない。
http://d.hatena.ne.jp/w_o/20111130#c1322818333
で、コメントもらってますが、上のように、カーネル内で勝手に止まってしまうと、RCUのロックが解放されないという問題が発生するみたいです。上のdevmwaitは何も考えてないので、確認してないですが、多分同じ問題が発生すると思います。
h_sakurai
mwaitでお願いします。
w_o
すいません、まにあわなかった。明日こそ書きます。
しかし一体mwait何に使うんですか…
内容としては、「これって使うの難しいんじゃ?」という内容の予定なんですが、「〜みたいなのに使えないか?」とかあれば、実験したいと思いますが。
nminoru
mwait は特権命令なので一般的な OS だとカーネルしか使えませんね。
Linux はスレッドに対してシグナル等の非同期な割り込みがかかると thread_info 構造体の flags が更新されるので、最近の x86/Linux はアイドル処理に HLT を出す替りに thread_info の flags を mwait するという処理が入っているはずです。
過去に x86/Linux カーネルを勝手改造して、こちらの用意した専用メモリ領域が書き換わるまで mwait で待つという勝手システムコールの追加実験をしたことがあります。メモリ変化があるかプロセスに割り当てられたタイムクァンタムを使い尽くすまで C ステートを落として止まってもらおうと狙ったものです。
これ問題がありました。RCU のロックがいつまでたっても解放できなくなって、運用を続けると異常となりました。RCU のロックは、関係するカーネルスレッドがユーザースレッドに戻ると使用が終わったと判定できるのですが、その頃の Linux は tick のタイマー割り込み発生時にこの RCU をチェックしていました。その判定状態は「現在実行中のスレッドがユーザランドにいるかアイドル状態であること」です。
Linux カーネルが自前で使っている mwait 以外の箇所で mwait すると、プロセスが「カーネル内で動いている」ことになります。上記の RCU のチェックと思いっきりぶつかってしまったのです orz
w_o
> RCU のロックがいつまでたっても解放できなくなって
そんな罠が…それは気付かないですね…
h_sakurai
mwaitって何かもしらなかったのでmwaitをお願いしたのでした。
たまにはコメントしないとっていう。
w_o
> mwaitって何かもしらなかったのでmwaitをお願いしたのでした。
今度「ARMはWFEとかマルチコア用の命令があるから素晴らしい」とかいう人に会ったときに、「x86もmwaitありますし」とか言って喧嘩ふっかけたりとかしていただけると書いた甲斐があるのでぜひそういう感じ(?)でお願いします。
h_sakurai
なるほどー。JVM勉強会とかで、IA64がどうのとか出たときに話そうとがんばってみます。phpで memcache を使ってスピンロックをする奴を作ってたので、層は違うけど、カーネルレベルでにたような事をやれる凄い奴なんだなっと覚えておきます。
アイドル : 87W
pause なし : 101W
pause あり : 99W
pause のかわりにnop : 101W
と、なっていて、一応効果あるように見えます。
ワットチェッカ読みなので、この差だと信頼性イマイチですが、何回やってもpauseありのほうがわずかに低いので、なんらかの効果はあるみたいです。
もう少し効果があると思ったのですが、PAUSE 命令なしでもループを検出してフロントエンドを止めてしまうので不必要なリソースは使わないのかもしれません。