
2005-12-02
安藤秀樹著,コロナ社刊 (amazon)
昨今のプロセッサでは IPC (instructions par clock cycle; 1サイクルあたりの命令処理数)を向上させるために様々な技術が応用されている。本書では,それらの技術の中でも命令レベルでの並列性を扱うものについて解説を行っている。具体的にはスーパースカラと VLIW の2種類のアプローチについて触れている。
内容は簡潔にまとめられており非常に読みやすい。個々の技術について丁寧に解説を行いながらも,あまり掘り下げ過ぎないように気を遣っているような感触がある。参考文献リストが充実しているのも良い。特に掘り下げたい項目がある場合は,それらの参考文献を辿ることによって必要な情報に到達することができる。この辺りのバランスには好感が持てる。
VLIW に関しては個人的にあまり興味が無いため,後半部分はほとんど読み飛ばしてしまった。しかし,前半部分だけを切り出してみても,購入する価値はあると感じさせる内容であったと思う。
河田聡監修,今中良一著,電波新聞社刊 (amazon)
CD-ROM や DVD-ROM などの光ディスクメディアは,仕事で年中触れているわりには,知らないことがあまりにも多い。その辺りの話題について,基礎知識を身につけるつもりで購入してみた。
CD を始めとした種々の光ディスクメディアとそのドライブ装置に用いられている諸技術について解説を行っている。触れられているのはあくまでも概論であり,詳細な技術情報を得ようとしている人にとっては不足する内容かもしれない。自分のように一般教養的な内容が目的の場合には,適度なレベルであったと思う。
ただ,著者の個人的な意見や所感が混ぜられている点は少々気になった。やや客観性に欠けていると感じられるきらいもあり,「読み物」として割り切れば許容できるが,純粋な技術書を欲している場合は適切でないかもしれないと感じられた。
今村元一著,CQ出版刊 (amazon)
ビデオ信号についても知らないことが多い。これもやはり,基礎知識を身につけるつもりで購入してみた。
黎明期の TV 放映実験から始まり, NTSC やデジタル映像フォーマットなど,様々なビデオ信号規格について解説を行っている。こちらもやはり触れられているのは概論であり,専門家を目指すには不足する内容であろうと思う。自分の場合は色々と得るものがあったので適度なレベルだったと思う。下位互換性を重要視して発展してきた分野なので,歴史をなぞることによってようやく分かることも少なくない。
解説がやや大雑把である点は少々気になった。例えば周波数領域の捉え方などについて非常に危うい部分がある。理解を助けるための簡略化であれば大いに受け入れられるが,直感を重視するがあまりに勘違いや思い込みを誘発してしまうような解説になってしまうことは,技術書である以上最大限避けるべきであると思われる。
2005-12-07
複素平面におけるジュリア集合のプロットは,フラクタル図形の代表例として知られる [1] 。
ジュリア集合は複素数だけでなく,クオータニオンでも同様に求めることができる。クオータニオン上でのジュリア集合は4次元の形状として表されるので,これを「輪切り」にして3次元空間上に投影すると,非常に興味深い姿が現れてくる [2] 。
自作のレンダラーによる生成例を以下に示す。

クオータニオン上のジュリア集合は,複素平面上のジュリア集合と同じく,どことなく有機的な雰囲気を持つことが特徴として挙げられる。形状の複雑さやバリエーションの多彩さについては,複素平面上のそれと比較して非常に高いものが認められる。
クオータニオン・ジュリア集合のプロットを行うには複数の手段が考えられるが,恐らく,光線追跡(レイトレーシング)を行ってジュリア集合との交点を求めていくという手法が,最も単純かつ高品質であると思われる。この手法については Hart ら [3] に詳しい。光線毎の追跡処理はそれぞれ独立しており,並列化が容易であることから,最近では GPU などを用いた高速化が試みられている [4] 。
上の画像の生成には Crane の実装 [4] を参考にした。現状では FPU を用いたナイーブな実装であるため,様々な高速化の余地が考えられる。画質についても改良すべき点は少なくない。プログラミングの練習課題としては非常に面白いものであると思う。しばらくの間,このプログラムの改良を行ってみたいと考えている。
2005-12-12
映画「コンタクト」のストーリーは SETI (地球外知的生命体探査)プロジェクトを下地としている。地球外の知的生命体からの信号を受信した科学者達は,その受信した信号の中から,未知の技術によって構成された転送装置の設計図を発見する。映画のストーリーでは,幾多の困難に遭いつつも遂には転送装置を作動させ,神秘的なエンディングへと辿り着く。だがもし,地球外生命体が悪意をもって転送装置を送信してきたとするならば,どんな結末へと辿り着くことだろうか? これは,映画とはまた別のストーリーとして面白い筋書きではあると思う。
フェルミ国立加速器研究所 (Fermilab) の Richard Carrigan は, SETI プロジェクトの抱える潜在的な危険性について考察を行っている [1] 。 Carrigan によれば,現在の SETI プロジェクトは地球外知的生命体からの「攻撃」に対して「脆弱性」を抱えている。もし,受信されたデータの中に人類にとって害のあるデータが含まれていたとしても,これを防ぐために必要とされる適切な手続きは,今のところ用意されていない。
もし,地球目掛けて「攻撃」を仕掛けてくる地球外知的生命体が存在すると仮定するならば,その攻撃のきっかけとなるのは,地球からの信号であると考えられる。地球上で無線通信が開始されたのはおよそ 100 年前のことなので,往路を考慮すれば 50 光年の範囲にある恒星系から応答が返される可能性が考えられる。 TV 放送の場合は,開始されたのがおよそ 60 年前のことになるので, 30 光年の範囲から応答の可能性が考えられる。現在の天体観測によれば,地球から 50 光年の範囲には 400 個ほどの恒星が存在するとされている [2] 。
しかし,これらの信号は地球上での通信を前提としている。これらの信号を外部の恒星系において受信することは果たして可能なのだろうか? Tarter [3] によれば,現在の地球上の技術でも,1光年先の恒星系から発信された TV 信号を受信することは可能であるとされている(ただし,発信源と地球の間に別の恒星が存在しないことを前提とする)。受信技術が更に進歩すれば,この範囲は広がる可能性がある。ちなみに,軍事レーダー信号であれば 300 光年先でも受信は可能であり,更にアレシボ級のレーダーからの非常に強い信号ともなれば 3000 光年先でも受信は可能であるとされている。
Carrigan は主たる脅威として地球外からのコンピュータウィルスによる攻撃の可能性を危惧している。これは Carrigan がコンピュータに関して専門外であるがゆえの素朴な発想であり,実際のコンピュータウィルスに関して少しでも知識のある技術者ならば,この可能性を即座に否定することができるのではないかと思う。個人的にも,この可能性は万が一にもあり得ないと感じられる。しかし Carrigan は,地球外から持ち帰ったサンプルに対して厳しい検疫を行うのと同じように, SETI プロジェクトにおいて受信されたデータにも厳しい管理体制を敷くべきであると主張する。検疫にしてみても,実際に生体汚染が発生する危険性は恐ろしく低いものの,未知の脅威に備えるべくして行われているという側面がある。 SETI に関して同様の考えを当てはめることも,決して飛躍した発想ではないかもしれない。
結局のところ, Carrigan の主張するリスクは,それを対策するコストに見合うものであるとは感じられない。しかし,そもそも SETI 自体が一種の奇跡を追い求めるプロジェクトであることを考えれば,その恐ろしく低いリスクに対して備えを固めておくというのも不自然なことではないかもしれない。それに,もし地球外から有為な信号が受信されたとすれば,これはあらゆる地域のあらゆる文化において衝撃となることは間違い無いから,そこで普段は予想だにしなかったような事態が引き起こされたとしても決して不思議ではない。そのときに Carrigan が先見の人として脚光を浴びるならば,それはまたひとつの結末として愉快なことではあると思う。
2005-12-14
これまで C および C++ は良好な上位互換性を保ちながら進化を続けてきた [1] 。この基本方針は,次期 C++ 規格であるところの C++0x においても堅持されている。オリジナルの C++ 設計者であり C++0x 規格の策定にも携わる Bjarne Stroustrup 氏は,言語仕様の拡張は最低限に留め,なるべくライブラリの拡張によって機能を補うべきとの考えを示している [2] 。
C++ 標準ライブラリの拡張については,国際標準化委員会 (ISO/IEC JTC1/SC22/WG21) において検討が行われている [3] 。拡張の内容は Technical Report (ISO/IEC DTR 19768) にまとめられており,現在は 6/24 に公開された N1836 が最新バージョンのドラフトとなっている [4] 。策定の第一段階である TR1 (Technical Report 1) は近い将来に完成を迎え,次の段階である TR2 を経て,最終的には C++0x 規格に組み込まれる見通しとなっている。
TR1 における拡張項目を覗いてみると, Boost ライブラリからの転用がその多くを占めていることに気付く [5] [6] [7] 。 Boost 開発者達が行ってきた下積みがここでようやく活かされることになるのかと考えると,なかなか感慨深いものがある。モジュールの構成としては,ハッシュテーブルやスマートポインタのように以前から需要の高かったモジュールや,タプル (tuple) や固定配列 (array) のように使い勝手の良い軽量コンテナクラス,関数ラッパー (function) や関数オブジェクトバインダ (bind) のように高階プログラミングを強化するモジュール [8] などが含まれている。基本的に,従来の STL の構成を補強する形になっていると感じられる。
他とは少し毛色の異なるモジュールとして,正規表現処理や擬似乱数生成などが挙げられる。また,最終的な C++0x 規格においては,これらのモジュールに加えて,例えば並列性のサポート機能などのように,よりシステム色の濃いモジュール群が追加されるとの方針が示されている [2] [7] 。
TR1 は基本的に仕様だけの存在であり実装は存在しない。ただし,いくつかの処理系は TR1 の実装に着手している。例えば GCC 4.0 においては TR1 モジュール群の一部が既に実装されている。この実装の過程については GCC Developers' Summit の記事に詳しい [9] 。一部にはコンパイラ側の拡張が必要なモジュールや,コンパイル時のパフォーマンスに深刻な影響を与えるモジュールなどが存在するようであり,苦労が偲ばれる。
2005-12-21
GCC には以前からプロファイルを利用した最適化の機能が搭載されているが,この機能は近年になって更なる改良が加えられている [1] 。最適化の内容については Hubička [2] および Dvořák ら [3] に詳しい。
プロファイルを利用した最適化(以下「プロファイルフィードバック」)を用いるには,まずプロファイルの取得を行う必要がある。オプション "-fprofile-generate" を付加してコンパイルを行うと,プロファイリング用の特殊処理が組み込まれたコードが生成される。このコードを実行すると,プロファイル情報を含んだ拡張子 gcda のファイルが,各オブジェクトファイルに対応するかたちで出力される。
適当な試行によってプロファイルを取得したら,プロファイルは残したままプロジェクトを一旦クリアし,今度はオプション "-fprofile-use" を付加して再コンパイルを行う。すると,プロファイルフィードバックが行われたコードが生成される。
なお,プロファイルの取得時と利用時ではコンパイルオプションを同一に保つ必要がある。例えば,最適化オプション "-O2" を用いるならば,プロファイル取得時にもこれを有効にしておく。
本来ならば,プロファイルフィードバックを用いる場合にはプログラム全体コンパイル (whole program compilation) を併用することが推奨される。これにはオプション "-fwhole-program" および "--combine" を付加すればよい。ただし,これらのオプションは GCC 4.1 からの追加機能であるため,現在の正式リリースバージョン (GCC 4.0.2) では用いることができない。もとより,プロファイルフィードバックの機構自体も GCC 4.1 において変更されているため,文献 [2] と同じ効果を得るには GCC 4.1 を導入するか,あるいは以降の正式リリースを待つ必要がある。
現状では,フローのプロファイリング (edge profiling) と,値のプロファイリング (value profiling) が実装されている。これらのプロファイリングは, GCC に以前から存在するプロファイリングの機構を改良するかたちで実装されている。
フローのプロファイルは,制御フローグラフ (control flow graph; CFG) [4] [5] の分析に用いられる。制御フローグラフとは,基本ブロック(内部にジャンプを含まない一連の処理)を頂点 (node) とし,基本ブロック間のジャンプを辺 (edge) とするグラフ構造であり,データフロー解析をはじめとする各種の最適化処理に用いられる。 edge profiling はこのグラフ構造の各辺を通過する頻度を記録することを意味する。
値のプロファイリングについては,簡単なヒストグラムの記録と,2の累乗の検出のみが実装されている。そもそも現状では,値のプロファイルに基づいた最適化は簡単なものしか実装されていないため,プロファイルの内容もごく簡単なもののみに限定されている。
これらの動的なプロファイルの他に,静的プロファイル (profile estimation) も最適化に利用することができる。これは,何らかの理由によって動的なプロファイルの取得が不可能な場合に,代替の手段として用いられる。
静的プロファイリングでは,生成コードを実行せずに,静的な分析のみによってプロファイルの「見積もり」を行う。この手法は主に Ball and Larus の静的分岐予測の手法 [6] に基づいている。
例えば,ループ処理においてループの先頭に戻るフローは通過頻度が高いと予測することができる。また, exit や abort のように帰還しない関数へと繋がるフローは通過頻度が低いと予測することができる。これらの予測は「安定した予測」として静的プロファイリングに用いられる。
このほかに「不安定な予測」も静的プロファイリングに用いられる。例えば,ポインタの NULL チェックを行う分岐や,2つの浮動小数点値が等しいかどうか確認する分岐は,不成立 (not taken) である可能性が高い。これらの予測は前述の予測ほど安定はしていないが,補助的な情報として加味することはできる。
フローのプロファイルからは,各基本ブロックの重要度を導き出すことができる。基本ブロックの重要度が判明したならば,重要度の高いブロックには優先的にレジスタの割り当てを行ったり,重要度の高いブロックのみを選択的にインライン展開したりすることができる。また,重要度の高いブロックを含む関数は,専用のセクション ".text.hot" に格納される。これにより,命令キャッシュの負担の軽減や,ジャンプ時の距離の短縮を期待することができる。
このほかに,ブロックの順序入れ換えによる分岐回数の軽減や,末尾ブロックの複製 (tail duplication) による合流地点の消去などが行われる。後者は,分岐後に合流するフローを,合流後のフローを複製することによって,合流の無い単純な基本ブロックへと変換する (superblock formation) 。こうして最も重要なパスを単純化することができれば,そこから更なる最適化を期待することができる [7] 。
値のプロファイルについては,今のところ,変数による除算を定数除算に変換する,2の累乗による乗除算をビットシフトに変換する,等々の単純な最適化にしか用いられていない。ただし今後の改良において,値のプロファイルに基づいた仮想関数のインライン化などが検討されている。
文献 [2] によれば,プロファイルフィードバックを用いることにより,整数系ベンチマーク (SPECint 2000) において平均で 12.22% の速度向上が実現されている。また,静的プロファイルのみでも 6.17% の速度向上が実現されている。これは最適化の効果としてはかなり高いものであり,近年 GCC に追加された最適化機能の中では最も効果的なもののひとつであるとされている。
手元の環境でも簡単な試験を行ってみたが,不完全なバージョン (MinGW GCC 3.4.2) を用いたためか,文献通りの効果を得ることはできなかった。そればかりか,プロファイルフィードバックを行うことによってパフォーマンスが低下することもあった。この辺りについては GCC 4.1 以降の環境が入手できてから再び検証を行ってみたい。
プロファイルフィードバックによる恩恵を真っ先に被ることができるのは GCC 自身であると思われる。標準ライブラリのビルドのついでにプロファイリングを行えば,それなりに鍛えられた GCC を生成することができる。文献によれば 7% 程度の速度向上が実現されている。
また, Linux ディストリビューションの構築を行う際にも,テストプログラム (make check) の実行時にプロファイリングを行うことによって,簡易的に最適化を行うことができる。これは実用データではなくテストデータに合わせた最適化となるため,必ずしも最良の結果とはならないものの,平均で 10% 程度の速度向上を得ることができるとされている。
フローのプロファイルは重要な基本ブロックの特定に利用される。各種の最適化はその基本ブロックを優先するかたちで行われる。
フローのプロファイルは他に,重要なフローの単純化に利用される。
実際にプロファイルを行わなくとも,静的プロファイルによって,ある程度の最適化を期待することができる。
GCC のプロファイルフィードバックは発展途上中であり,好ましい結果を得るには少なくとも GCC 4.1 以降の正式リリースを待つ必要がある。
プロファイルフィードバックの効果にはばらつきが多く,一定の傾向を掴むことは難しいが,うまくいけば 10% 程度の速度向上を期待することができる。
2005-12-26
モジュラーシンセサイザーとは,様々な種類のモジュールを組み合わせることによって音色を作り出す形式のシンセサイザーのことを指す。現在ではあまり用いられない形式ではあるが,少量の需要が存在することから製造は続けられている。この種の製品を現在も製造しているメーカーとしては Analogue Solutions, Analogue Systems, Buchla & Associates, Doepfer Musikelektronik などが挙げられる。
モジュラー間の接続には主にケーブル(パッチケーブル)が用いられる。大量のケーブルと操作子(ノブ)によって覆われた外観は非常にアナクロ的であり,初期のコンピュータの姿を連想させるものがある。以下に例として Buchla 社の 200e を挙げる(画像は Buchla 社のサイトより転載)。

モジュラーシンセサイザーが廃れた理由としては,製造コストがかさむこと,音色のメモリー保存ができないこと,筐体が場所をとること,消費電力が高いこと,等々が挙げられる。要するに,自由度が高いこと以外にはあまり利点が無い。しかし,その自由度の高さや,音作りのメカニズムと直接触れ合うことの面白さなどから,現在でも愛好する人は少なくない。例えば Keith Emerson は今でも Moog Modular をライブパフォーマンスに利用している。また,上の Buchla 200e は Nine Inch Nails の備品の中に見つけることができる。
モジュラーシンセサイザーには前述のような欠点があり,趣味で導入するには非常に敷居が高い。最近では PC 上でモジュラーシンセサイザーをエミュレートするソフトウェアがあるため,これを使えば比較的気軽にモジュラーシンセシスを楽しむことができる。例としては Arturia 社の Moog Modular V などが挙げられる。
ソフトウェアによるエミュレーションは比較的高い負荷が要求されるため,これを外部のハードウェアに行わせるという方式の製品も存在する。例としては Creamware 社の SCOPE プラットフォームや, Clavia 社の Nord Modular シリーズなどが挙げられる。特に後者は単体の楽器としても機能する製品として比較的有名な存在となっている。
1998 年に発表された Nord Modular 初代ラインナップの中に Nord Micro Modular と呼ばれるモデルが存在する。同シリーズにおいて最も小型かつ廉価なモデルであるが,その分機能も制限されている。省スペース性を意識しているように感じられるものの,ラックマウントには対応していない。また,ノブの少なさからするとパフォーマンス向けというわけでもない。結局のところセールスもあまり振るわなかったのか,これ以後,同社のラインナップに "Micro" の語が現れることは無かった。
現在でも微妙に人気は無いようで,他の Clavia 製品が高値を維持しているのに対して,中古の Micro Modular は 4-5 万円程度で入手が可能となっている。運が良ければもっと安価に入手することができるかもしれない。

中古の Micro Modular を導入する際の注意点として,エディターの互換性の問題が挙げられる。 Nord Modular シリーズでは回路の構築(パッチング)に PC 上のエディターを用いるが,初代ラインナップ向けの旧バージョンのエディターには互換性の問題が存在し,通常の状態では Windows XP 上で動作しなくなってしまっている。これを解決するには,エディターの実行形式のプロパティから「互換モード」を有効にしておく必要がある。恐らく Windows 98 互換に設定しておけば問題無く動作するものと思われる。

簡単なパッチの例として TB-303 を模したアシッド系ベース音色を作成してみた。まず最初にパッチの構成を以下に示す。

オシレーターには基本的な鋸状波(ノコギリ波)を用いつつ,少しクセを与えるために Shaper で変調した波形を合成した。純粋な鋸状波だと少し音が太過ぎる(低音成分が多い)ような印象があったので,適度に軽くなるまで変調波を合成するようにした。
オリジナルの TB-303 は 18dB/Oct のローパスフィルターを用いているとのことなので,これにならってフィルターは 18dB/Oct とした。無論,オリジナルのフィルターを忠実に再現することはできないが,適度に近いものにはなっていると思う。
エンベロープは,アンプ側には標準的な ADSR 形式を用いつつ,フィルター側には軽量な AD 形式を用いている。また,これらのゲート信号には通常の "Gate" 入力ではなく "Patch gate" 入力を用いている。 "Patch gate" を用いることによって,レガート(キーオフ前に次のキーを繋げた状態)時に再トリガーがかかるのを防ぐことができる。これは,アシッドベースの特徴でもあるスライド奏法を実現するのに不可欠な手続きとなる。
また,オリジナルの TB-303 は出力に軽いクリップがかかっているとの情報があったので,最終出力には微量のオーバードライブをかけてみた。これはもしかしたら蛇足かもしれない。
パッチの構築が完了したら,操作子への割り当てを行う。ここでは最も調整頻度が高いと思われる「フィルター周波数」「フィルター変調量」「エンベロープ減衰速度」の3つのパラメータに割り当てを行った。本当はフィルター・レゾナンスにも割り当てられると良いが, Micro Modular には割り当て可能な操作子が3つしかないので諦めた。
このパッチの使用例を示す。個人的な感想としては,少し音に「張り」があり過ぎるような気がする。もう少し「くぐもった感じ」や「粘り気」のようなものが与えられると良いと思う。
参考として,ディストーション・エフェクトを付加した例を示しておく。エフェクターには,ギター用エフェクターの BOSS OS-2 を用いた。