せっかく徹夜して測ったので貼っとくか

http://morihyphen.hp.infoseek.co.jp/files/perf.diff

命令ごとのカウントを測るようにするパッチです。今日のHEADとの差分です。正確性は知らない。あと手元のCore2で測ったらBigNumの乗算が遅いということは無くて、sendが遅かった。(おととい計測したのはPS3のPPE)

Core2は特殊すぎるので、Core2をターゲットにしてパフォーマンスを考えるのは非常に抵抗がある…大体のRISCは「依存性のない大きめの基本ブロックを作る」で大体解決できるのだけど、x86レジスタが少なすぎるのでこれができない。が、それでもCore2は大体のRISCより速い。

遅いループがあったとして、たとえば、BigNumの乗算とかmulが依存し続けるというまさに遅いループだったのだけど、これを速くしたいとする。

Core2はOut-of-Orderが付いてて、適当に並列化できるところが発見されてmulがスケジューリングできる、かつ、乗算のレイテンシが普通のマシンの半分くらいなので問題無い。でも他のアーキテクチャでは酷い。

で、このループは、キャリーをあとのループで足す、もしくは、アンロールして次の次の桁の乗算あたりとスケジューリングするとかして、mulが依存しないように書きかえれば、速くなる気がする。恐らく、この最適化は、x86以外、ARM、PPC、IA64、MIPSあたりでは効果がある気がする。(気がするブログ)

けど、x86では、これはレジスタが足りなくて多分遅くなる&読みにくくなる。

さて、こういう場合に、「読みにくくなる」という障壁をのりこえて、速くなるループにかきかえるべき、という主張をするにはどうすればいいだろうか?EM64TAtomとかで実験して主張すればいいかなぁ…

話が特殊っぽい感じになってしまったので、今どきのトレンドである並列化の話と混ぜておくと…

並列化の難しさとかは、技術的な問題というより、この問題の延長線上にある気がしてて、つまり、「ループ繰り越し依存がいかに悪か」を周知させて、かつ、「速くなるようにコードを修正しないといけない」というのを納得してもらわないといけない。