Pentium(R) III プロセッサと Pentium 4 プロセッサにおける ...AP-944...

37
AP-944 NURBS 曲面での高速化のパフォーマンス比較 01/10/30 1 Pentium ® III プロセッサと Pentium 4 プロセッサにおける NURBS (non-uniform rational B-spline) 曲面での 高速化のパフォーマンス比較 バージョン 2.0 2000 7 資料番号: 248609J-001

Transcript of Pentium(R) III プロセッサと Pentium 4 プロセッサにおける ...AP-944...

Page 1: Pentium(R) III プロセッサと Pentium 4 プロセッサにおける ...AP-944 NURBS曲面での高速化のパフォーマンス比較 01/10/30 1 Pentium® III プロセッサと

AP-944 NURBS曲面での高速化のパフォーマンス比較

01/10/30 1

Pentium® IIIプロセッサとPentium 4プロセッサにおける

NURBS (non-uniform rational B-spline) 曲面での高速化のパフォーマンス比較

バージョン 2.0

2000年 7月

資料番号: 248609J-001

Page 2: Pentium(R) III プロセッサと Pentium 4 プロセッサにおける ...AP-944 NURBS曲面での高速化のパフォーマンス比較 01/10/30 1 Pentium® III プロセッサと

AP-944 NURBS曲面での高速化のパフォーマンス比較

01/10/30 2

Page 3: Pentium(R) III プロセッサと Pentium 4 プロセッサにおける ...AP-944 NURBS曲面での高速化のパフォーマンス比較 01/10/30 1 Pentium® III プロセッサと

AP-944 NURBS曲面での高速化のパフォーマンス比較

01/10/30 3

【輸出規制に関する告知と注意事項】

本資料に掲載されている製品のうち、外国為替および外国為替管理法に定める戦略物資等または役務に該当するものについては、輸出または再輸出する場合、同法に基づく日本政府の輸出許可が必要です。また、米国産品である当社製品は日本からの輸出または再輸出に際し、原則として米国政府の事前許可が必要です。

【資料内容に関する注意事項】

・本ドキュメントの内容を予告なしに変更することがあります。

・インテルでは、この資料に掲載された内容について、市販製品に使用した場合の保証あるいは特別な目的に合うことの保証等は、いかなる場合についてもいたしかねます。また、このドキュメント内の誤りについても責任を負いかねる場合があります。

・インテルでは、インテル製品の内部回路以外の使用にて責任を負いません。また、外部回路の特許についても関知いたしません。

・本書の情報はインテル製品を使用できるようにする目的でのみ記載されています。

インテルは、製品について「取引条件」で提示されている場合を除き、インテル製品の販売や使用に関して、いかなる特許または著作権の侵害をも含み、あらゆる責任を負わないものとします。

・いかなる形および方法によっても、インテルの文書による許可なく、この資料の一部またはすべてを複写することは禁じられています。

本資料の内容についてのお問い合わせは、下記までご連絡下さい。

インテル株式会社 資料センタ

〒305-8603 筑波学園郵便局 私書箱115号

Fax: 0120-47-8832

*一般にブランド名または商品名は各社の商標または登録商標です。

Copyright © Intel Corporation 1999, 2000

Page 4: Pentium(R) III プロセッサと Pentium 4 プロセッサにおける ...AP-944 NURBS曲面での高速化のパフォーマンス比較 01/10/30 1 Pentium® III プロセッサと

AP-944 NURBS曲面での高速化のパフォーマンス比較

01/10/30 4

目次

1 はじめに .............................................................................................................................................6

2 NURBS曲面 .......................................................................................................................................6

2.1 NURBS曲面を使用するアプリケーション............................................................................7

2.2 NURBS曲面の基礎 ...................................................................................................................8

2.3 3次曲面テセレーションの実現 .............................................................................................12

2.3.1 計算式の改良 ..........................................................................................................................13

2.3.2 標準の Intel® x87 アーキテクチャを使用したコード........................................................13

2.3.3 SSEを使用したコード ..........................................................................................................14

2.3.4 ヒント......................................................................................................................................15

3 パフォーマンス ...............................................................................................................................17

3.1 パフォーマンス向上................................................................................................................17

3.2 考察 ...........................................................................................................................................17

4 結論 ...................................................................................................................................................18

5 コード例 ...........................................................................................................................................19

5.1 標準の Intel x87 アーキテクチャを使用したコード例 .......................................................19

5.1.1 任意の次元の NURBS曲面テセレーション .......................................................................19

5.1.2 ネストした内部ループによる 3次 NURBS曲面テセレーション ...................................21

5.1.3 内部ループを展開した 3次 NURBS曲面テセレーション ...............................................25

5.2 SSE 組み込み関数を使用したコード例................................................................................27

5.2.1 SSE 組み込み関数を使用した NURBS曲面テセレーション ...........................................27

5.2.2 SSE 組み込み関数を使用した 3次 NURBS曲面テセレーション....................................30

付録 A – 節点ベクトルと基底関数..................................................................................................... A-1

付録 B - パフォーマンス・データ.......................................................................................................B-1

パフォーマンス・データの改訂履歴..............................................................................................B-1

テスト・システム構成 .....................................................................................................................B-3

Page 5: Pentium(R) III プロセッサと Pentium 4 プロセッサにおける ...AP-944 NURBS曲面での高速化のパフォーマンス比較 01/10/30 1 Pentium® III プロセッサと

AP-944 NURBS曲面での高速化のパフォーマンス比較

01/10/30 5

改訂履歴

改訂 改訂履歴 日付

2.0 インテル® Pentium® 4プロセッサに関する改訂 2000年 7月

1.0 初版 1999年 9月

参考資料

このアプリケーション・ノートでは次の資料を参考にした。次の資料には、ここで取り上げた事項を理解するための有用な情報が含まれている。

Alan Watt著、『3D Computer Graphics』第 2版、Addison Wesley、1993年

James Foley、Andries van Dam、Steven Feiner、John Hughes著、『Computer Graphics: Principlesand Practice』第 2版、Addison Wesley、1990年

Les Piegl、Wayne Tiller著、『The NURBS Book』、Springer-Verlag、1997年

「Increasing the Accuracy of the Results from the Reciprocal and Reciprocal Square Root Instructionsusing the Newton-Raphson Method」、インテル・アプリケーション・ノート AP-803、資料番号:243637-001

Page 6: Pentium(R) III プロセッサと Pentium 4 プロセッサにおける ...AP-944 NURBS曲面での高速化のパフォーマンス比較 01/10/30 1 Pentium® III プロセッサと

AP-944 NURBS曲面での高速化のパフォーマンス比較

01/10/30 6

1 はじめに Intel® アーキテクチャ(IA)命令セットのためのストリーミング SIMD拡張命令(SSE)は、パックド、単精度、浮動小数点、単一命令複数データ(SIMD)演算を提供している。SSEを使用すると、3Dグラフィックス、リアルタイム物理計算、空間的(3D)オーディオでよく使用する演算を高速化できる。

このアプリケーション・ノートでは、リアルタイム・アプリケーションで表示するNURBS(non-uniform rational B-spline)曲面(パラメトリック曲面の一種)のテセレーション(細分割、三角形分割)を高速化する手法について説明する。NURBSは、CAD業界で曲線や曲面を記述する標準技法である。映画、デジタル・アート、そして最近では特にビデオ・ゲームの分野にお

けるオブジェクト・モデリングで、NURBSの使用が広がっている。

パラメトリック曲面は、一連の離散点(制御点と呼ぶ)と、一連の基底関数で定義される。パラメトリック曲面上の点は、制御点、基底関数、2つのパラメータ値を関数に引き渡して計算される。パラメトリック曲面を効率よくレンダリングするには、まず曲面をいくつかの離散ポリ

ゴンに分割して近似し、次に標準のポリゴン・レンダリング・パイプラインで各ポリゴンをレ

ンダリングする。曲面を一連の離散ポリゴンに分割する作業をテセレーションという。

NURBS曲面のテセレーションで重要な最適化対象は、次の 2つである。

• 基底関数の計算

• 曲面上の点の計算

このアプリケーション・ノートでは、基底関数の計算に関する最適化手法は取り上げない。基底関数はすでに計算され、メモリ内の配列に保存されているものとする。このアプリケーショ

ン・ノートでは、曲面上の点の計算に関する最適化手法だけを説明する。まず、NURBSの概要を説明し、SSEの利用方法など最適化手法を説明する。次に、Pentium® IIIプロセッサとPentium 4プロセッサでのパフォーマンスを比較する。最後に、すべての最適化手法を使用したソース・コード例を付録に示す。

2 NURBS曲面曲面は、ポリゴン・メッシュとして保存するより、パラメトリック曲面として保存する方が効

率的なことが多い。中精度から高精度で曲面を近似するには、パラメトリック曲面パッチの方

がポリゴン数が少なくて済む。現実世界のほとんどのオブジェクトは本質的に曲面で構成され

ているので、パラメトリック曲面(特に NURBS曲面)が現実オブジェクトのモデリングの標準になるのは当然である。現実オブジェクトをモデリングする CADアプリケーションでは、古くからパラメトリック曲面が多用されてきた。最近では、映画やアートにおける CG特殊効果でもパラメトリック曲面が使われ始めている。ビデオ・ゲームでパラメトリック曲面を使用し

てオブジェクト・モデリングを行うと、バーチャル・ワールド内のオブジェクトをより詳細に

表現でき、リアルなビデオ・ゲーム体験が可能になる。

Page 7: Pentium(R) III プロセッサと Pentium 4 プロセッサにおける ...AP-944 NURBS曲面での高速化のパフォーマンス比較 01/10/30 1 Pentium® III プロセッサと

AP-944 NURBS曲面での高速化のパフォーマンス比較

01/10/30 7

2.1 NURBS曲面を使用するアプリケーションこのアプリケーション・ノートが提供する情報は、ゲームのようなリアルタイム・アプリケー

ションでの NURBSレンダリングに最適である。現在のビデオ・ゲームは、各シーンのオブジェクトをポリゴン・モデルで表現しているものが多い。ポリゴン・モデルにかわって

NURBSモデルを使用する利点を次に説明する。

メモリ使用量

NURBSモデルを保存するのに要するメモリ・サイズは、モデルの詳細レベルに関係なく一定である。オブジェクトは表示する時点でテセレーションされるので、表示するときの詳細レベ

ルは、保存に必要なメモリ・サイズに影響しない。これに対して、ポリゴン・モデルは固定モ

デルなため、詳細レベルを高くすればするほど、それを保存するメモリ・サイズも大きくなる。

詳細レベル

NURBS曲面定義は、任意の精度で曲面を近似できる。すなわち、同じ制御点と基底関数を使用して、曲面を任意の詳細レベルで近似して表示できる。これに対して、ポリゴン・モデルは

詳細レベルを変えるたびに、別のポリゴン・メッシュが必要になる。ビデオ・ゲームのアー

ティストは、表示するときの詳細レベル数だけ、モデル・オブジェクトのインスタンスを作成

する必要がある。NURBSモデルならば、1つのモデルから複数の詳細レベルを導出できるので、アーティストは NURBSモデルを一度作成するだけでよい。詳細レベルを変えてもモデルを変える必要がないため、メモリ・パフォーマンスの向上にもつながる。

アニメーション

NURBSモデルの方がポリゴン・モデルよりアニメーション化に要する計算が少なくて済む。NURBSモデルを動かすには、NURBS曲面上の制御点を移動するだけでよい。詳細レベルが非常に低い場合を除き、NURBSモデルの制御点数は、ポリゴン・モデルの頂点の数より少ない。そのため、NURBSモデルで動かす方が、移動する点数が少ない。その上、NURBSモデルならば、表示の詳細レベルに関係なく、移動する点数が同じである。

CPU /メモリの傾向

PCの世界では、これまで CPUのクロック周波数の方が、メモリのクロック周波数より速く上昇してきた。CPUのクロック周波数は 1秒間に実行できる命令数に関係し、メモリのクロック周波数は 1秒間にメモリ・サブシステムからマイクロプロセッサに送り出すバイト数に関係する。今後も、CPUのクロック周波数の方が、メモリのクロック周波数より速く上昇すると予測される。そのため、今後 PCのリソースを有効利用するには、この傾向を考慮してプログラム設計を行う必要がある。

ポリゴン・モデルの方が NURBSモデルよりメモリ・リソースの消費量が多い(サイズが大きい)が、レンダリング中は NURBSモデルの方がポリゴン・モデルより CPUリソースを多く消費する(レンダリングの負荷が大きい)。現在市販されているビデオ・ゲームで表示されるよう

Page 8: Pentium(R) III プロセッサと Pentium 4 プロセッサにおける ...AP-944 NURBS曲面での高速化のパフォーマンス比較 01/10/30 1 Pentium® III プロセッサと

AP-944 NURBS曲面での高速化のパフォーマンス比較

01/10/30 8

な詳細レベルならば、ポリゴン・モデルの方が NURBSモデルより高速にレンダリングできる。ただし、キャッシュ効果(大きいポリゴン・モデルはキャッシュ内に収まらない)、およびよく知られた最適化手法(曲面テセレーションより先に NURBS曲面の制御点を変換する)により、高い詳細レベルでの NURBSモデルのレンダリングでも、ポリゴン・モデルのレンダリングと同等かそれ以上の速度で実行できるようになってきた。CPUのクロック周波数の方がメモリのクロック周波数より速く上昇する傾向を考えると、しだいに NURBSモデルをレンダリングする方がポリゴン・モデルをレンダリングするより効率がよく負荷も少なくなっていき、やがて

は今日の詳細レベルでも、NURBSモデルのレンダリングの方がポリゴン・モデルのレンダリングより負荷の少ない方法になると考えられる。

変換

次のセクションで説明するが、NURBS曲面は有理 Bスプラインである。有理曲線と有理曲面は、制御点の変形、拡大縮小、回転、透視変換を行っても不変である。非有理曲線と非有理曲

面は、制御点を透視変換すると変わってしまう。このことは、NURBS曲面の制御点への変形、拡大縮小、回転、透視変換は、NURBS曲面のテセレーションより前に実行できるのを意味する。したがって、変換後の制御点を使用して、NURBS曲面をテセレーションすると、変換後の曲面上の点が生成される。この方法は、テセレーションする曲面上の点数が、変換する制御

点数より多い場合に、大幅なパフォーマンス向上につながる。

2.2 NURBS曲面の基礎 NURBS曲面は、他のほとんどのパラメトリック曲面より滑らかで制御しやすい。3次曲面はたいていのアプリケーションに十分な滑らかさを持ち、曲面形状も制御しやすいので、ここで

は 3次曲面を使用する。また、3次曲面ならば、Intel Pentium IIIプロセッサで、4つのデータを同時処理する SIMD演算を利用しやすい。

曲面の次数は、曲面の基底関数の次数で決定される。3次曲面の基底関数の次数は 3である。3次基底関数の一般式は次のようになる。

b(u) = a3*u3 + a2*u2 + a1*u + a0

ここで、

b(u)は、基底関数

uは、基底関数を定義するパラメータ

a3、a2、a1、a0は、基底係数

基底関数の詳細については、このアプリケーション・ノートの付録「節点ベクトルと基底関数」を参照のこと。

このセクションでは、曲面に関する用語を理解しているものとして説明する。次に進む前に、

『Computer Graphics: Principles and Practice』第 2版のパラメトリック曲線とパラメトリック曲面に関する章を読まれることをお勧めする。

NURBS曲面は、非有理 Bスプラインと、有理および非有理ベジエ曲線/曲面を総合したものである。NURBS曲面は前述の曲面の特性をすべて備えると同時に、その限界をいくつか克服している。NURBS曲面で克服できる限界のうち最も重要なのが、曲面の連続性の制御しやすさ

Page 9: Pentium(R) III プロセッサと Pentium 4 プロセッサにおける ...AP-944 NURBS曲面での高速化のパフォーマンス比較 01/10/30 1 Pentium® III プロセッサと

AP-944 NURBS曲面での高速化のパフォーマンス比較

01/10/30 9

である。非一様 Bスプラインは、線状セグメントを導入せずに、始点、終点、制御点を補間できるが、一様 Bスプラインではそれができない。

NURBS曲面と通常の 3Dでは、光を当てたときの処理に 2つの大きな違いがある。変換後の曲面上の点を照明する場合は、制御点の変換と同じ変換を光に対して先に行う必要がある。これ

は比較的負荷の少ない操作だが、3Dジオメトリ・パイプラインでは一般にこのような方法は取らない。

もう 1つの違いは、面法線の計算にある。面法線は、照明の際に光に対する面の向きを判定するのに最もよく使用される。面上の点を計算するとき同様に、面法線も曲面に対して計算する

必要がある。面法線を計算する式は、面上の点を計算する式とよく似ている。面法線の場合は、

基底関数だけでなくその導関数を使用する点だけが異なる。この問題はこのアプリケーショ

ン・ノートの範囲外なので、詳細については参考資料を参照のこと。

制制御御点点

+

基基底底関関数数

= NNUURRBBSS局局面面

図1: 制御点と基底関数が NURBS曲面を定義する

パラメトリック曲面上の点は、図 1に示すように、一連の基底関数と一連の制御点を使用して計算する。バイ・パラメトリック関数は、2つのパラメータを持つ関数である。ここでは、uと vが 2つのパラメータである。NURBS曲面上の点を計算するバイ・パラメトリック関数を次に示す。

∑∑

∑∑

= =

= == p

i

q

jjiqjpi

p

iji

q

jqjpi

wvbub

PvbubvuS

0 0,,,

0,

0,,

)()(

)()(),(

ここで、

uと vは、曲面を定義する 2つのパラメータ

Page 10: Pentium(R) III プロセッサと Pentium 4 プロセッサにおける ...AP-944 NURBS曲面での高速化のパフォーマンス比較 01/10/30 1 Pentium® III プロセッサと

AP-944 NURBS曲面での高速化のパフォーマンス比較

01/10/30 10

pは、パラメータ uで定義される基底関数の次数 – 3次ならば 3

qは、パラメータ vで定義される基底関数の次数 – 3次ならば 3

jiP , = [xwi,j ywi,j zwi,j]は、重み付け制御点(wi,jは重み)

wi,jは制御点 i,jの重み

bi,p(u)は、パラメータ uの基底関数

bi,q(v)は、パラメータ vの基底関数

),( vuS = [x(u,v) y(u,v) z(u,v)]は、テセレーションした曲面上の点

ユーザは、 ),( vuS のすべてのコンポーネントを設定しなければならないので注意のこと。

v

u

0,0P

3,0P

0,3P

33,P

図2: 制御点グリッドとパラメータ u、v

図 2に、制御点と 2つのパラメータ u、vの関係を示す。各パラメータに関係づけられた制御点の個数は異なる可能性がある。図 2のグリッドは、4×4である。3次曲面の制御グリッドの場合、パラメータ u、vがそれぞれ 4つ以上の制御点を持つ必要がある。制御グリッドは、例えば 5×4、10×6、8×13などになる。

各パラメータ(uと v)が持つ制御点の個数と次数は同じとは限らない(pと qが等しいとは限らない)。また、パラメータはそれぞれ独自の基底関数セットを持つ。

制御点グリッドの大きさは、曲面を定義する 2つの項目に関係する。1つは、基底関数の次数である。もう 1つは、そのパラメータに関係づけられた節点ベクトルの節点値数である。節点ベクトルは、非降順の数値シーケンスである。基底関数は節点ベクトルから導出するので、節

点ベクトルは曲面の形状定義に関係する。節点ベクトルの詳細については、付録を参照のこと。

曲面の次数と、パラメータ uの節点値数および制御点数の関係を次に示す。

nu = mu – p ただし )1(*2)1( +≥+ pmu

ここで、

pは、u方向の曲面の次数

Page 11: Pentium(R) III プロセッサと Pentium 4 プロセッサにおける ...AP-944 NURBS曲面での高速化のパフォーマンス比較 01/10/30 1 Pentium® III プロセッサと

AP-944 NURBS曲面での高速化のパフォーマンス比較

01/10/30 11

nuは、u方向の制御点数

(mu+1)は、パラメータ uに関係づけられた節点ベクトル内の節点値数

同様に、パラメータ vについては次のようになる。

nv = mv – q ただし )1(*2)1( +≥+ qmv

ここで、

qは、v方向の曲面の次数

nvは、v方向の制御点数

(mv+1) は、パラメータ vに関係づけられた節点ベクトル内の節点値数

ここで、重要なのは次の 3点である。

• uと vは、それぞれ独自の節点ベクトルを持つ。

• uと vが持つ制御点の個数は異なる可能性がある。

• 曲面の次数と節点ベクトル内の節点数は、各パラメータに関係づけられた制御点数と関係がある。

テセレーション

NURBS曲面を、いくつかの離散ポリゴンに分割する操作をテセレーションという。曲面をテセレーションした後は、通常の 3Dジオメトリ・パイプラインでポリゴンをレンダリングできる。

このアプリケーション・ノートで行う一様テセレーションでは、局所的なカーブが考慮されない。一様テセレーションでは、パラメータ空間の規則的なグリッド点から、曲面上の(場合によっては非規則的な)グリッド点を生成し、そのグリッドで曲面が近似される。曲面のテセレーションを開始する前に、ユーザ(人間またはプログラム)が u、vの両パラメータに対してステップ・カウントと範囲を指定する。ステップ・カウントの逆数が、各パラメータのパラメト

リック・ステップ・サイズになる。一般に、パラメトリック範囲は[0,1]に設定する。ステップ・カウントを 10にすると、パラメトリック・ステップ・サイズは 1/10(すなわち 0.1)になる。その結果、{0.0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0}において基底関数が評価される。パラメータ u、vのステップ・カウントと範囲がどちらも 10と[0,1]に設定したとすると、曲面上の

点 ),( vuS は、次の uv座標で計算される。

{ (0.0,0.0), (0.0,0.1), (0.0,0.2), …, (0.0,0.8), (0.0,0.9), (0.0,1.0),

(0.1,0.0), (0.1,0.1), (0.1,0.2), …, (0.1,0.8), (0.1,0.9), (0.1,1.0),

(0.2,0.0), (0.2,0.1), (0.2,0.2), …, (0.2,0.8), (0.2,0.9), (0.2,1.0),

.

.

.

(0.8,0.0), (0.8,0.1), (0.8,0.2), …, (0.8,0.8), (0.8,0.9), (0.8,1.0),

(0.9,0.0), (0.9,0.1), (0.9,0.2), …, (0.9,0.8), (0.9,0.9), (0.9,1.0),

(1.0,0.0), (1.0,0.1), (1.0,0.2), …, (1.0,0.8), (1.0,0.9), (1.0,1.0) }

Page 12: Pentium(R) III プロセッサと Pentium 4 プロセッサにおける ...AP-944 NURBS曲面での高速化のパフォーマンス比較 01/10/30 1 Pentium® III プロセッサと

AP-944 NURBS曲面での高速化のパフォーマンス比較

01/10/30 12

このアプリケーション・ノートでは、非一様テセレーションではなく、一様テセレーションを選択した。アルゴリズムが比較的簡単なこと、一様テセレーションの方が SIMD処理に向いていることが理由である。非一様テセレーションの方が、NURBS曲面をより効果的にポリゴンで表現できるが、そのアルゴリズムは予測不可能な分岐を含む複雑なものになり、コーディン

グ方法によっては再帰計算が必要になる。実際のアプリケーションでは、メモリにも CPUにもオーバヘッドをかけずに、必要な詳細レベルを達成するために、一様テセレーションと非一

様テセレーションを組み合わせる必要があるのを注意してほしい。

次に示すのは、一様 NURBS曲面テセレーションを行う疑似コードである。

// algorithm for cubic NURBS surface tessellation.

float u = v = 0.0; // parametric values

float u_step_size = 1.0 / u_steps; // u direction parametric step

float v_step_size = 1.0 / v_steps; // v direction parametric step

// u_steps is the number of parametric steps to take in the u direction

for ( int i = 0; i <= u_steps; i++ )

{

// v_steps is the number of parametric steps to take in the v direction

// (u_steps*v_steps) is the number of surface points to evaluate

for ( int j = 0; j <= v_steps; j++ )

{

∑ ∑

∑ ∑=

= =

= =p

0i

q

0jji,qj,pi,

p

0iji,

q

0jqj,pi,

(v)w(u)bb

P(v)(u)bbv)(u,S

u += u_step_size;

}

v += v_step_size;

}

2.3 3次曲面テセレーションの実現このセクションでは、SSEによる最適化を行う場合と行わない場合の両方で、NURBS曲面を

一様分割するガイドラインを示す。どの方法も違いは、 ),( vuS の計算方法だけであるのに注意

のこと。

このアプリケーション・ノートに示すコード例はどれも、曲面上の点をメモリ内の配列に入れ

る。曲面上の点のデータ構造は例えば次のようになる。

struct SurfacePoint{

float x, y, z;

};

SSEを使用する場合は、次の制御点データ構造が必要になる。

struct ControlPoint {

float x, y, z, w;

Page 13: Pentium(R) III プロセッサと Pentium 4 プロセッサにおける ...AP-944 NURBS曲面での高速化のパフォーマンス比較 01/10/30 1 Pentium® III プロセッサと

AP-944 NURBS曲面での高速化のパフォーマンス比較

01/10/30 13

};

SSEを使用しない場合は、このデータ構造は必須ではないが、ここではどれも同じデータ構造を使用する。

節点ベクトルと節点スパンの詳細は、付録を参照のこと。どの方法でも、節点スパン・イン

デックスの配列を使用して、曲面計算に使用する制御点セットを決定する(曲面上の一点を計算するのに、(p+1)×(q+1)個の制御点セットを使用する)。節点スパン・インデックスの配列は、曲面テセレーションを実行する前に生成される。

2.3.1 計算式の改良

3つのコードはどれも前述の ),( vuS の改良バージョンを使用する。同次座標で曲面上の点を求

める計算式 ),( vuS は次のようになる。

∑ ∑== =

p

iji

q

jqjpiw PvbubvuS

0,

0,, )()(),(

),( vuSw は曲面上の点を同次座標で表したもので、そのコンポーネントは[X Y Z W]である。

非同次座標で表す曲面上の点 ),( vuS は、同次座標 ),( vuSw から次の式で求められる。

[ ]

==

WZ

WY

WXzyxvuS ),(

X、Y、Z、Wは、 ),( vuSw のコンポーネントである。

この計算式は、Intel® x87アーキテクチャでコーディングするのにも、SSEを使用してコーディングするのにも適切である。

この計算式の 3次元バージョンは、次数を 3に固定して次のようになる。

∑ ∑== =

3

0,

3

03,3, )()(),(

iji

jjiw PvbubvuS

[ ]

==

),(),(

),(),(

),(),(

),(,

,

,

,

,

,

vuSvuS

vuSvuS

vuSvuS

zyxvuSWW

ZW

WW

YW

WW

XW

この計算式は、元の計算式より SSEが使いやすいように改良されている。4つのコンポーネント(x, y, z, w)をすべて同時に計算する場合、SSEならば 4つの独立した算術演算をまとめて実行できる。

2.3.2 標準の Intel® x87アーキテクチャを使用したコード

このアプリケーション・ノートでは、Intel x87アーキテクチャを使用して、NURBS曲面テセレーションを行うコード例を 3つ示す。最初のコードは、任意の次元の NURBS曲面をテセレーションできる。このコードは、前セクションで説明した計算式をそのまま実行する。

),( vuSw の総和は、ネストした一組のループで計算する。

3次元に限定した 2つのコードの 1つは、最初のコードとよく似ている。テセレーションする曲面の次元を示す変数を 3にしただけである。

Page 14: Pentium(R) III プロセッサと Pentium 4 プロセッサにおける ...AP-944 NURBS曲面での高速化のパフォーマンス比較 01/10/30 1 Pentium® III プロセッサと

AP-944 NURBS曲面での高速化のパフォーマンス比較

01/10/30 14

3次元に限定した 2つのコードの違いは、 ),( vuSw の総和の計算方法である。最初のコードでは

ネストした一組のループで計算するが、2番目のコードでは内側のループを展開している。

この 3つのソース・コード例を付録に示す。

2.3.3 SSEを使用したコード

SSEを使用したコードは、Intel x87アーキテクチャを使用したコードから作成した。SSEを使用したコード例を 2つ示す。最初のコードは、Intel x87アーキテクチャを使用し、任意の次元の曲面を計算するコードから作成した。2番目のコードは、Intel x87アーキテクチャを使用し、内側ループを展開して 3次曲面を計算するコードから作成した。

SSEを使用したコードはどちらも、同次曲面上の点( ),( vuSw )を構成する 4つのコンポーネントを同時に計算する。各コンポーネントの計算式は次のようになる。

∑ ∑== =

3

0

3

03,3, )()(

i ji,jji xvbubX

∑ ∑== =

3

0

3

03,3, )()(

i ji,jji yvbubY

∑ ∑== =

3

0

3

03,3, )()(

i ji,jji zvbubZ

∑ ∑== =

3

0

3

03,3, )()(

i ji,jji wvbubW

ここで、

X、Y、Z、Wは、同次空間、すなわち ),( vuSw における曲面上の点の 4つのコンポーネント

この 4つの計算式は XMMレジスタですべて同時に計算される。計算が完了すると、XMMレジスタの各要素に、 ),( vuSw のコンポーネントが 1つずつ入る。1つの要素に X、1つの要素にY、同様に ZとWが入っている。

同次曲面上の点(上記の xw、yw、zw)は、X、Y、Zの各コンポーネントに 1/Wを掛けることで、非同次曲面上の点に変換される。ここに、SSEによる最適化の可能性がある。まず、X、Y、Z、Wが入っているレジスタのコピーを作成する。次に、コピー全体にWをブロードキャストして、各要素にWの値が入るようにする。逆数近似命令(rcpps)を使用して、このレジスタの各要素で 1/Wを計算する。最後に、このレジスタの内容を、X、Y、Z、Wが入っているレジスタの内容と掛け合わせる。その結果として、非同次空間における曲面上の点が得られる。SSEの組み込み関数を使用して、この計算を行う疑似コードを次に示す。

// pseudo-code for calculating non-homogeneous surface point from

// the homogeneous surface point

__m128 XYZW, rcpW, xyz1; // XYZW = [ W Z Y X ]

rcpW = _mm_shuffle_ps(XYZW, XYZW, 0xff); // rcpW = [ W W W W ]

rcpW = _mm_rcp_ps(rcpW); // rcpW = [1/W 1/W 1/W 1/W]

xyz1 = _mm_mul_ps(rcpW, XYZW); // xyz1 = [ 1 z y x ]

Page 15: Pentium(R) III プロセッサと Pentium 4 プロセッサにおける ...AP-944 NURBS曲面での高速化のパフォーマンス比較 01/10/30 1 Pentium® III プロセッサと

AP-944 NURBS曲面での高速化のパフォーマンス比較

01/10/30 15

計算した x、y、zは、曲面上の点を入れる配列に保存する必要がある。xと yを保存するには、_mm_storel_pi()組み込み関数を使用できる。zを保存するには、_mm_movehl_ps()組み込み関数を使用して、zをレジスタの最下位要素(スカラ要素)に移動してから、_mm_store_ss()を使用して、スカラ保存を行う。この操作を行う疑似コードを次に示す。

// pseudo-code for storing non-homogeneous surface point to

// surface point array

SurfacePoint *S; // pointer to current point in surface point array

// struct SurfacePoint { x, y, z };

_mm_storel_ps((__m64*)S, xyz1);

_mm_store_ss(S->z, _mm_movehl_ps(xyz1, xyz1));

任意の次元に対応するコードでは、 ),( vuSw の総和をネストした 2つのループで計算している。3次曲面に限定したコードでは、内側ループが展開されている。これが、SSEを使用した 2つのコードの最も大きな違いである。この 2つのコード例も付録に示す。

2.3.4 ヒント

逆数近似

同次コンポーネントWの逆数(1/W)を計算するときは、精度よりパフォーマンスを優先している。1/Wの計算では、SSEの除算命令 divpsではなく、逆数近似の SSE rcppsを使用する。逆数近似命令は、1/xの演算を近似する。divpsのかわりに rcppsを使用すると、除算のパフォーマンスが大きく向上する。divps命令は rcpps命令と比べて、レイテンシが非常に長くスループットが悪い。rcppsの誤差は 1.5 * 2-12である。それ以上の精度が必要な場合は、divpsではなくNewton-Raphsonアルゴリズムを使用する。Newton-Raphsonアルゴリズムの詳細については、参考資料を参照のこと。

データ・アライメント

アライメントされているデータのロードには、movaps命令を使用する。アライメントされていないデータのロードには、movups命令を使用する。アライメントされたデータのロードの方が、アライメントされていないデータのロードより高速である。入力データを 16バイト境界にアライメントすると、アライメント済みロード命令が使用できる。パフォーマンスを向上

させるには、制御点配列と基底関数配列をアライメントするとよい。制御点のデータ構造は

16バイト(4バイトの浮動小数点が 4つ)である。サイズが 16バイトのデータ構造は、SSEの利用に最適である。このようなデータ構造ならば、最初の配列要素を 16バイト境界にアライメントすると、配列内のすべての要素が 16バイト境界にアライメントされる。その結果、配列内のデータはすべて、アライメント済みメモリ・アクセスが可能になる。ハードウェアは、ア

ライメントしたメモリ・アクセスのパフォーマンスを向上させる特別なサポートを行う。

_mm_load_ps()や_mm_store_ps()のような組み込み関数は、アライメント済みメモリ・アクセスに対するハードウェア・サポートを利用している。

基底値は、基底関数を計算して得られた値である。基底値は、 ),( vuS の計算に使用される。基

底値配列をアライメントすれば、基底値が必要なときにアライメント済みロードを使用できる。

uおよび v方向に曲面を計算するときの基準とするパラメトリック値は、それぞれ 4つの基底

Page 16: Pentium(R) III プロセッサと Pentium 4 プロセッサにおける ...AP-944 NURBS曲面での高速化のパフォーマンス比較 01/10/30 1 Pentium® III プロセッサと

AP-944 NURBS曲面での高速化のパフォーマンス比較

01/10/30 16

値を持つ。基底値は float 型なので、4つの基底値を 16バイトのデータ構造で保持できる。制御点配列と同様に、基底値配列も最初の要素をアライメントすれば、配列内のすべての要素

がアライメントされる。その結果、基底値配列の要素については、常にアライメント済みメモ

リ・アクセスを使用できる。

同次曲面上の点の 4つのコンポーネント(X、Y、Z、W)を同時に計算することで、XMMレジスタの 4つの要素を最大限に活用できる。曲面上の点を非同次座標に変換する前に ),( vuSw を

計算すれば、3つではなく 4つのコンポーネントを計算するので、曲面上の点を計算で XMMレジスタの 4つの要素をすべて活用できる。

Page 17: Pentium(R) III プロセッサと Pentium 4 プロセッサにおける ...AP-944 NURBS曲面での高速化のパフォーマンス比較 01/10/30 1 Pentium® III プロセッサと

AP-944 NURBS曲面での高速化のパフォーマンス比較

01/10/30 17

3 パフォーマンス曲面上の点の計算は明らかに負荷が大きいので、計算する点の個数を最小にするように常に注

意する必要がある。すなわち、求められる詳細レベルで曲面を表示するのに必要な最小限の個

数しか計算しないようにする。ユーザまたは開発者は、この個数をビジュアルに決定する。

このアプリケーション・ノートでは、曲面上の一点を計算するのに要する時間をパフォーマン

スの指標とした。それには、まず曲面計算に要したトータルの時間(曲面上の点をすべて計算するのに要した時間)を測定する。次に、トータルの時間を、計算した曲面上の点の個数で割り、一点の計算に要した平均時間を求める。パフォーマンス比較は、曲面上の一点を計算する

のに要した時間で行った。

曲面の特性とテセレーションの度合いにより、パフォーマンスに違いがでた。曲面の詳細レベ

ルを上げるには、曲面定義により多くの制御点を追加する必要がある。すなわち、曲面を表示

するときの詳細レベルを高くするほど、曲面定義により多くの制御点が必要となる。曲面定義

が持つ制御点数は、曲面テセレーションのパフォーマンスに影響する。曲面定義が持つ制御点

数が多いほど、曲面テセレーションのパフォーマンスは低下する。曲面定義を保持するのに必

要なメモリが増えるし、曲面上の点の計算にどの制御点セットを使用するか判定するロジック

も複雑になるからである。アーティストは、この関係に常に意識し、必要最低限の制御点を使用して、製作するオブジェクトを定義する必要がある。

テセレーションの度合いによっても、パフォーマンスは変わってくる。一般に、曲面上の一点

当たりのパフォーマンスは、計算する点数が多いほど向上する。これには、いくつかの理由が

ある。まず、曲面上の点をいくつ計算するかに関係なく、同じ量のデータがキャッシュにロー

ドされる。メモリ・ロードのオーバヘッドは、曲面上の点を 100個計算するときも、1000個計算するときもほぼ同じである。

次に、曲面上のより多くの点を計算する方が、分岐予測の精度が向上する。曲面上の点を多く

計算するほど、分岐 1つ当たりに実行される命令数が増加するので、実際に命令を実行している時間の方が、分岐予測誤りから回復する時間より多くなる。

3.1 パフォーマンス向上

SSEを使用して 3次曲面をテセレーションするコードが最速だった。SSEを使用して任意の次元の曲面をテセレーションするコードより、パフォーマンスははるかに高かった。SSEを使用する 2つのコードは、Intel x87アーキテクチャを使用するコードよりはるかに高速だった。Pentium 4プロセッサを Pentium IIIプロセッサと比較すると、どのコードもほぼ同程度のパフォーマンス向上が見られた。

3.2 考察

NURBS曲面テセレーションのパフォーマンスは、コーディング方法によって大きく変わる。NURBS曲面テセレーションでは、常に開発時間対パフォーマンスというトレードオフがある。一般に、アルゴリズムをアセンブリ言語でコーディングすると、Cや C++のような高級言語でコーディングするより時間がかかる。SSEを使用するコードはどれも、Intel® C/C++コンパイラが提供する SSEの組み込み関数を使用する。SSEの組み込み関数は、アセンブリ・コードとCの中間の環境を提供する。SSEの組み込み関数は、SSEへの直接インターフェイスを提供す

Page 18: Pentium(R) III プロセッサと Pentium 4 プロセッサにおける ...AP-944 NURBS曲面での高速化のパフォーマンス比較 01/10/30 1 Pentium® III プロセッサと

AP-944 NURBS曲面での高速化のパフォーマンス比較

01/10/30 18

る C++ APIである。SSEの組み込み関数を使用すると、NURBS曲面テセレーションをアセンブリ・コードで実行するのとほぼ同等のパフォーマンスが得られた。このことは、SSE組み込み関数を使用して NURBS曲面テセレーションを行うコードをコンパイルして生成されたアセンブリ・コードからも確認された。

Intel x87アーキテクチャまたは SSEを使用したコードのいくつかで、NURBS曲面の次数を 3次に限定したのは、一般性とパフォーマンスのトレードオフからである。どの曲面も、3次のNURBS曲面で定義できる。それ以上の連続性が必要ならば、アーティストはより高次の曲面を使用して描画し、後処理の際に高次の曲面を、同じ形状を持ついくつかの 3次曲面に分割すればよい。このような後処理の詳細については、Pieglと Tillerによる『The NURBS Book』(「参考資料」を参照)を参照してほしい。

4 結論NURBS曲面の次数を 3に限定すると、次の 2つが可能になり、曲面テセレーションのパフォーマンスが向上する。

• 曲面テセレーションを行う最も内側のループから分岐をなくす。

• SSEを使用するために基底値をアライメントする。

SSEは、NURBS曲面を表示するアプリケーションのパフォーマンスを向上させる機能を持つ。パフォーマンス向上に貢献する SSEの機能としては、次のものがある。

• SSEの SIMD機能。

• レイテンシが長い divps命令のかわりに rcpps命令を使用できる。divps命令と比較したときの誤差の増大は許容範囲である。

• 制御点と基底関数値に対するアライメント済みメモリ・アクセス。

• Intel x87アーキテクチャを使用するコードと比較すると、実行する命令総数が少なくなる。

Pentium 4プロセッサでは、Pentium IIIプロセッサと比べて大きなパフォーマンス向上が見られた。パフォーマンス向上の第一の理由は、マイクロプロセッサの周波数が高いことである。こ

のアプリケーション・ノートに示す曲面テセレーションのコードはどれも、プロセッサの周波

数にほぼ比例するパフォーマンスが測定された。

Page 19: Pentium(R) III プロセッサと Pentium 4 プロセッサにおける ...AP-944 NURBS曲面での高速化のパフォーマンス比較 01/10/30 1 Pentium® III プロセッサと

AP-944 NURBS曲面での高速化のパフォーマンス比較

01/10/30 19

5 コード例このセクションに示すコード例には、次のマクロ定義が必要である。

#define CUBIC_DEGREE 3

#define CUBIC_ORDER 4

また、次のコードでは、次の構造体が定義されている必要がある。

struct SurfacePoint {

float x, y, z;

};

5.1 標準の Intel x87アーキテクチャを使用したコード例次の Cコード例は、標準の Intel x87アーキテクチャの浮動小数点演算を使用して、NURBS曲面の一様テセレーションを実行する。

5.1.1 任意の次元の NURBS曲面テセレーション

次の Cコードは、任意の次元の NURBS曲面に対して一様テセレーションを実行する。

void TessellateSurfaceC(

SurfacePoint surface_points, // output surface points

unsigned int u_step_count, // steps to take in u direction

unsigned int v_step_count, // steps to take in v direction

unsigned int u_degree, // degree of basis values in u direction

unsigned int v_degree, // degree of basis values in v direction

float *u_basis_values, // values from u basis functions

float *v_basis_values, // values from v basis functions

unsigned int u_knot_spans, // knot span indices for u values

unsigned int v_knot_spans) // knot span indices for v values

{

SurfacePoint *sp = surface_points;

float *u_basis = u_basis_values;

unsigned int *u_knot_span = u_knot_span_indices;

/* for each parametric value in the u direction */

for ( unsigned int u_index = 0; u_index < u_step_count; u_index++ )

{

float *v_basis = v_basis_values;

unsigned int *v_knot_span = v_knot_spans;

/* for each parametric value in the v direction */

for ( unsigned int v_index = 0; v_index < v_step_count; v_index++ )

{

/* this is a surface point in homogeneous space */

Page 20: Pentium(R) III プロセッサと Pentium 4 プロセッサにおける ...AP-944 NURBS曲面での高速化のパフォーマンス比較 01/10/30 1 Pentium® III プロセッサと

AP-944 NURBS曲面での高速化のパフォーマンス比較

01/10/30 20

/* it holds intermediate values until the end of the function */

struct HomogeneousSurfacePoint

{

float X, Y, Z, W;

};

HomogeneousSurfacePoint hsp;

hsp.X = hsp.Y = hsp.Z = hsp.W = 0.0f;

/*

Step through the control points row-by-row, column-by-

column. Here we calculate where the beginning of the first row

for the outer loop. This pointer (cp_row) is incremented one

row at a time.

*/

ControlPoint *cp_row = &control_points[

((*u_knot_span)-u_degree) * v_control_point_count +

((*v_knot_span)-v_degree)];

/* calculate the surface point in homogeneous space */

for ( unsigned int i = 0; i <= u_degree; i++ )

{

/* current control point is the first in the current row */

ControlPoint *cp = cp_row;

/* reset temp to zero */

HomogeneousSurfacePoint temp;

temp.X = temp.Y = temp.Z = temp.W = 0.0f;

/* inner summation */

for ( unsigned int j = 0; j <= v_degree; j++ )

{

temp.X += v_basis[j] * cp->x;

temp.Y += v_basis[j] * cp->y;

temp.Z += v_basis[j] * cp->z;

temp.W += v_basis[j] * cp->w;

/* increment to the next control point in the row */

cp++;

}

/* outer sum */

hsp.X += u_basis[i] * temp.X;

hsp.Y += u_basis[i] * temp.Y;

hsp.Z += u_basis[i] * temp.Z;

hsp.W += u_basis[i] * temp.W;

Page 21: Pentium(R) III プロセッサと Pentium 4 プロセッサにおける ...AP-944 NURBS曲面での高速化のパフォーマンス比較 01/10/30 1 Pentium® III プロセッサと

AP-944 NURBS曲面での高速化のパフォーマンス比較

01/10/30 21

/* increment to the next row of control points */

cp_row += v_control_point_count;

}

/* bring homogeneous point into nonhomogeneous space */

hsp.W = 1.0f / hsp.W;

sp->x = hsp.X * hsp.W;

sp->y = hsp.Y * hsp.W;

sp->z = hsp.Z * hsp.W;

/* increment to next surface point in surface point array */

sp++;

/* increment to next set of v basis values */

v_basis += (v_degree+1);

/* increment to the next v knot span index */

v_knot_span++;

}

/* increment to next set of u basis values */

u_basis += (u_degree+1);

/* increment to the next u knot span index */

u_knot_span++;

}

}

5.1.2 ネストした内部ループによる 3次 NURBS曲面テセレーション

次の Cコードは、3次 NURBS曲面に対して一様テセレーションを実行する。

void TessellateCubicSurfaceC(

SurfacePoint surface_points, // output surface points

unsigned int u_step_count, // steps to take in u direction

unsigned int v_step_count, // steps to take in v direction

unsigned int u_degree, // degree of basis values in u direction

unsigned int v_degree, // degree of basis values in v direction

float *u_basis_values, // values from u basis functions

float *v_basis_values, // values from v basis functions

unsigned int u_knot_spans, // knot spans for u values

unsigned int v_knot_spans) // knot spans for v values

{

if ( u_degree != CUBIC_DEGREE || v_degree != CUBIC_DEGREE )

{

Page 22: Pentium(R) III プロセッサと Pentium 4 プロセッサにおける ...AP-944 NURBS曲面での高速化のパフォーマンス比較 01/10/30 1 Pentium® III プロセッサと

AP-944 NURBS曲面での高速化のパフォーマンス比較

01/10/30 22

exit 0;

}

SurfacePoint *sp = surface_points; // current output surface point

float *u_basis = u_basis_values; // current set of 4 u basis values

unsigned int *u_knot_span = u_knot_spans; // current u knot span index

/* for each parametric value in the u direction */

for ( unsigned int u_index = 0; u_index < u_step_count; u_index++ )

{

float *v_basis = v_basis_values; // current v basis values

unsigned int *v_knot_span = v_knot_spans; // current v knot span idx

/* for each parametric value in the v direction */

for ( unsigned int v_index = 0; v_index < v_step_count; v_index++ )

{

/* this is a surface point in homogeneous space */

/* it holds intermediate values until the end of the function */

struct HomogeneousSurfacePoint

{

float X, Y, Z, W;

};

HomogeneousSurfacePoint hsp;

hsp.X = hsp.Y = hsp.Z = hsp.W = 0.0f;

/* step through control points row-by-row, column-by-column */

/* here we calculate where the beginning of the first row is */

/* in the outer summation loop this pointer is incremented by

one row of control points at a time */

ControlPoint *cp_row = &control_points[

((*u_knot_span)-CUBIC_DEGREE) * v_control_point_count +

((*v_knot_span)-CUBIC_DEGREE)];

/* calculate the surface point in homogeneous space */

for ( unsigned int i = 0; i <= CUBIC_DEGREE; i++ )

{

/* current control point is the first in the current row */

ControlPoint *cp = cp_row;

/* reset temp to zero */

HomogeneousSurfacePoint temp;

temp.X = temp.Y = temp.Z = temp.W = 0.0f;

Page 23: Pentium(R) III プロセッサと Pentium 4 プロセッサにおける ...AP-944 NURBS曲面での高速化のパフォーマンス比較 01/10/30 1 Pentium® III プロセッサと

AP-944 NURBS曲面での高速化のパフォーマンス比較

01/10/30 23

/* inner summation */

for ( unsigned int j = 0; j <= CUBIC_DEGREE; j++ )

{

temp.X += v_basis[j] * cp->x;

temp.Y += v_basis[j] * cp->y;

temp.Z += v_basis[j] * cp->z;

temp.W += v_basis[j] * cp->w;

/* increment to the next control point in the row */

cp++;

}

/* outer summation */

hsp.X += u_basis[i] * temp.X;

hsp.Y += u_basis[i] * temp.Y;

hsp.Z += u_basis[i] * temp.Z;

hsp.W += u_basis[i] * temp.W;

/* increment to the next row of control points */

cp_row += v_control_point_count;

}

/* bring control point into non-homogeneous space */

hsp.W = 1.0f / hsp.W; // calculate reciprocal W

sp->x = hsp.X * hsp.W;

sp->y = hsp.Y * hsp.W;

sp->z = hsp.Z * hsp.W;

/* increment to the next output surface point */

sp++;

/* increment to the next set of v basis values */

v_basis += CUBIC_ORDER;

/* increment to the next v knot span index */

v_knot_span++;

}

/* increment to the next set of u basis values */

u_basis += CUBIC_ORDER;

/* increment to the next u knot span index */

Page 24: Pentium(R) III プロセッサと Pentium 4 プロセッサにおける ...AP-944 NURBS曲面での高速化のパフォーマンス比較 01/10/30 1 Pentium® III プロセッサと

AP-944 NURBS曲面での高速化のパフォーマンス比較

01/10/30 24

u_knot_span++;

}

}

Page 25: Pentium(R) III プロセッサと Pentium 4 プロセッサにおける ...AP-944 NURBS曲面での高速化のパフォーマンス比較 01/10/30 1 Pentium® III プロセッサと

AP-944 NURBS曲面での高速化のパフォーマンス比較

01/10/30 25

5.1.3 内部ループを展開した 3次 NURBS曲面テセレーション

次の Cコードは、3次 NURBS曲面に対して一様テセレーションを実行する。最も内側ループで総和を求める部分が展開されている。

void TessellateCubicSurfaceC_Unrolled(

SurfacePoint surface_points, // output surface points

unsigned int u_step_count, // steps to take in u direction

unsigned int v_step_count, // steps to take in v direction

unsigned int u_degree, // degree of basis values in u direction

unsigned int v_degree, // degree of basis values in v direction

float *u_basis_values, // values from u basis functions

float *v_basis_values, // values from v basis functions

unsigned int u_knot_spans, // knot spans for u values

unsigned int v_knot_spans) // knot spans for v values

{

if ( u_degree != CUBIC_DEGREE || v_degree != CUBIC_DEGREE )

{

exit 0;

}

SurfacePoint *sp = surface_points; // current output surface point

float *bu = u_basis_values;// current set of u basis values

unsigned int *u_knot_span = u_knot_spans; // current u knot span index

/* for each parametric value in the u direction */

for ( unsigned int u_index = 0; u_index < u_step_count; u_index++ )

{

float *bv = v_basis_values; // current set of v basis values

unsigned int *v_knot_span = v_knot_spans; // current v knot span idx

/* for each parametric value in the v direction */

for ( unsigned int v_index = 0; v_index < v_step_count; v_index++ )

{

/* this is a surface point in homogeneous space */

/* it holds intermediate values until the end of the function */

struct HomogeneousSurfacePoint

{

float X, Y, Z, W;

};

HomogeneousSurfacePoint hsp;

hsp.X = hsp.Y = hsp.Z = hsp.W = 0.0f;

Page 26: Pentium(R) III プロセッサと Pentium 4 プロセッサにおける ...AP-944 NURBS曲面での高速化のパフォーマンス比較 01/10/30 1 Pentium® III プロセッサと

AP-944 NURBS曲面での高速化のパフォーマンス比較

01/10/30 26

ControlPoint *cp = &control_points[

((*u_knot_span)-CUBIC_DEGREE) * v_control_point_count +

((*v_knot_span)-CUBIC_DEGREE)];

#define HOMOGENEOUS_SURFACE_POINT(idx) \

hsp.X += bu[idx]*(bv[0]*cp[0].x+bv[1]*cp[1].x+bv[2]*cp[2].x+bv[3]*cp[3].x);\

hsp.Y += bu[idx]*(bv[0]*cp[0].y+bv[1]*cp[1].y+bv[2]*cp[2].y+bv[3]*cp[3].y);\

hsp.Z += bu[idx]*(bv[0]*cp[0].z+bv[1]*cp[1].z+bv[2]*cp[2].z+bv[3]*cp[3].z);\

hsp.W += bu[idx]*(bv[0]*cp[0].w+bv[1]*cp[1].w+bv[2]*cp[2].w+bv[3]*cp[3].w);\

cp += v_control_point_count;

HOMOGENEOUS_SURFACE_POINT(0)

HOMOGENEOUS_SURFACE_POINT(1)

HOMOGENEOUS_SURFACE_POINT(2)

HOMOGENEOUS_SURFACE_POINT(3)

// bring the point into nonhomogeneous space

hspW = 1.0f / hsp.W;

sp->x = hsp.X * hsp.W;

sp->y = hsp.Y * hsp.W;

sp->z = hsp.Z * hsp.W;

// increment to the next output surface point

sp++;

// increment to the next set of u basis values

bv += CUBIC_ORDER;

// increment to the next v knot span index

v_knot_span++;

}

// increment to the next set of v basis values

bu += CUBIC_ORDER;

// increment to the next u knot span index

u_knot_span++;

}

}

Page 27: Pentium(R) III プロセッサと Pentium 4 プロセッサにおける ...AP-944 NURBS曲面での高速化のパフォーマンス比較 01/10/30 1 Pentium® III プロセッサと

AP-944 NURBS曲面での高速化のパフォーマンス比較

01/10/30 27

5.2 SSE組み込み関数を使用したコード例このセクションに示す Cコードは、SSEを使用して、NURBS曲面の一様テセレーションを行う方法を示す。

まず最初に、次のマクロを定義する必要がある。

/* checks to see if pointer ‘p’ is aligned to a 16 byte boundary */

#define IS_ALIGNED_16(p) (((DWORD)(p))%16 == 0)

/* the number of coordinates per surface point (x, y, z) */

#define COORD_PER_SURF_PT 3

5.2.1 SSE組み込み関数を使用した NURBS曲面テセレーション

次の Cコードは、SSE組み込み関数を使用して、任意の次数の NURBS曲面に対して一様テセレーションを実行する。

void TessellateSurfaceSSE(

SurfacePoint surface_points, // output surface points

unsigned int u_step_count, // steps to take in u direction

unsigned int v_step_count, // steps to take in v direction

unsigned int u_degree, // degree of basis values in u direction

unsigned int v_degree, // degree of basis values in v direction

float *u_basis_values, // values from u basis functions

float *v_basis_values, // values from v basis functions

unsigned int u_knot_spans, // knot spans for u values

unsigned int v_knot_spans) // knot spans for v values

{

float *sp = (float*) surface_points; // current output surface point

float *u_basis = u_basis_values; // current set of u basis values

unsigned int *u_knot_span = u_knot_spans; // current u knot span index

/* for each parametric value in the u direction */

for ( unsigned int u_index = 0; u_index < u_step_count; u_index++ )

{

float *v_basis = v_basis_values; // current set of v basis values

unsigned int *v_knot_span = v_knot_spans; // current v knot span idx

/* for each parametric value in the v direction */

for ( unsigned int v_index = 0; v_index < v_step_count; v_index++ )

{

/* hsp --> surface point in homogeneous space */

__m128 hsp = _mm_setzero_ps(); // init all elements to zero

Page 28: Pentium(R) III プロセッサと Pentium 4 プロセッサにおける ...AP-944 NURBS曲面での高速化のパフォーマンス比較 01/10/30 1 Pentium® III プロセッサと

AP-944 NURBS曲面での高速化のパフォーマンス比較

01/10/30 28

/* Step through control points row-by-row, column-by-column. */

/* Calculate where the beginning of the first row is. */

/* In the outer summation loop this pointer is incremented one

row at a time */

ControlPoint *cp_row = &control_points[

((*u_knot_span)-u_degree) * v_control_point_count +

((*v_knot_span)-v_degree)];

/* calculate the surface point in 3D homogeneous space */

for ( unsigned int i = 0; i <= u_degree; i++ )

{

/* current control point is first in the current row */

float *cp = (float*) cp_row;

ASSERT( IS_ALIGNED_16(cp) );

__m128 temp = _mm_setzero_ps(); // intermediate values

__m128 basis; // temporarily holds basis values

/* inner summation */

for ( unsigned int j = 0; j <= v_degree; j++ )

{

temp = _mm_add_ps(temp,

_mm_mul_ps(

_mm_set_ps1(v_basis[j]),

_mm_load_ps(cp)));

/* increment to the next control point in the row */

cp += 4;

}

/* outer summation */

hsp = _mm_add_ps(hsp,

_mm_mul_ps(_mm_set_ps1(u_basis[i]), temp));

/* increment to the next row of control points */

cp_row += v_control_point_count;

}

/* calculate reciprocol homogeneous W --> 1/W */

__m128 rhw = _mm_rcp_ps(_mm_shuffle_ps(hsp, hsp, 0xff));

Page 29: Pentium(R) III プロセッサと Pentium 4 プロセッサにおける ...AP-944 NURBS曲面での高速化のパフォーマンス比較 01/10/30 1 Pentium® III プロセッサと

AP-944 NURBS曲面での高速化のパフォーマンス比較

01/10/30 29

/* bring the surface point into nonhomogeneous space */

hsp = _mm_mul_ps(hsp, rhw);

/* store the surface point to the surface point array */

_mm_storel_pi((__m64*) sp, hsp);

_mm_store_ss(sp+2, _mm_movehl_ps(hsp, hsp));

/* increment to next output surface point */

sp += COORD_PER_SURF_PT;

/* increment to next set of v basis values */

v_basis += (v_degree+1);

/* increment to next v knot span index */

v_knot_span++;

}

/* increment to next set of u basis values */

u_basis += (u_degree+1);

/* increment to next u knot span index */

u_knot_span++;

}

}

Page 30: Pentium(R) III プロセッサと Pentium 4 プロセッサにおける ...AP-944 NURBS曲面での高速化のパフォーマンス比較 01/10/30 1 Pentium® III プロセッサと

AP-944 NURBS曲面での高速化のパフォーマンス比較

01/10/30 30

5.2.2 SSE組み込み関数を使用した 3次 NURBS曲面テセレーション

次の Cコードは、SSE組み込み関数を使用して、3次 NURBS曲面の一様テセレーションを実行する。

void TessellateCubicSurfaceSSE(

SurfacePoint surface_points, // output surface points

unsigned int u_step_count, // steps to take in u direction

unsigned int v_step_count, // steps to take in v direction

unsigned int u_degree, // degree of basis values in u direction

unsigned int v_degree, // degree of basis values in v direction

float *u_basis_values, // values from u basis functions

float *v_basis_values, // values from v basis functions

unsigned int u_knot_spans, // knot spans for u values

unsigned int v_knot_spans) // knot spans for v values

{

float *sp = (float*) surface_points; // current output surface point

float *u_basis = u_basis_values; // current set of u basis values

unsigned int *u_knot_span = u_knot_spans; // current u knot span index

/* for each parametric value in the u direction */

for ( unsigned int u_index = 0; u_index < u_step_count; u_index++ )

{

float *v_basis = v_basis_values; // current v basis values

unsigned int *v_knot_span = v_knot_spans; // current v knot span idx

/* load and broadcast the basis values */

ASSERT( IS_ALIGNED_16(u_basis) );

__m128 bu[CUBIC_ORDER];

bu[3] = _mm_load_ps(u_basis);

bu[0] = _mm_shuffle_ps(bu[3], bu[3], 0x00);

bu[1] = _mm_shuffle_ps(bu[3], bu[3], 0x55);

bu[2] = _mm_shuffle_ps(bu[3], bu[3], 0xaa);

bu[3] = _mm_shuffle_ps(bu[3], bu[3], 0xff);

/* for each parametric value in the v direction */

for ( unsigned int v_index = 0; v_index < v_step_count; v_index++ )

{

/* load and broadcast the basis values */

ASSERT( IS_ALIGNED_16(v_basis) );

__m128 bv[CUBIC_ORDER];

bv[3] = _mm_load_ps(v_basis);

bv[0] = _mm_shuffle_ps(bv[3], bv[3], 0x00);

Page 31: Pentium(R) III プロセッサと Pentium 4 プロセッサにおける ...AP-944 NURBS曲面での高速化のパフォーマンス比較 01/10/30 1 Pentium® III プロセッサと

AP-944 NURBS曲面での高速化のパフォーマンス比較

01/10/30 31

bv[1] = _mm_shuffle_ps(bv[3], bv[3], 0x55);

bv[2] = _mm_shuffle_ps(bv[3], bv[3], 0xaa);

bv[3] = _mm_shuffle_ps(bv[3], bv[3], 0xff);

/* get a pointer to the first row of control points */

/* we process the control points one row at a time */

ControlPoint *cp_row = &control_points[

((*u_knot_span)-CUBIC_DEGREE) * v_control_point_count +

((*v_knot_span)-CUBIC_DEGREE)];

/* calculate the surface point in 3D homogeneous space */

__m128 hsp = _mm_setzero_ps();

float *cp;

#define HOMOGENEOUS_SURFACE_POINT(idx) \

\

cp = (float*) &cp_row[idx*v_control_point_count]; \

ASSERT( IS_ALIGNED_16(cp) ); \

\

hsp = _mm_add_ps(hsp, \

_mm_mul_ps(bu[(idx)], \

_mm_add_ps( \

_mm_add_ps( \

_mm_mul_ps(bv[0], _mm_load_ps(cp+0)), \

_mm_mul_ps(bv[1], _mm_load_ps(cp+4))), \

_mm_add_ps( \

_mm_mul_ps(bv[2], _mm_load_ps(cp+8)), \

_mm_mul_ps(bv[3], _mm_load_ps(cp+12))))));

HOMOGENEOUS_SURFACE_POINT(0)

HOMOGENEOUS_SURFACE_POINT(1)

HOMOGENEOUS_SURFACE_POINT(2)

HOMOGENEOUS_SURFACE_POINT(3)

/* calculate reciprocol homogeneous W --> 1/W */

__m128 rhw = _mm_rcp_ps(_mm_shuffle_ps(hsp, hsp, 0xff));

/* bring the surface point into nonhomogeneous space */

hsp = _mm_mul_ps(hsp, rhw);

/* store the surface point to the surface point array */

_mm_storel_pi((__m64*) sp, hsp);

_mm_store_ss(sp+2, _mm_movehl_ps(hsp, hsp));

Page 32: Pentium(R) III プロセッサと Pentium 4 プロセッサにおける ...AP-944 NURBS曲面での高速化のパフォーマンス比較 01/10/30 1 Pentium® III プロセッサと

AP-944 NURBS曲面での高速化のパフォーマンス比較

01/10/30 32

/* increment to the next output surface point */

sp += COORD_PER_SURF_PT;

/* increment to the next set of v basis values */

v_basis += CUBIC_ORDER;

/* increment to the next v knot span index */

v_knot_span++;

}

/* increment to the next set of v basis functions */

u_basis += CUBIC_ORDER;

/* increment to the next u knot span index */

u_knot_span++;

}

}

Page 33: Pentium(R) III プロセッサと Pentium 4 プロセッサにおける ...AP-944 NURBS曲面での高速化のパフォーマンス比較 01/10/30 1 Pentium® III プロセッサと

AP-944 一様 NURBS曲面テセレーションのパフォーマンス比較 – 節点ベクトルと基底関数

01/10/30 A-1

付録 A - 節点ベクトルと基底関数基底関数(bi,p(u)と bj,q(u))は、節点ベクトルから導出される。パラメータ u、vは、それぞれ独自の節点ベクトルを持つ。したがって、各パラメータはそれぞれ独自の基底関数セットを持つ。

節点ベクトルから基底関数を導出するアルゴリズムは、どちらのパラメータでも同じである。

以降の説明では、特に断らない限り、パラメータ uについてのみ説明する。これは議論をわかりやすくするためなので、パラメータ vにも同じ処理や計算式が当てはまる。

曲面の次数は、その曲面を定義する基底関数の次数と同じである。基底関数は、次の多項式で表される。

0,1,2

2,2

2,1

1,,, **...***)( iiip

pip

pip

pipi auauauauauaub ++++++= −−

−−

3次曲面は、次の 3次基底関数(p = 3)で定義される。

0,1,2

2,3

3,3, ***)( iiiii auauauaub +++=

係数 ai,p、ai,p-1、ai,p-2、…、ai,2、ai,1、ai,0は、基底係数と呼ばれ、節点ベクトルと呼ばれる非降順の数値シーケンスから導出される。節点ベクトルを構成する数値シーケンス内のそれぞれの

値は、節点または節点値と呼ばれる。節点ベクトルは次のように表される。

U = [u0, u1, u2, …, um-2, um-1]

ここで、mは節点ベクトル内の節点数で、次の式で計算される。

m = n + p +1

ここで、nは制御点数、pは曲面の次元、u0、u1、u2、…、um-2、um-1は範囲[0,1]内の節点値である。

各基底関数は、(パラメータの指定範囲内で)曲面の形状に影響する。節点は、ある基底関数から次の基底関数に切り替わるパラメトリック値を決定する。すなわち、節点ベクトル内の節点

値により、ある基底関数の影響が終了し、次の基底関数の影響が開始する境界が決まる。

種々のパラメトリック曲面があるので、NURBSには特定の基底関数セットはない。基底関数は節点間隔に依存し、低次の基底関数から再帰的に定義される。Cox-DeBoorアルゴリズム 1の

直接応用を使用して、節点ベクトルから直接基底関数を計算できる。あるいは、Cox-DeBoorアルゴリズムの拡張バージョンを使用して、基底係数を計算し、それから基底値を計算するこ

ともできる。3次 Bスプラインのパラメータ uに対して定義される Cox-DeBoorアルゴリズムを次に示す。

)()()(

)()()(

)()()(

,0,1

)(

2,114

42,

33,

1,113

31,

22,

0,112

20,

11,

10,

uBuuuu

uBuu

uuuB

uBuuuu

uBuu

uuuB

uBuuuu

uBuu

uuuB

otherwiseuuu

uB

iii

ii

ii

ii

iii

ii

ii

ii

iii

ii

ii

ii

iii

+++

+

+

+++

+

+

+++

+

+

+

−−

+−−

=

−−

+−−

=

−−

+−−

=

<≤

=

1つのパラメトリック値に対して、4つの基底値が生成されるのに注意のこと。

Page 34: Pentium(R) III プロセッサと Pentium 4 プロセッサにおける ...AP-944 NURBS曲面での高速化のパフォーマンス比較 01/10/30 1 Pentium® III プロセッサと

AP-944 一様 NURBS曲面テセレーションのパフォーマンス比較 – 節点ベクトルと基底関数

01/10/30 A-2

基底関数の計算方法は、アプリケーションごとに大きく異なる。計算方法は、曲面テセレー

ションを行う頻度と、詳細レベルの違いによって変わる。詳細レベルが変わるたびに、基底関

数に関して何らかの操作を行う必要がある。最も簡単なのは、詳細レベルが変わるたびにすべ

ての基底関数を再計算する方法である。この他にも種々の方法があるが、このアプリケーショ

ン・ノートの範囲を超えているため、ここでは説明しない。このアプリケーション・ノートで

は、基底関数は計算済みで基底値がメモリ内の配列(できればアライメント済み配列)に保存されているものとする。

節点ベクトルは次のように表される。

U = [u0, u1, u2, u3, u4, …, um-5, um-4, um-3, um-2, um-1]

ここで、

u0、u1、u2、…、upは、すべて 0

um-p-1、um-p、um-p+1、…、um-1は、すべて 1

1,...,0 21 ≤≤ −−+ pmp uu

3次節点ベクトルは次のように表される。

U = [u0, u1, u2, u3, u4, …, um-5, um-4, um-3, um-2, um-1]

ここで、

u0 = 0

um-1 = 1

1,0 21 ≤≤ −muu

節点の反復により、曲面の連続性は低下する。実際に、非一様パラメトリック曲面を使用する

利点の 1つは、制御点の補間(またはパススルー)を強制できる点にある。他の曲面の節点は一様に分布しており(そのため一様曲面と呼ばれる)、したがって節点の反復はない。これが、一様曲面の連続性は非一様曲面ほど効果的に制御できない理由である。3次節点ベクトルで最初と最後の節点を 4回繰り返すと、制御グリッドの隅の制御点が曲面で補間される。

節点スパンは、節点ベクトル内で隣接する節点の間隔である。パラメトリック値は節点スパン上に「座る」といい、各パラメトリック値は節点ベクトル内の 2つの節点値の間に位置する。このアプリケーション・ノートに示すコードでは、節点スパン・インデックスを使用して、現

在の uと vの値から ),( vuS を計算するのにどの制御点セットを使用するか決定する。節点スパ

ン・インデックスの決定方法を図 3に示す。

[0.0, 0.0, 0.0, 0.0, 0.5, 1.0, 1.0, 1.0, 1.0]0 1 2 3 4 5 6 7

節点ベクトル

節点スパン・インデックス:

u = 0.25

図 3: ラベル付き節点スパンを持つ節点ベクトル。パラメトリック値、u = 0.25、は節点スパン・インデックス 3を持つ。

Page 35: Pentium(R) III プロセッサと Pentium 4 プロセッサにおける ...AP-944 NURBS曲面での高速化のパフォーマンス比較 01/10/30 1 Pentium® III プロセッサと

AP-944 一様 NURBS曲面テセレーションのパフォーマンス比較- パフォーマンス・データ

01/10/30 B-1

付録 B - パフォーマンス・データ

パフォーマンス・データの改訂履歴

改訂 改訂履歴 日付

2.0 1.2 GHz インテル® Pentium® 4のパフォーマンス・データに関する改訂 2000年 7月

1.0 初版 1999年 9月

このパフォーマンス測定では、1つの NURBS曲面で 256個の点を計算した。この数を選択したのは、曲面上の一点当たりのパフォーマンスがこの個数で一定になるからである。曲面上の

256以上の点.を計算すると、一点当たりのパフォーマンスにいくらかばらつきがでた。256以下の点を計算すると、オペレーティング システムのオーバヘッドがパフォーマンス測定の妨げとなった。

制御点グリッド・サイズは、10×10を無作為に選択した。u方向、v方向ともに 10個の制御点を持つ。このサイズの選択は無作為であり、意味はない。制御点グリッド・サイズを変えると、

ここに示したパフォーマンス測定結果とは異なる値になる。グリッド内の制御点数を増やすと、

必要なメモリ・アクセス回数が増えるので、パフォーマンスは低下する。

表 1: NURBS曲面テセレーションのパフォーマンス・データ

曲面上の一点の計算に要する平均時間(マイクロ秒)を測定した

パフォーマンス・データ(曲面上の一点の計算に要したマイクロ秒)

コーディング方法

インテル Pentium IIIプロセッサ

(733 MHz)

インテル Pentium 4プロセッサ

(1.2 GHz)

Intel® x87アーキテクチャ 0.377 0.263

Intel x87アーキテクチャ(3次) 0.344 0.227

Intel x87アーキテクチャ(3次、展開)

0.356 0.192

ストリーミング SIMD拡張命令(SSE)

0.306 0.190

SSE(3次) 0.161 0.0967

Page 36: Pentium(R) III プロセッサと Pentium 4 プロセッサにおける ...AP-944 NURBS曲面での高速化のパフォーマンス比較 01/10/30 1 Pentium® III プロセッサと

AP-944 一様 NURBS曲面テセレーションのパフォーマンス比較- パフォーマンス・データ

01/10/30 B-2

表 2:表 1のパフォーマンス・データから求めた高速化

高速化の値は、表 1の第 2列の値を表 1の第 3列の値で割ったものである。

コーディング方法 インテル® Pentium® 4プロセッサによる高速化

Intel x87アーキテクチャ 1.43

Intel x87アーキテクチャ(3次) 1.52

Intel x87アーキテクチャ(3次、展開)

1.86

SSE 1.61

SSE(3次) 1.67

高速化の平均 1.62

パフォーマンスは、通常のキャッシュ環境で測定した(アプリケーション・ノートによっては、「完全キャッシュ」環境で測定したものもある)。パフォーマンス測定に使用したのは、733MHz Pentium IIIプロセッサと 1.2 GHz Pentium 4プロセッサである。使用したシステムの詳細については、B-3の「テスト・システム構成」を参照のこと。

ソフトウェア・プリフェッチを使用すると、制御点数が少ないときはレイテンシによるパ

フォーマンスへの影響が隠される場合がある。このアプリケーション・ノートに示すコードで

は、ソフトウェア・プリフェッチはいっさい使用していない。

最も高速なのは、SSEを使用する 3次のコードを Pentium 4で実行した場合であった。Pentium4プロセッサによる高速化が最も大きかったのは、x87アーキテクチャを使用し、ループを展開した 3次のコードで、1.86倍の高速化が測定された。次に高速化が大きかったのは、SSEを使用する 3次のコードで、1.67倍の高速化が測定された。

Pentium IIIプロセッサでは、SSEを使用する最速コードが、Intel x87アーキテクチャを使用する最速コードの 2.14倍速かった。Pentium 4プロセッサでは、SSEを使用する最速コードが、Intel x87アーキテクチャを使用する最速コードの 1.98倍速かった。SSEを使用する最速コードを Pentium 4プロセッサで実行した場合は、Intel x87アーキテクチャを使用する最速コードをPentium IIIプロセッサで実行した場合より、3.56倍速かった。

ほとんどの場合、パフォーマンスは、Pentium IIIプロセッサと Pentium 4プロセッサの周波数にほぼ比例している。NURBS曲面テセレーションは、SSEと Pentium 4プロセッサを使用することにより大きく向上する。

Page 37: Pentium(R) III プロセッサと Pentium 4 プロセッサにおける ...AP-944 NURBS曲面での高速化のパフォーマンス比較 01/10/30 1 Pentium® III プロセッサと

AP-944 一様 NURBS曲面テセレーションのパフォーマンス比較- パフォーマンス・データ

01/10/30 B-3

テスト・システム構成

表 3: インテル® Pentium® IIIシステム構成

プロセッサ Pentium IIIプロセッサ(733 MHz)システム Intel® Desktop Board VC820

BIOSバージョン VC82010A.86A.0028.P10

2次キャッシュ 256 KB

メモリ・サイズ 128 MB RDRAM PC800-45

Ultra ATAストレージ・ドライバ

製品候補 6.00.012

ハード・ディスク IBM DJNA-371800 ATA-66

ビデオ・コントローラ/バス

Creative Labs 3D Blaster† Annihilator† Pro AGP nVidia GeForce256†

DDR –32MB

ビデオ・ドライバの

リビジョン

NVidia Reference Driver 5.22

オペレーティング・

システム

Windows† 2000ビルド 2195

表 4: インテル® Pentium 4システム構成

プロセッサ Pentium 4プロセッサ(1.2 GHz)システム Intel Desktop Board D850GB

BIOSバージョン GB85010A.86A.0014.D.0007201756

2次キャッシュ 256 KB

メモリ・サイズ 128 MB RDRAM PC800-45

Ultra ATAストレージ・ドライバ

製品候補 6.00.012

ハード・ディスク IBM DJNA-371800 ATA-66

ビデオ・コントローラ/バス

Creative Labs 3D Blaster Annihilator Pro AGP nVidia GeForce256 DDR–32MB

ビデオ・ドライバの

リビジョン

NVidia Reference Driver 5.22

オペレーティング・

システム

Windows 2000ビルド 2195