Win32 Fiber カッコワルイ

Win32 Fiber の局所人気

Fiber (あるいは MicroThread,Coroutine) の可能性は,特にゲームプログラマの間で高く評価されているようで,しばしば Win32 Fiber は非常に興味深くてチャレンジングな API として紹介されています.さて,言語機能としての Fiber が非常に興味深いという点はもちろん同意するところですが,一方でその語源とも言われる Win32 Fiber は一部の分野で高く評価されすぎているようにも思えます.
Win32 Fiber は世間で思われているほど万能ではなく,ほとんどの既存のライブラリと互換しません(誤解のないように修正) 特にマルチコア時代の軽量スレッドとしての用途では,既存のライブラリの多くに対し互換性の問題が発生します.もしあなたが,C/C++ 言語の世界に手っ取り早く Fiber を導入するために Win32 Fiber API に注目しているなら,もう一度考え直すことをおすすめします.
実際,私の知る限り,MSSQL Server 系の人々は,Win32 Fiber API に対してゲームプログラマとは正反対の評価を下しているようです.

Microsoft SQL Server のファイバモード

私の知る限り,Win32 Fiber API を実用的に使っている唯一のアプリケーションがMicrosoft SQL Server です.Microsoft SQL Server はファイバモードと呼ばれるモードを持っていて,スレッド切り替えに伴うカーネルモードへの遷移を減らすために Fiber を使用し,それによってスループットの向上をはかっています.
しかしながら,ファイバモードを使用することでスループットが改善するケースは希であるにも関わらず,ファイバモードによって引き起こされる問題の方が多いというのが実情のようです.
http://qlist1.quest.com/read/messages?id=12854

Win32 Fiber の副作用

プロセスレベルの並列処理よりもスレッドレベルの並列処理が好まれる Win32 プログラミングの世界では,実に多くのライブラリが Thread Local Storage (TLS) を使用しています.しかしながら,Win32 Fiber の実装では,あるスタックがスレッド A からスレッド B に移動することを許してしまうため,TLS を前提に書かれた多くのプログラムが破綻してしまうことになります(誤解のないように修正) Win32 Fiber は,メインにして唯一の利用者である MS SQL Server を見てもわかるように,ユーザモードスレッドを物理スレッドの垣根を越えて「持ち運べる」ようにし,手動で物理スレッドにディスパッチすることで,多数の CPU に大量のジョブを効率よく投入し,トータルスループットを向上させるというのが主目的です.しかし,このような大胆なスケジューリングを行う代償として,既存の TLS を前提に書かれた多くのコンポーネントが正しく動作しなくなるという問題があります.Slava Oks 氏は,このような問題を抱えたコンポーネントとして,次のようなものを挙げています.

  • COM
  • RPC
  • Side by Side
  • Older versions of CRT
  • Windows synchronization: Critical Section & Mutex

Be aware: FLS-Fiber Local Storage

もしあなたのアプリケーションが,これらの技術に依存しているとすれば,Win32 Fiber の使用は控えるべきです(誤解のないように修正) Win32 Fiber による TLS への影響を慎重に考慮すべきです.
.NET Framework 2.0 は,当初マネージスレッドの Win32 Fiber への対応が予定されていましたが,ぎりぎりまで作業が行われたあげくに結局 Win32 Fiber のサポートは取りやめとなってしまいました.このときの様子については『Fiber mode is gone...』で詳しく語られています.
そしてその結果,MS SQL Server 2005 の新機能である SQLCLR も,SQL Server のファイバモードとは排他利用ということになってしまいました.

Win32 Fiber Local Storage (FLS)

Windows Server 2003 kernel 以降の NT kernel *1は,Fiber Local Storage (FLS) と呼ばれる新しいストレージをサポートしました.従来の TLS 依存コードを FLS で書き換えることにより,真の意味で Fiber Safe なコンポーネントを作ることができます.実際,少なくとも Visual C++ .NET 2003 以降の Visual C++ CRT は,これらの OS で FLS を使用するように書き換えられています.しかしながら,古い OS では,いくら新しい CRT を使用しても,Fiber Safe にはなりません.また,古い CRT に依存したままのコンポーネントが残っている限り,アプリケーション全体での Fiber Safe はやはり実現できません.

参考資料

  • The Perils of Fiber Mode』は,MS SQL Server のファイバモードや Win32 Fiber API への幻想が抜けきれない誰かにお勧めの資料です.
  • Be aware: FLS-Fiber Local Storage』は,Win32 Fiber の障害となるコンポーネントが端的に列挙された分かりやすい記事です.
  • Advanced Windows 改訂第4版』では,ファイバモードについて数ページに渡って解説が行われています.しかし今回述べたような注意点について詳しく触れられていないため,実用にあたっては注意が必要でしょう.
  • MSDN Library: Fibers』でも,TLS に関する注意点や,FLS について解説が行われているので,一度目を通しておくとよいでしょう.何か不足していると思われる情報があれば,Community Comment に追記してみてください.

何でいまごろ Fiber?

この辺のかっこいい Fiber が震源かな?

*1:x64 Edition の Windows XP を含む