Entry

そういえば関数ポインタとジャンプテーブルについて

2012年06月10日

以前,関数ポインタに関する入門書の解説について,関数ポインタを配列で管理するようなコードを現実に見ることはほとんどないとゆ話を書いたのでした。しかし,まったくないかというとそゆわけではなく,一応使用例はあるのです。いずれにしても,一般的な入門書で書かれているように,for-文でクルクル回すようなことはしないのだけど。

どういう場面で使うかというと,これはジャンプテーブル(テーブルジャンプ)と呼ばれる制御機構を作るときに使われます。マイコンや OS カーネル周りを扱ったことのある向きはおなじみだけれども,例えば AVR のようなマイコンでは,割り込みベクタと呼ばれる関数ポインタ(のようなもの)があらかじめ定義されている。どうしてこういう機構が必要なのかというと,ひとつは if-文を使用せずインデックスでアクセスできることから場合に応じて処理を振り分ける際に速度的に優位な場合があること,もうひとつは共有ライブラリのように,仮想メモリ上のメモリ配置の関係でサブルーチンを動的に設定しなくちゃいけない場合があることが挙げられます。

この点,速度的に優位な点があるなら,マイコンや OS カーネル周り以外にも使い出があるじゃないか,とも思えます。実際,ゲームプログラミングなんかではジャンプテーブルを実装しているところもある。しかし,やはりジャンプテーブルといったテクニックは,関数ポインタの使用方法としてニッチな部類に属するのだと思う。

関数ポインタをあらかじめ配列に格納しておき,インデックスから直接関数を呼び出す方式では,たしかに呼び出す関数を決定する際の if-文を省略することができます。しかし,インデックスを管理する方法自体にコストがかかる場合,それは関数を決めるコストをインデックスを決めるコストに置き換えたただけで,意味がない。作りによってはむしろ遅くなってしまう。端的に言うと,インデックスで飛び先を決めるにしても,インデックスの値それ自体を if-文で決めていたら意味がないとゆこと。

テーブルジャンプを使う場面とゆのは,例えば,有限状態機械を構成する際の状態遷移表でアクションに相当する関数をまとめるときくらいなのだと思う。つまり,その状態に紐付くアクションで次の状態を戻すことによって,if-文を省略できる場合があるとゆこと。もっとも,この適用例にしても,場合によっては普通に switch-文を使った場合よりも遅くなりうる(その状態に固有のアクションがない場合も次の状態を返すために必ず関数呼び出しが入るので,関数呼び出しのコストが必ず上積みされる)。また,配列のインデックスと状態を表す状態値の帳尻が合ってないといけないので,状態値を柔軟に定義することも難しくなる。

結局のところ,こゆテクはかなり目的が限定されたところで使われるテクニックなわけで,やはり関数ポインタの使用例として説明すべきではないのだと思う。こゆ例が出ると,あー……この人普段プログラム書いてないんだな,とか思ってしまいます。

Trackback
Trackback URL:
Ads
About
Search This Site
Ads
Categories
Recent Entries
Log Archive
Syndicate This Site
Info.
クリエイティブ・コモンズ・ライセンス
Movable Type 3.36
Valid XHTML 1.1!
Valid CSS!
ブログタイムズ

© 2003-2012 AIAN