ToDo:
http://www.kmonos.net/wlog/111.html#_2334100705
なんかこの話は gus さんと何度かしたのでなんか書く。
結論としてはなんか C++ が残念な気がするという話なんだけど、 メモリアロケータの実際とか自信無い面があるので少しあやしい。 全く測定とかはしてないし。
まず、要素数が少ない時。
この時はどうせメモリアロケータ的に 穴もへったくれもなくてサイズごとのプール使ってるんじゃないのか。 そしてキリのいい数字の方がサイズごとのプールにちょっきり入りそうだし、 倍々でいいんじゃないの。
次に要素数多い時。
なんか mmap しはじめるはず。 ということで使い捨てたメモリは munmap されるだろうし やはり依然として穴とか関係ない感がある。
ただやはり瞬間的に要素数 * 3 のメモリが必要になるわけだし、 このへんになると直感的に 1.5 倍とか少なめな方が良さげな気もする。
そもそも要素数が大きくなってくると realloc が mremap になっていって、 mremap ならそもそも アドレスが移動しようがコピーいらなくなるんじゃね? ならし計算量どころか毎回 O(1) なんじゃね? という話を gus さんにした。
すると C++ の allocator は realloc しないと教えてもらった。 kinaba さんが引用している comp.lang.c++ の 議論にもあるけど、 C++ の vector は、 必ず、次の領域の allocate => コピー => free って感じでやる、らしい。
さて、仮に C++ の allocator に realloc があったらいいのかっていうと、 どうも realloc ではうまくいかない気がする。 というのは non-POD な型の場合、 アドレスの移動が起きた場合、 適切にコピーコンストラクタ呼んでやらないといけなくて、 しかし realloc でアドレスが変わった時って、 前の pointer は既に free されているのよね。
なんか話としては
などなど。なんか C++ ダメなんじゃないかと思った。 0x とかで解決されてるよ! とかだったらすいません。
(02:22)
でその議論の結論としては
#include <stdio.h> struct S { S(const S& s) { } }; int main() { // copy コンストラクタを定義たせいでデフォルトコンストラクタが無い時は //S s; // こうすればいいよ! S s(s); }
(02:32)
http://twitter.com/kazuho/status/17851784436
x86-64 の場合、無いと大変なことになる系かなと
何故でしょうか!!!
とかいうのはめんどいので書く。
x86-64 さんは、こうアドレス空間が広いです。 64bit 。 x86 と同じ 32bit 絶対でデータを mov とかしようとすると、 届かないことがあったりします。 つまりどういうことかというと、
void foo() { puts("foo"); }
をコンパイルして objdump する。
> gcc -c -g rip.c > objdump -Sr rip.o rip.o: file format elf64-x86-64 Disassembly of section .text: 0000000000000000 <foo>: void foo() { 0: 55 push %rbp 1: 48 89 e5 mov %rsp,%rbp puts("foo"); 4: bf 00 00 00 00 mov $0x0,%edi 5: R_X86_64_32 .rodata 9: e8 00 00 00 00 callq e <foo+0xe> a: R_X86_64_PC32 puts+0xfffffffffffffffc } e: c9 leaveq f: c3 retq
とかすると、まぁ callq の引数部分が 32bit 相対になっていて、 ここがその、 so とかになった時に loader が解決できない可能性があるわけ。
で、それが理由で普通に -shared とかすると、
> gcc -g rip.c -shared -o rip.so /usr/bin/ld: /tmp/ccbHkebh.o: relocation R_X86_64_32 against `.rodata' can not be used when making a shared object; recompile with -fPIC /tmp/ccbHkebh.o: could not read symbols: Bad value collect2: ld returned 1 exit status zsh: exit 1 gcc -g rip.c -shared -o rip.so
とまぁ怒られるわけです。つまりどこにでも置けるように PIC (position independent code) にしやがれ、と。
で言われた通りに -fPIC とかつけるとどうなるかっつーと、
0000000000000000 <foo>: void foo() { 0: 55 push %rbp 1: 48 89 e5 mov %rsp,%rbp puts("foo"); 4: 48 8d 3d 00 00 00 00 lea 0x0(%rip),%rdi # b <foo+0xb> 7: R_X86_64_PC32 .rodata+0xfffffffffffffffc b: e8 00 00 00 00 callq 10 <foo+0x10> c: R_X86_64_PLT32 puts+0xfffffffffffffffc } 10: c9 leaveq 11: c3 retq
こうなる。 ここに rip 相対が登場して、 .text と .rodata の相対的な位置は変わらんようにしてある (っていうかまとめて mmap するって話だと思う) のでちゃんと relocation できますめでたしめでたしというような。
ちなみに x86 だとどうなるかというと、
00000000 <foo>: void foo() { 0: 55 push %ebp 1: 89 e5 mov %esp,%ebp 3: 53 push %ebx 4: 83 ec 14 sub $0x14,%esp 7: e8 fc ff ff ff call 8 <foo+0x8> 8: R_386_PC32 __i686.get_pc_thunk.bx c: 81 c3 02 00 00 00 add $0x2,%ebx e: R_386_GOTPC _GLOBAL_OFFSET_TABLE_ puts("foo"); 12: 8d 83 00 00 00 00 lea 0x0(%ebx),%eax 14: R_386_GOTOFF .rodata 18: 89 04 24 mov %eax,(%esp) 1b: e8 fc ff ff ff call 1c <foo+0x1c> 1c: R_386_PLT32 puts } 20: 83 c4 14 add $0x14,%esp 23: 5b pop %ebx 24: 5d pop %ebp 25: c3 ret
なんか call が増えて大変なことになる。 __i686.get_pc_thunk.bx の定義は
08048416 <__i686.get_pc_thunk.bx>: 8048416: 8b 1c 24 mov (%esp),%ebx 8048419: c3 ret
という感じで、まぁ要は call で eip 取ってくるテクニック。
ところで、 なんで call pop じゃダメなのかは知らない。 intel さんが call があると ret やーというような解析を もりっとしていて、 call したのに ret しないと遅くなるとか そいうことだったりとかかなーとか妄想するが知らない。
あと、たしか、 x86-64 は 64bit 絶対 call とか、 64bit 絶対参照とかあったと思う。 このへん使えばどこにでも届くわけだけど、 やらないのは、どうせ PIC の方がいいじゃん (リロケーションのコストとか的に) ってことなのかなぁ。知らない。
(23:33)
こいう話は TCC の時に色々 考えたりしたので、 どっかで話したりする機会ないかなぁとか思いつつ今に至ってる気がする。
謎のメモが出てきた。
http://shinh.skr.jp/m/?date=20090331#p06
(23:36)
http://d.hatena.ne.jp/yshl/20100704#1278255925
おおありがたや、ということで適当に
http://github.com/shinh/w3m/commits/master
(00:45)
そうか $ をいじるという手があったかー
僕は fromInteger いじれるといいのかなぁとか思ったけど、 instance Num すると + を再定義せざるを得ないっぽいので どうしたもんかーという程度でとまってしまった
(06:39)
pm の man はあったものの w3mman で見れなかったので修正
http://github.com/shinh/w3m/commit/b9ad76673b43feba10f4d968948c8e44588f8334
(06:44)
すっかり忘れてた… 今からでもなんか書こう。
バイトしてた時の最初のプロジェクトは 大変社会勉強になるコードだった。
less とかで読んでいると、 どうも 2 行に 1 行空行が入っていて、 ヘンな style だなぁと思ったのだけど、 実は 20 段くらいネストしてるから 空白だけで 80 column 越えしてたのだった。
そのネストした中身はコピペな感じなコードなのだけど、 なかなか内容もためになった。
どういうものかということで一つ覚えているものを。 直線がたくさんあって、 その直線群、つまり
struct Line { float start_x, start_y, end_x, end_y; } vector<Line> lines;
とかいう lines があったとして、 その lines がループを形成しているかを判定したいらしい。
どうやってやってやるかというと、
複雑なコードの管理能力と、問題解決のための独創的な発想の2点で、 そのコードを書いた人は頭いいと思った。 つまりこう、頭は悪い方がいいのだなぁと勉強になった。
(07:22)
っていうジャンルがあるんだなぁ。 よく考えるとメインなノートPCのキーボードとかいらんわけだし、 もうこういうのでいい気がしてきた。
要求としては
この条件を満たしてなるべく安いものならいいと思った
(12:30)
dev channel 出てるなーということで入れてみた。
とりあえず linux は paged media 入ってるなぁ。
Win と Mac は間に合ってないっぽいな。 ちゃんとテストせんとなぁ…
(15:22)
http://route477.net/d/?date=20100702#p01
便利そうなので refe から離れるべく入れてみた。
rurema とか長いよってことで rure にした
(15:40)
man と apropos で良くねーと思った。
どうも Perl module と OCaml は man が入ってるみたいだ。 C++ の STL とかはあるわけだし、 Ruby とか Python も man にしておいてもいいんじゃないかな。 あと JavaScript も欲しいな
(15:51)
http://www.pps.jussieu.fr/~jch/software/polipo/
という cache する http proxy があるらしい。
filtering もできるっぽいから、 mod_python_filter とか使うのやめてこっちでいいかなぁ。
(16:13)
http://d.hatena.ne.jp/nurse/20100702#1278054508
CGI 好きなんだけどなぁ。
Process isolation というのは本当にいいもので、 つまりこう Ruby がクラッシュしようが メモリバカ喰いしようが、 そのプロセスさえ死んでくれればいいわけで、ねえ。
ゴルフ場はなんとなく FastCGI だけど、 正直 CGI の方がいいんちゃうかなーとかたまに思う。 なんかたまにメモリ大量消費してて、 よくわからん。
しかしまぁ、僕とかは ruby で web のなんか作る人間としては、 それこそ CGI.rb にそれなりに我慢ができる程度に 圧倒的にライトユーザなので、 まぁ意見としてはどうでもいい層なんだと思う
(23:56)
割と面白いかなぁ。 保存しないと反映されないんだけど、 html なんだからもうリアルタイムで更新してくれてもいい気もするな。 JS とかは保存を待って欲しいかもしれんが。
縦書きを transform でやってるのがあったので、 適当に flexbox でもやってみた。
Firefox だとびろーんと長くなった、が気にしない方向で。
(00:37)
つまり僕の転職候補会社が一つなくなったということだけど、 元々その可能性はとても低そうなので別に関係なかった
いや、しかし、これで楽天が大成功しちゃったりすると、 他の企業もマネしたりして、 つまり僕の転職候補会社が減っていく、 そういうことになると大変悲しいのだけど、 元々その可能性はとても低そうなので別に関係なかった
(23:23)
Mac は不思議がいっぱいだ!
まず ld が表題のエラーを出す件は、 これはまぁ普通に仮想メモリ空間が足りない。
http://www.opensource.apple.com/source/ld64/ld64-97.2/src/ld/ld.cpp
uint8_t* p = (uint8_t*)::mmap(NULL, info.fileLen, PROT_READ, MAP_FILE | MAP_PRIVATE, fd, 0); if ( p == (uint8_t*)(-1) ) throwf("can't map file, errno=%d", errno);
どうしたもんかなーというと、 正直 release build するくらいしか短期的な方法は思いつかん。
さて中期的な方法を考える。 どうせ mmap できないファイルなんて archive に決まってる、 そして archive を全部一気に mmap する理由とかどこにもない。
OK だいたいわかった。
Mach-O の .a はたぶん最初のエントリとしてなんかテーブルが入ってる。 これはたぶん ranlib が作るエントリだ。 名前が __.SYMDEF ならこのエントリになるっぽい。たぶん。 このファイル名のファイル作って突っ込んだらどうなるだろうね。
でまぁ Reader::getAtoms やら Reader::validFile やらは、 このエントリの列を iterate してるわけだなー。 iterate してる最中は、
template <typename A> const class Reader<A>::Entry* Reader<A>::Entry::getNext() const { const uint8_t* p = this->getContent() + getContentSize(); p = (const uint8_t*)(((uintptr_t)p+3) & (-4)); // 4-byte align return (class Reader<A>::Entry*)p; }
てな感じなので、 ちょぼちょぼ munmap mmap がはさまるような構造にしてやればいいんじゃないかねー。 やってられるかー
(00:40)
すげえ雑な方法で自分のところではリンクは通るようになった。
diff -ur ld64-85.2.1.orig/src/ld.cpp ld64-85.2.1/src/ld.cpp --- ld64-85.2.1.orig/src/ld.cpp 2010-06-29 07:54:08.000000000 -0700 +++ ld64-85.2.1/src/ld.cpp 2010-06-29 09:15:37.000000000 -0700 @@ -3088,12 +3088,19 @@ } + +struct GreaterFileSize { + bool operator()(const Options::FileInfo& l, const Options::FileInfo& r) { + return l.fileLen > r.fileLen; + } +}; void Linker::createReaders() { fStartCreateReadersTime = mach_absolute_time(); std::vector<Options::FileInfo>& files = fOptions.getInputFiles(); + sort(files.begin(), files.end(), GreaterFileSize()); const int count = files.size(); if ( count == 0 ) throw "no object files specified";
つまり全ファイルをデカい順に sort 。 ただこれでは chromium の bot はなおらんだろうね。 なんか build log 見ると謎の hack がボットには入ってるっぽい。
3時間ほどあれば根治もできると思うがー
(01:31)
適当に家賃を自動引き落しにしたいなぁというのと、 そういえば敷金はかえってきたんだろうか… というのを調べようと、銀行へ行った。
したらなんか色々やった
で、三井住友に振り込むから手数料高いっぽいので、 三井住友に聞きに行く。
結局毎回 400 円とかするとなんかちょっとバカらしいよねえ。 大屋と同じ支店で口座開くとかいう荒技もあるが。
どうも定期的な振込が安くでできる銀行口座開けってのが よくあるアドバイスっぽい。 めどいぞ。
(22:57)
cronlog を使わせてもらおうと思った。
http://github.com/kazuho/kaztools/blob/master/cronlog
僕は自分は C++ と Ruby を使って書くことが多いけど、 人が書いたものとしては C や Perl じゃないと許せないという 考えを持っているので Perl なのは良い。
どうでもいいけどこの guncat というのは zcat とは違うんかな。
さて health check は ruby の test/unit でいいのかなーと思ったが、 色々不満がありそうだ。
まずどうせ自動再起動も入れたいので、 失敗時にはなんかフック入れたいんだけど、 assert 一個につき test_ 一個書く感じにしたいので、 全部の test_ に rescue とか書かにゃならん。 一つの class の中の test が一個コケてたら 自動再起動スクリプトが走る…とかにしたいんだけどな。
こんなんでいいか
(01:25)
いくつか強そうなチーム
http://wiki.freaks-unidos.net/weblogs/azul/icfp-2010
http://gwillen.livejournal.com/65537.html
http://hoenicke.ath.cx/icfp10/
(17:58)
_ kazuho [うほ。お手柔らかに m(__)m > guncat というのは zcat とは違うんかな zcat だと全部のフ..]
http://twitter.com/kinaba/status/17019694551
これは
http://www.kmonos.net/pub/Presen/fltv/FLTV.pdf
の
.maxPrio = .max{|a,b| a.priority <=> b.priority} even = evens.maxPrio odd = odds.maxPrio
ができるって話よりもう一歩いい感じな感じだなぁ。
ミスって引数足りない時はどうなるのかな。 エラってくれないと静かに全然期待と違う動きすることがあってうざいと思うんだけど、 まぁいかにもこの部分適用だけされた関数使ってませんよーとか スコープ出る時に言ってくれたりしそうだけど。
(00:27)
こういう形式のゴルフコンペはどうかな。
つまりこうみんなで競争しながら頭ひねって答えを考えると。
とかいうルールを加えてもいいのかなぁと思う。 明らかに自明な最短解がある問題が出題されるとつらいので、 出題者は開始1時間解答できないとかそんな。
得点計算式に問題があるな… A さんが 10B 出して B さんが 8B 発見した時に、 9B => 8B と投稿した方が点数が多くなる式はダメだ。 むしろ分割するともらえる得点が減るといい気がする。
(01:34)
http://ja.wikipedia.org/wiki/MD5
MD5 はあっさり衝突するらしい。ダメぽ。
http://ja.wikipedia.org/wiki/SHA
SHA1 もうどうも衝突してるらしいじゃんダメぽ。
何かっていうと自分で書いたハッシュ関数とか 欲しいなぁというのがあったのだけど。
ていうか codegolf.com で sha256 書きましたっけ… すっかり忘れていた。
(01:59)
ニコニコの latency ひどいよなーと思って、 inspector で見てみると、 どうも prototype.js とかの 静的なコンテンツのダウンロードというか 304 Not Modified がかえってくるまでが遅い。
アホかーと思ったので、 とりあえずローカルの apache に mod_disk_cache を仕込んだ。 だいぶはやくなった。
(18:43)
powertop すると Ruby が上位に来ることが多い。
たぶん timer thread でもりもり起きてるのが問題かなーと思ってたんだけど、 よく考えると ruby 1.8 でも上位に来てる。 ruby-1.8.7 でも timer とかあるっぽいし 1.9 だけってのが記憶違いかな。
地球に優しくするにはどうすればいいんだろう。
http://redmine.ruby-lang.org/issues/show/270
に書いてあるみたいに最初に Thread.new するまでは 少なくとも必要ないのかなぁ。
ていうか thread の切り替えを促すってのは 各 thread が自発的にあー 10ms 過ぎたなーとか言って 他にゆずるとかできんのかな。
signal の集約の方は別にタイマとしての機能は必要じゃない気がするけど、 ええとどうなんかな。
(22:08)
u4 で適当に動かしていたサーバ群を適当に daemontools 管理下に置く。 具体的には
があったようだ。
あとは…
あたりが勝手に動くとなお良い。
それと health check 的なのを統合的にやりたいなぁ。 チェックすべきは
あたりか。
(23:23)
twitter のリソースの読まれっぷりを見てると、 spinner.gif とか loader.gif とか外部リソースなんだなぁ。 こいうのは data: にするもんなんかなぁと思ってた。
あとこれを最初に読む必要は無いよね…とか
(23:42)
前 | 2025年 1月 |
次 | ||||
日 | 月 | 火 | 水 | 木 | 金 | 土 |
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |
全てリンクフリーです。 コード片は自由に使用していただいて構いません。 その他のものはGPL扱いであればあらゆる使用に関して文句は言いません。 なにかあれば下記メールアドレスへ。
Before...
_ kosaki [なんかどこかで聞いたことある話だと思ったらmameさんがズバリ書いていてくれた。なんというエスパー]
_ shinh [おおたしかに再ヒットしてますね面白い。ただ、 linux+glibc だと後半半分くらいの overlap 、つまり..]
_ Rui [CALLとRETをペアにするほうが速いというのはどこかで読んだなーと思ったらAMDの最適化マニュアルでした(*1)。..]
_ m.ukai [> call pop 今時は平気で最適予測できると思いますが、return stack buffer を実装した初..]
_ shinh [Rui さん m.ukai さんコメントありがとうございますです。 ご指摘の通り、 -mtune= で call/..]