2011年12月31日土曜日

ケーパビリティを使ったリソース保護機構「Capsicum」


このエントリでは、ケーパビリティを使ったリソース保護機構である「Capsicum」を紹介します。Capsicumは、まもなく正式リリースされるFreeBSD 9に搭載される予定です。

Capsicumとは?
タネンバウムの「モダンオペレーティングシステム」では、オペレーティングシステムのリソース保護機構について、以下の3つを紹介しています。
  • 保護ドメイン
  • アクセス制御リスト
  • ケーパビリティ
これらのうち、ケーパビリティとは、改竄不可能なトークンを使ったアクセス制御ですが、これまでごく一部の研究用OSでしか実装されてきませんでした。

Capsicumとは、そのようなケーパビリティを使ったリソース保護機構を一般的なUNIXに導入しようというプロジェクトです。

Capsicumによるメリット
オペレーティングシステムのリソース保護機構については、DAC(Discretionary Access Control)やMAC(Mandatory Access Control)が広く使われていますが、これらは、1つのアプリケーションが様々な形式のリソースを扱う場合のリソース保護に向いたようには設計されていません。ここでいう様々な形式のリソースとは、たとえば、ウェブブラウザの場合、画像、動画、Flash、JavaScriptなどといったデータです。信用を受けたリソース元ではない可能性もあります。

そのような様々な形式のリソースを扱う局面おいてデータを保護するために、ウェブブラウザのChromiumでは、プロセスを複数に分けることでコンパートメント化を実現しています。ところが、この方法をとる場合、プラットフォームによってプロセス周りの仕様が変わるため、プログラマがそれぞれの環境に合わせてそれなりの量のコードを書いて実装しなければならないという問題があります。

この問題への解決策として、一般的なUNIXにケーパビリティを使ったリソース保護機構を補完的に導入しようというものが、Capsicumです。たとえば、Chromiumへのテスト実装では、わずか100行のコード追加で、コンパートメント化を実現できたといいます。

Capsicumは、FreeBSD 9に導入される予定です。12月9日にFreeBSD-9.0 RC3が公開されたので、来年の早いうちには正式リリースされるでしょう。

--

2011年12月28日水曜日

コンピュータシステムのアクセス制御における、2つの文脈


システムのアクセス制御といったとき、大きく2つの文脈に分けられます。オペレーティングシステムの分野における伝統的なアクセス制御と、企業内の情報システムにおけるアクセス制御の2つです。

後者は前者からの派生でありもちろん両者には関係性があるのですが、前者は悪意を持った攻撃者への対策という観点が主である一方、後者は複雑な組織内での適切な権限割当てという観点が大きくなっています。

オペレーティングシステムにおけるアクセス制御
タネンバウムの「モダンオペレーティングシステム」では、オペレーティングシステムのファイル保護機構は以下の3つが紹介されています。
  • 保護ドメイン
  • アクセス制御リスト
  • ケーパビリティ
保護ドメインは任意アクセス制御(Discretionary Access Control; DAC)、アクセス制御リストは強制アクセス制御(Mandatory Access Control; MAC)ともいわれます。

DACとMAC
従来のオペレーティングシステムにおけるアクセス制御として、DACとMACがあります。

DACはもともと、ユーザをお互いから守るように設計されていました。ファイルのようなオブジェクトの所有者が、そのオブジェクトへのパーミッションを指定できるという仕組みです。パーミッションは、そのオブジェクトがアクセスされるときに、OSによってチェックされます。

ところが、DACには脆弱性があります。root権限のような特権がアクセス制御を迂回できてしまうため、システムをクラックされて特権を取得されると重要なファイルを書き換えられてしまう可能性があるのです。これは、リソースの所有者とそのリソースへのアクセス権限設定者が分離されていないことによる問題です。

MACは、そういったDACの弱点を補い、システムのセキュリティポリシーを強化するよう設計されました。システム管理者がポリシーを決め、そのポリシーがOSのカーネルのあちこちに埋め込まれたフックによってチェックされます。

ケーパビリティ
DACやMACは、リソースに対してセキュリティレベルを設定するという考え方に基づく仕組みです。一方、プロセスに対して最小限のアクセス権限を与えることでシステムの安全性を高めるという考え方があります。それがケーパビリティです。

たとえば、UNIXにおけるプロセスには、一般ユーザ権限で動くものと特権で動くものがあります。もし、特権で動いているプロセスに脆弱性があった場合、不正な操作によりプロセスが持っている権限を取得されてしまう可能性があるのです。

この問題を解決する方法がケーパビリティです。特権をさらに細分化したケーパビリティと呼ばれる単位で取り扱えるようにし、プロセスに最小限のケーパビリティのみを与えて必要な処理のみを行わせるというものです。

この仕組みにより、もしプロセスに脆弱性がありそれが悪用されたとしても、そのプロセスが必要とする最小限のケーパビリティしか奪われないため、被害の範囲を狭めることが可能になります。プロセスが自らジェイルに入るようなものです。

ケーパビリティはこれまで、一部のセキュアOSでのみ使われていましが、最近の動きとして、Capsicumというケーパビリティ機構がFreeBSD 9に搭載されます。あらゆるシステムがインターネットに繋がれるようになる中、予期せぬ脆弱性からシステムを守るため、ケーパビリティのような保護機構の必要性が高まっているといえます。

企業内の情報システムにおけるアクセス制御
1990年ごろまで、軍事システムでMACが利用される一方、企業や行政組織ではMACではなくDACが適しているとされていました。しかし、DACには上述の脆弱性が存在します。企業や行政組織でITシステムが広く使われるようになるにつれ、それらの組織でも情報セキュリティがより重要となりました。

そんな中、DACの脆弱性を補いつつも、企業や行政組織でも運用が可能なアクセス制御の仕組みとして、ロールベースアクセス制御(Role-based Access Control; RBAC)が考えだされました。

DACやMACでは、アクセス制御の主体は個々のユーザやグループ、対象はファイルのような具体的なリソースでした。一方、RBACでは、パーミッションはユーザやグループではなく「役割(ロール)」について付与され、ユーザやグループはそれらの「役割」に紐づけられます。また、対象も具体的なリソースではなくそれらのリソースに対して一連の操作を行う「オペレーション」となります。

このように、「役割」や「オペレーション」といった、一段抽象度を上げた概念に対してアクセス制御を行うことで、RBACでは、企業および行政組織のポリシーや構造に合わせた柔軟な、しかし集中的なコントロールを可能としています。企業や行政組織での実運用が重視されているのがポイントです。


--

Compiling the Particle-based Simulation Description Language


On the former entry, I described simple N-Body simulation in the Particle-based Simulation Description Language as a embedded DSL and executed it with interpreter. In this entry, I introduce compiling and demonstrate it.

Implementation
The Particle-based Simulation Description Language is compiled to Haskell using Template Haskell, a GHC extension to Haskell that adds compile-time metaprogramming facilities.

With this transformation, a code corresponding to the N-Body simulation code written in plain Haskell on the former entry is produced, then it is compiled with GHC Haskell compiler.

In other words, the host language is the Particle-based Simulation Description Language and the target language is Haskell, though there is no clear line between the host and target languages because it is a embedded DSL.

Codes
Here the codes are, with the interpreter introduced on the former entry together, arranged as a module.

The structure of the module is as below:
- Examples/
- SimulationDSL/
  - SimulationDSL.hs
  - SimulationDSL/
    - Compiler/
    - Data/
    - Interpreter/
    - Language/
    - Test/

Execution
To execute, compile CompilerRun.hs in Examples directory and run the output file as below:
$ cd Examples
$ ghc -i../SimulationDSL --make -O2 CompilerRun.hs
$ ./CompilerRun

Performance
Comparing performance on three codes:
  • with compiler - CompilerRun
  • in plain Haskell - NBody
  • with interpreter - InterpreterRun
The performance:
$ time ./CompilerRun > /dev/null

real 0m0.949s
user 0m0.927s
sys 0m0.011s

$ time ./NBody > /dev/null

real 0m0.972s
user 0m0.950s
sys 0m0.011s

$ time ./InterpreterRun > /dev/null
real 0m2.932s
user 0m2.906s
sys 0m0.022s

As chart:


As intended, the same performance to the code in plain Haskell is given with compiler, which is 2x-3x faster than with interpreter.

Conclusion
In this entry, I introduced compiling the Particle-based Simulation Description Language to Haskell and showed improvement in performance of simple N-Body simulation.

While this time I chose Haskell as the target language for this embedded DSL, it is also possible to compile it to C adapting OpenMP or CUDA with parallel computation.


--

2011年12月13日火曜日

粒子ベースシミュレーション記述言語のコンパイル


前回のエントリでは、粒子ベースシミュレーション記述言語を使ってN-Body(多体問題)シミュレーションを記述し、それをインタプリタとして実行しました。

今回は、それをコンパイルして実行するようにしたので紹介します。

実装方針
実装の方法としては、Template Haskellを使ってDSLをHaskellのコードに変換しています。この展開によって、前回のエントリでHaskellで直接書いた場合と同様のコードを生成し、さらにghcでコンパイルしています。

つまり、ホスト言語が粒子ベースシミュレーション記述言語、ターゲット言語がHaskellということになります。もっとも、組み込みDSLなので明確な線引きがあるわけではありませんが。

コード
コードはこちらに置いてあります。前回のインタプリタとあわせて、モジュールとして整理しました。

モジュールの構成は以下のようになっています。
- Examples/          実行例をまとめています
- SimulationDSL/
  - SimulationDSL.hs   モジュール外へのエクスポート
  - SimulationDSL/
    - Compiler/        コンパイラに関するコード
    - Data/            基本的なデータ構造
    - Interpreter/     インタプリタに関するコード
    - Language/        シミュレーション記述言語の構文と解釈
    - Test/            テストを追加していく予定

実行方法
以下のように、ExamplesフォルダのCompilerRun.hsをコンパイルし、ファイルを実行します。
$ cd Examples
$ ghc -i../SimulationDSL --make -O2 CompilerRun.hs
$ ./CompilerRun

実行効率の確認
実行速度を、以下について比べてみます
  • コンパイラを使った場合 - CompilerRun
  • Haskellで直接書いた場合 - NBody
  • インタプリタを使った場合 - InterpreterRun

実行速度は以下のようになりました。
$ time ./CompilerRun > /dev/null

real 0m0.949s
user 0m0.927s
sys 0m0.011s

$ time ./NBody > /dev/null

real 0m0.972s
user 0m0.950s
sys 0m0.011s

$ time ./InterpreterRun > /dev/null
real 0m2.932s
user 0m2.906s
sys 0m0.022s

グラフにすると以下のようになります。



狙い通り、コンパイラを使った場合は、インタプリタのx2〜x3の速度、つまり、Haskellで直接書いた場合と同等の速さで動いています。

まとめ
このエントリでは、粒子ベースシミュレーション記述言語をHaskellにコンパイルしました。その結果、実行速度が改善されたことを示しました。

今回は組み込みDSLとしてターゲット言語をHaskellにしましたが、Cにコンパイルすることや、さらにOpenMPやCUDAに対応させて並列計算を可能にすることも検討しています。

また、HackageDBにAccelerateという配列をCUDAで計算するライブラリがあるようなので、これを使う方法もありそうです。

逆の方向として、粒子ベースシミュレーション記述言語の表現力を強化することも考えられます。
  • 境界条件の指定
  • 効率的な近傍探索のサポート
  • 例外処理
  • デバッガ
  • プロファイラ
  • 階層構造の導入(剛体シミュレーション)
  • ドメインの導入(固液連成)

ラグランジュ的表現とオイラー的表現
この言語はラグランジュ的な表現を記述することができます。一方、オイラー的な表現を記述することはできません。

有限差分法や有限要素法、あるいは格子ガス法や格子ボルツマン法といった、格子およびメッシュをベースにした表現を使ったシミュレーションを記述するには、また別の言語モデルを設計することになるでしょう。


関連エントリ
このエントリに関連するページです。

粒子法シミュレーション記述言語によるn-Body(多体問題)シミュレーション
粒子法シミュレーションを記述するための言語を設計中
【まとめ】埋め込みDSL関係の論文(1)
【まとめ】埋め込みDSL関係の論文(2)


まとめページ

粒子法(SPH)のプログラムを解説したシリーズです。ソースコードも公開しています。

粒子法(SPH)のプログラム一覧




シミュレーションの結果をレンダリングして作った動画です。流体シミュレーションや剛体シミュレーションの動画を見ることができます。

動画の一覧






--

2011年12月2日金曜日

N-Body simulation using the Particle Simulation Description Language


On the former entry (in Japanese), a free-fall simulation on point mass is shown as a starting point towards designing a language to describe particle simulation, or SPH.

On this entry, I introduce a improved Language and demonstrate N-Body Simulation on point mass using it.

Describing N-Body Simulation
N-Body simulation is represented in mathematical formula as below:



where xi, vi, ai and fi are position, velocity, acceleration and force on point mass i, respectively.

With the introduced language, as embedded DSL in Haskell, this simulation can be described as below:
nBody =
  do define         "x" (integral (var "v" <*> dt))
     define         "v" (integral (var "a" <*> dt))
     defineWithType "a" (var "f" </> m) ExpTypeVector
     define         "f"
                    (let r = norm (var' "x" <-> var "x")
                         k = m <*> m <*> g </> r </> r
                         n = (var' "x" <-> var "x") </> r
                     in sigma (k <*> n))
     initialConditionV "x" x0
  where dt = constantS 0.01
        m  = constantS 1
        g  = constantS 9.8
        x0 = V.fromList [ (0,0,0), (2,0,0), (0,2,0) ]

Explanation
define declaration defines an equation on physical amount on point mass i.

defineWithType declaration also defines an equation on physical amount, instructing type with it. When we use define declaration, the type of the equation we define is inferred with other equations. On the other hand, if the type can not be inferred, we must instruct it using defineWithType declaration. The types we can use are Scalar and Vector for now.

initialConditionV declaration is to give the initial condition of the physical amount defined with a "integral" expression. The last letter "V" means that the physical amount has Vector type. As the argument of it, an array of Vector is given as the initial condition of the position "x". Besides, the initial condition of the velocity "v" can be omitted, and an array of zero vector is given implicitly.

integral expression means integration, calculated explicitly inside the module.

var expression and var' expression are variables indicated by the symbol given as its argument. var' expression must be in a sigma expression. The difference in var and var' is described in the next paragraph.

sigma expression means summation of the calculated result of its operand expression on point mass j excluding itself. In the operand, var "x" means xi and var' "x" means xj.

dt, m and g are constant values lifted with the constantS function. The last letter "S" shows that the constant has Scalar type.

Execution
The nBody defined in the code can be evaluated as below:

main = mapM_ (printRow . flip machineRegisterValueV "x")
     $ take 100 $ runSimMachine nBody
* for the whole code, see Simulation.hs in GitHub

About performance efficiency
For now, this language is implemented as interpreter, so the performance of codes written in it is not very fast. I've compared it with the similar N-Body simulation code written in plain Haskell (see NBody.hs in GitHub). The result is below. Simulation is in the language and NBody in plain Haskell.

$ time ./Simulation > /dev/null

real    0m2.900s
user    0m2.869s
sys     0m0.020s

$ time ./NBody > /dev/null 

real    0m0.846s
user    0m0.829s
sys     0m0.011s

The program in the language is x1/3 - x1/4 as fast as in plain Haskell.

To improve the performance, using Template Haskell, we can compile, in the broad sense, the language to plain Haskell and make it work more efficiently. Also, compiling it to generate C or CUDA code would be pretty nice :)

--

2011年12月1日木曜日

粒子法シミュレーション記述言語によるn-Body(多体問題)シミュレーション


以前のエントリでは、粒子法シミュレーションを記述するための言語として、まず1つの質点についての自由落下を記述できるようにしてシミュレーションする例を示しました。

今回は、それを進めて、複数質点についてのn-Bodyシミュレーションを記述できるようにしたので紹介します。

n-Bodyシミュレーションの記述
n-Bodyシミュレーションを、数式で以下の様に表現した場合を考えます。



ここで、xi, vi, ai, fiは、それぞれ、ある質点iの位置、速度、加速度、力です。mは質点の質量、gは重力定数です。質点の質量はすべての質点について同じとします。

提案する言語を使うと、このシミュレーションを、以下のようにHaskellの組み込みDSLとして記述できます。
nBody =
  do define         "x" (integral (var "v" <*> dt))
     define         "v" (integral (var "a" <*> dt))
     defineWithType "a" (var "f" </> m) ExpTypeVector
     define         "f"
                    (let r = norm (var' "x" <-> var "x")
                         k = m <*> m <*> g </> r </> r
                         n = (var' "x" <-> var "x") </> r
                     in sigma (k <*> n))
     initialConditionV "x" x0
  where dt = constantS 0.01
        m  = constantS 1
        g  = constantS 9.8
        x0 = V.fromList [ (0,0,0), (2,0,0), (0,2,0) ]

記述の説明
"define"によって、ある質点iの物理量について方程式を定義しています。

"defineWithType"は、"define"と同じように物理量を定義しますが、併せて型を指定する点が異なります。"define"を使った場合には、その式の型は他の式から推論されますが、他の式から型を推論できない場合には、"defineWithType"を使って型も併せて指定します。現在使える型は、スカラーとベクトルの2種類です。

"initialConditionV"は、integralを使って定義された物理量の初期条件を与えるためのものです。最後の"V"は、その物理量の型がベクトルであることを示しています。引数として、ベクトルの配列を渡しています。速度vについては初期条件が省略されており、その場合は0ベクトルが使われます。

"integral"は、積分を表します。内部では陽解法で計算しています。

"var", "var'"は、引数で与えたシンボルで表される変数です。var'はsigmaの中でのみ使うことができます。varとvar'の違いについては、以下のsigmaの中で説明します。

"sigma"は、自身を除いた質点jについてオペランドの式を計算した値の合計です。オペランド中の var "x" がxiを、var' "x" がxjを表します。iが一定で、jをi以外の各質点について変えた場合の値を合計したものを返します。

dt、m、gといった定数は、constantS関数でリフトさせて使います。最後の"S"は、その定数がスカラーであることを示しています。

実行
上記で定義したnBodyを、以下のようにrunSimMachine関数に渡すことで計算します。
main = mapM_ (printRow . flip machineRegisterValueV "x")
     $ take 100 $ runSimMachine nBody
※コード全体についてはこちらを見てください

実行速度について
現時点では、この言語はインタプリタとして実装されているため、実行速度はあまり速くありません。

同じシミュレーションをHaskellで直接書いた場合(ソースコード)と速度を比較すると、以下のようになりました。SimLangがこの言語、NBodyがHaskellで直接書いた場合です。

$ time ./SimLang > /dev/null

real    0m2.900s
user    0m2.869s
sys     0m0.020s

$ time ./NBody > /dev/null 

real    0m0.846s
user    0m0.829s
sys     0m0.011s
Haskellで直接書いた場合に比べて、1/3〜1/4の速度になっています。

実行速度については、Temlate Haskellを使って、Haskellで直接書いた場合と同等のコードに(広義の)コンパイルすることで効率化できます。

課題
現時点での実装には、以下のような課題があります。
  • 0割算などの例外処理
  • デバッグのしやすさ、記述にエラーがあったときのメッセージの改善

ロードマップ
今後のロードマップとして以下のようなことを考えています。
  • より強力な型推論
  • Template Haskellによる(広義の)コンパイル
  • テスト
  • 設計の解説
  • 組み込みDSLや言語抽象についての解説
  • SPHの記述(分岐や近傍探索の導入)
  • 剛体シミュレーションの記述(階層表現の導入)
  • 固液連成シミュレーションの記述(ドメインの導入)
  • ベンチマーク

関連エントリ
このエントリに関連するページです。

粒子法シミュレーションを記述するための言語を設計中
【まとめ】埋め込みDSL関係の論文(1)
【まとめ】埋め込みDSL関係の論文(2)


まとめページ
粒子法(SPH)のプログラムを解説したシリーズです。ソースコードも公開しています。

粒子法(SPH)のプログラム一覧



シミュレーションの結果をレンダリングして作った動画です。流体シミュレーションや剛体シミュレーションの動画を見ることができます。

動画の一覧





--