FireGL お前もか!

3年前に購入したDellのノートPCがスペック的にも厳しくなってきたのでエプソンダイレクトのNJ5100Proに買い換えた。

スペックはこんな感じ。
  1. 15.4インチ液晶、WUXGA(1920x1200)
  2. Core2 duo T7500(2.2GHz)
  3. Mobility FireGL V5600 512MB
  4. 240GB RAID 0 HDD
15インチでWUXGAというのが必須条件だったのだが、これを満たすノートはDell、エプソンダイレクト、HP、NECでそれぞれ1機種ずつしかなく、ほとんど選択の余地がなかった。

さて、RAIDのおかげかビルド時間がかなり短縮したし、OpenGLの描画もかなり速くなったし、いい買い物したな・・・と思っていたのも束の間のことであった。
OpenGLアプリケーションの要素のピックがめちゃくちゃ遅い。 どのくらい遅いかというと、そこらのポンコツマシンでも瞬時に処理が終わるのに数10秒も待たされるのである。
どうやらOpenGLのセレクション周りでFireGLのドライバに不具合があるようだ。
これでは個人的にマシン自体が ま っ た く 使い物になりません。
(とりあえずGLのセレクションを使わずに NV_occlusion_queryで高速なピック処理ができそうな気もするので、それで回避できるか、ひまなときに調べてみよう)

昔からATIのOpenGLのドライバには恨みがたくさんあった。
古くは、Rage128なんかでは同じくGLのセレクション周りで、結果のZ座標の正負が逆というとんでもないイージーなバグもあったりしてショックのあまりあやうく失神しそうになったことがある。
そして、FireGLまでもATIに買収されて残念な製品になってしまったようだ・・・

とりあえずATIには・・・
          ,;r'"´;;;;;;;;;;;;;;;;;;;;;;;;;;`ヽ、
         ,r'";;;;:::::;彡-=―-=:、;;;;;;ヽ、
        /;;ィ''"´  _,,,,....ニ、 ,.,_ `ヾ;;;;〉  
         `i!:: ,rニ彡三=、' ゙''ニ≧=、!´  屋上に行こうぜ・・・・・・
        r'ニヽ,   ( ・ソ,; (、・')  i'
         ll' '゙ ,;:'''"´~~,f_,,j  ヾ~`''ヾ.   久しぶりに・・・・・・
        ヽ) , :    ''" `ー''^ヘ   i!
        ll`7´    _,r''二ニヽ.     l   キレちまったよ・・・・・・
        !:::     ^''"''ー-=゙ゝ    リ
        l;:::      ヾ゙゙`^''フ    /
        人、      `゙’゙::.   イ


Foreach

Boost.Foreachは簡単に使えて、かつ、メリットも大きいライブラリだ。
forループを Perlなんかの foreachのように記述できるようになる。

たとえば配列だったら
double a[] = {1,2,3,4};

for (int i = 0; i < sizeof(a)/sizeof(*a); ++i) {
  a[i] *= -1;
}
なんて書いていたのを
double a[] = {1,2,3,4};

BOOST_FOREACH(double& d, a) {
  d *= -1;
}
てな感じにループカウンタなどを気にしないで書ける。 これがものすごーく快適。
ループの終了条件があっているかだとか、多重ループでは正しいカウンタをインクリメントしているのかだとかに労力を費やす必要がなくなるのは本当に大きい。

listなんかにも当然使えるのだけど、
for (std::list<int>::const_iterator it = l.begin(); it != l.end(); ++it) {
  std::cout << *it << "\n";
}
BOOST_FOREACH(int n, l) {
  std::cout << n << "\n";
}
と書けて、プログラマの意図するところも短く明確に伝わるようになる。

シーケンスとして扱えるものは配列やlistだけでなく、以下にあげたようにrangeになっているものならOK。さらに自分の作ったコンテナ型でもちゃんとコンセプトを満たせば利用できるようになる。
  • STLコンテナ(とその仲間たち)
  • 配列
  • NULL終端文字列 (char[], wchar_t[], char*, wchar_t*)
  • std::pair<Iterator, Iterator>


パフォーマンス面では、ドキュメントをみるかぎり
  • 動的メモリ確保や、仮想関数呼び出し、関数ポインタ呼び出しなどが一切なく、コンパイラの最適化を阻害しない。
  • 普通にループをハードコードした場合にくらべて数%程度のパフォーマンス犠牲しかない。
とのことなので問題になることはほとんどなさそう。

注意するべき点としては2つほどドキュメントで挙げられている。 1つはBOOST_FOREACHはマクロを使って実装されているので、カンマの数は1つでなくてはならない。
とすると、mapなんかの場合に問題になる。
std::map<char*, int> m;

BOOST_FOREACH(std::pair<char*, int> p, m) {  // コンパイルエラー! カンマが複数個ある。
  ..
}
これはtypedefによって回避するか
std::map<char*, int> m;
typedef std::pair<char*, int> P;

BOOST_FOREACH(P p, m) {  // OK!
  ..
}
あらかじめ内容を受け取る変数を宣言しておけばいい。
std::map<char*, int> m;
std::pair<char*, int> p;

BOOST_FOREACH(p, m) {  // OK!
  ..
}

もう1つはループ中に、ループの終了条件を表すイテレータ(end()で返すもの)を無効にするような操作を行ってはならないということ。
std::vector<int> v(4);

BOOST_FOREACH(int n, v) {
  v.push_back(1); // vectorだとpush_backによって 以前にend()によって返されたイテレータが無効になるのでアウト。
}
これはfor文を素直に使うしかない。


ところでBOOST_FOREACHはマクロを使って実装されているのだが、マクロの有名な副作用、つまり引数が複数回評価されて大変な事態を引き起こすことがないように変態テクニックを駆使して実装されている。
以下のようなコードでも GetStringFromStream()関数が呼び出されるのは1回限りであることが保証されている。
BOOST_FOREACH(char c, GetStringFromStream()) {
  ...
}

どのようなトリックを使って実現しているかは このページに記述されているが、とっても面白いので興味のある人は一読をオススメする。
記事のタイトルが "Conditional Love"(訳: 条件演算子、愛してるよ、条件演算子)になっているのが最初意味不明だったが、読み進めていくうちに謎が解き明かされていく。
C/C++の世界では悪役にされがちな条件演算子(?演算子)が、BOOST_FOREACHではとてつもなく重要な働きをしていることに感動すら覚えマスタ。

Planet Earth


Planet Earth - The Complete BBC Series [Blu-ray]

NHK、BBC、ディスカバリーチャネルとで共同制作したドキュメンタリー番組「プラネットアース」の Blu-ray版を買った。
ハリウッド映画でさえ、まるで相手にならない美しい映像が4枚組みで550分も入っている。それでいて、amazon.comでポチれば日本への送料込みで 約$73という安さ。Blu-ray見れてドキュメンタリ好きな人ならマストバイですな。驚異の映像ばかりでひたすら口をポカーンと開けて眺めてしまう。
音声も字幕も英語だけど、ナレーションが非常にゆっくり&聞き取りやすい声だし、そんなに難しい文章もないので、英語の勉強にもいいんじゃないでしょうか?



ちなみにNHKも日本語ナレーション版のDVD-BOXを売ってますが、全部買うと4万円を超すというボッタクリ価格です。
日本のDVDソフトの高さは異常だねえ・・・
Blu-rayでは、日本とアメリカのリージョンコードが同じになったので、アメリカのソフトも普通に再生できるようになったけど、これで日本のソフトも安くなってほしいもんだ。

報道ステーションにHamanaが!?

今日Hamanaのホームページのリファラをみていたら、 やけに変なところから飛んできている。
というわけで元をたどってみたら報道ステーションの番組中に Hamanaがちょっと登場したらしい。
昨日は10時20分ごろからいつものように報道ステーション見始めたのだが、放送されたのはそのちょっと前らしく、見逃してしまった・・・
/(^o^)\ <なんてこったい
一年近くバージョンアップしてないから、忘れられないためにもそろそろ新しいのリリースしないとな・・・

ついでに、ステーションつながりで、雀鬼こと桜井章一がニュースステーションに登場した回の動画を最近見つけた。この回は前から見たかったんだ。

5:00ぐらいからのロン牌を自由に変えるイカサマは圧巻。左手に5ピンを握りこんでいるんだろうが、いつやってるのかさっぱりわからん。20年間無敗というのは伊達じゃねえな。
昔の会社の社長(マジックが趣味)の尊敬する人物の一人が、桜井章一だというのを聞いて当時は驚いたが、わかった気がする。

割り箸の正しいリサイクル

割り箸を使ったメンマの作り方
http://portal.nifty.com/2007/04/01/uso03/

ほんとに割り箸が立派なメンマになっていやがる・・・ビックリ。

<< 5/25 >>