月別アーカイブ: 2007年1月

GeForce8800 Vista ドライバ 100.54

やっと出ました!
ベータでない Vista 用ドライバです。
nVIDIA のサイトから落とせます。
http://www.nvidia.com/content/drivers/drivers.asp

GeForce8800 GTX/GTS が発売されて、
DirectX SDK の D3D10 も RTM して、
Windows Vista も発売されて、
Vista 用ドライバも出て、
ようやく Shader4.0 が普通に使えます。
長かった・・

追記: よく見たらベータでした。
失礼しました。

PS3 Linux ファームアップ 1.50

Playstation3 用に新しいファームウエア v1.50 が出ました。
前回が v1.32 だったので、結構大幅なバージョンアップでしょうか。
http://www.jp.playstation.com/ps3/update/

他のシステムの起動周りで何か変わってないか HDD をフォーマットして確認して
みました。残念ながら「PS3 Linux のちょっと残念な点」 で書いた点については
特に何も変わっていませんでした。

HDD分割も相変わらず 10GB のままで、
パーティションを切らないと他のシステムのインストールも優先起動システムの選択も
できませんでした。
次回の更新に期待です。

Direct3D もうひとつのユニファイド

従来相違があって不思議と互換性が無かった
頂点フォーマットとテクスチャフォーマットが D3D10 で統一されています。
これもシェーダーが統合されたおかげでしょうか。

Direct3D9 では例えば頂点だと

 FLOAT4   float×4
 FLOAT16_4  float(16bit)×4
 SHORT4N   short×4
 UBYTE4   byte×4 (a b g r)
 D3DCOLOR  byte×4 (a r g b)
 DEC3N    (10,10,10)
 
等の専用形式があり、テクスチャにも

 A32B32G32R32F
 A16B16G16R16F
 A16B16G16R16
 A8B8G8R8
 A8R8G8B8
 A2R10G10B10

があります。上にあげたものはほぼ似たようなフォーマットですが、
それ以外のものは互換性が無くアクセスのために専用のコードが必要でした。

Direct3D10 では VertexShader も PixelShader も同じ性能を持っているので、
アクセス可能な Buffer および ShadeResource のフォーマットが同じものになって
いるようです。
(2次元圧縮の BC(DXT) 形式は除く)

その代わり頂点フォーマットでも R G B A 表記になります。
よく見ると D3D9 の A B G R 表記と逆順です。
もちろん x y z w にあわせたためだと思われます。

xyzw と rgba の統合までの道のり

・D3D8 まで ARGB → D3D9 で ABGR 追加 → D3D10 で RGBA に変更

DirectX Direct3D 10 その2

●caps

caps 情報が必要なく、どのビデオカードでも同じように動作するのが 10 の特徴と
されています。ただ全く判断が必要必要ないかといえばそうではなくて、最低限
D3D10 が動くかどうかの判別は要ります。

DX5 あたりの時代のビデオカードだと、同じチップなのにメーカーによって結構
機能が違っていました。この違いはドライバによるもので、有効になっている機能
であっても実際はドライバ側のエミュレーションだったり他の機能の代用で実現
していたのかもしれません。

D3D10 ではどのメーカーのビデオカードでも同じ用に動作することが求められて
いるのですが、カードによって実装方法が異なっていることは考えられます。
機能が有効になっていてもビデオカードによってはエミュレーション実装で実は
重い、なんて状況にもしなるんだったら、事前に caps で判断して苦手な機能を
弾ける方がいいのかもしれません。
この辺はさまざまなビデオカードが出てくるまではまだなんともいえないところです。

●GeometryShader

GS はプリミティブ単位でシェーダーを実行することができますが、さらに隣接する
プリミティブの情報も参照することが可能です。これは ADJ 系の Topology データ
が必要です。隣接するプリミティブの情報を格納した IndexBuffer や頂点情報を
作成しておくわけです。(D3D10_PRIMITIVE_TOPOLOGY_TRIANGLELIST_ADJ 等)

なのであらかじめ対応するデータ形式への変換が要ります。頂点情報が重複するので、
本当に隣接情報を受け取りたいだけなら基本的に Indexed だけ使うことになるで
しょう。

例えば Triangle なら隣接込みで 6頂点入力になります。この余分な頂点情報にわざと
関係ないデータの頂点を与えることで、プリミティブ単位の追加情報領域として
活用することができそうです。ここに面法線とか面マテリアルとか入れて GS で
合成してあげるなど、かなり使い道がありそうですね。

なお GS で頂点の追加ができますが、試してみたところ一度の出力は最大 1024 要素
(スカラー)までに制限されるようです。例えば頂点形式が

px py pz nx ny nz tu tx

だと8要素なので、1024/8= 128個。つまり 128頂点まで出力することができます。
Triangle List だと 42個分になるでしょうか。

●resource

リソース周りの構造の理解も重要なポイントです。かなりのリソースが相互に流用
可能になっています。大きく分けると Buffer と ShaderResourceView の2種類です。
シェーダー側でも Buffer として読むか ShaderResourceView として読み込むかで
命令が違います。
ShaderResourceView であっても結局 Load() を使えば offset 指定で直接読めるので、
できることは cbuffer とあまり変わりません。VertexShader のみ cbuffer に
使えるリソースが ConstantBuffer だけに制限されています。

なので VertexShader だけは c0~ 系命令のアクセスが最適化されているけれど、
他の Shader では内部で Load() に置き換わっているのだろうか、とかちょっと
思いましたがそんなことは無いよいうです。

サンプルでもこの辺の比較プログラムが存在するので、どれくらいパフォーマンスに
差が出るかは試すことができます。

ShaderResourceView を使うと FORMAT によるさまざまな形式のデータを読み込め
ますがその代わり配列相当なのでフォーマットの異なる構造を作れません。
(tbuffer としてはアクセスできる)

Buffer を使うと構造を定義できますが、int, float, half 等の組み合わせなので
DXGI_FORMAT のような柔軟なデータ形式では直接宣言できなくなるようです。
(R8G8B8A8とか)
ちなみに subresource は ~DX9 でいう Surface のことのようです。

PS3 PPU は速いのか

PS3 の CPU である Cell は 3.2GHz で動いています。
Cell は複数の CPU core の集合体であり、中には PPU ×1 と SPU × 8個の
合計 9個の CPU core が含まれています。
ただし PS3 版 Cell では SPU の個数は 7個に減っており、合計 8 core です。

Cell が圧倒的なパワーを持つといわれているのはこの 8個 (7個) の SPU を持って
いるからです。SPU だけで 8個 (7個) の異なるプログラムを同時に走らせることが
できて、特に大量の浮動少数演算でその威力を発揮します。

これらの複数の SPU を統合整理するのが PPU の本来の用途だといわれています。

PPU 自体は 64bit の Power アーキテクチャで、PowerPC と完全に命令セットの
互換性があります。Linux を比較的容易に走らせられるのもこのためで、
PowerPC 用の一般のバイナリパッケージをインストールすることが可能です。

PowerPC G5 (970) が最大でも 2~2.5GHz 前後だったことを考えると、3.2GHz で
動作する Cell は PPU だけでもかなり高速な印象を与えます。でも実際はそれほど
でもありません。

もともと PowerPC は比較的効率の良い動作をする CPU でした。ヒット率の高い分岐
予測やアウトオブオーダー実行、レジスタのリネーミングなど、パイプラインの
無駄を高度なアルゴリズムで実行時に回避します。またそのような方向で進化して
きました。割と一定した速度の出る、どんなプログラムでも速度が落ちにくい CPU
アーキテクチャだという印象があります。

逆にそれが複雑な設計を招いているのか、比較的高クロック化の妨げになっていた
と考えられます。

Cell や Xbox360 の CPU で使われているこの新しい CPU Core は、これまでの
PowerPC の路線とは完全に逆向きの設計が行われているようです。

つまり、高クロック化の妨げとなるような複雑な設計はやめて、シンプルかつ小さな
core にすること。その代わり速度を高クロック化とマルチコア化で稼ぐというもの
です。

もちろんアウトオブオーダー実行できないと、パイプラインは依存が発生する
たびにスカスカになることが考えられます。これを回避するための方策として用い
られているのがマルチスレッド化です。PPU 1つでも、依存関係の無い 2つのスレッド
コンテキストを持つことで、パイプラインの無駄を回避しようというわけです。

Pentium4 の HyperThread と似たようなものといえるかもしれません。だけど HT
よりもスレッドへの依存はより積極的だと考えられます。

まとめるとこんな感じになります。

・高クロック化の妨げになる複雑な高度な回路は無くする
  → シンプルになるので高クロック化しやすい
  → 複雑な回路が減って面積が小さくなる
  → CPU の動作効率が落ちる

・落ちた動作効率をカバーするために次の新たな技術を導入する
  → 高クロック化
  → マルチコア化
  → マルチスレッド化

動作効率の低下は、CPU を複数積んで、クロックをあげることで回避せよと。
またパイプラインや演算ユニットの無駄はスレッドで回避しろと、ある意味力技に
見えます。

これらの仕様を考慮すると、CPU の癖というか性格としては、次のような傾向になる
ことが予想できます。

  ピーク性能は高いがかなりピーキーであり、性能を安定して引き出す
  のは難しい。

・コンパイラ依存率が非常に高くなる
  → 実行時の命令順最適化が行われないので、あらかじめコンパイル時に厳密に
   最適化しておく必要がある。そうでないと性能が出ない。

・スレッドを2本走らせないと100%性能を発揮できない
  → 別スレッドでパイプラインを埋めることが前提の設計なので、スレッド1本
   では無駄が発生している。

つまり同じ Power アーキテクチャといえども、これまでの PowerPC とは全く正反対
の性格付けになっているわけです。

ちなみに Xbox360 の CPU は、SPU が無い代わりに Cell でいう PPU 相当が 3つ
入っています。2次キャッシュの容量とベクトル専用命令の追加に違いがありますが、
CPU core そのものの特徴や傾向は全く同じだと考えられます。

Xbox360 の CPU も、100% の性能に近づけるためにはそれぞれの core で 2スレッド、
合計 6スレッド分のプログラムが必要だということです。

PS3 Linux で PPU が 2個の CPU に見えるのは、このように HT のような2本の
スレッドが走るためです。

PS3 Linux で実際に使ってみて結構動作が遅く感じるのは、もちろん Cell のうち
ごく一部しか活用されていないこともありますが、従来の PowerPC 用コンパイラ&
バイナリでは相性が悪いというのも若干影響しているかもしれません。