C#は電気羊の夢を見るか?(引っ越し中)

dtiブログが閉鎖とのことでhttp://tanocs.blog.fc2.com/へ引っ越します。

配列のお話

普段何気なく使っている多次元配列。
過去の自分が作ったソースを見ていると、
ある時期を境に表記が変わっていることに気がついた。

int[][] a; //旧
int[,] a; //新

ある時期というのは、ブランクが1年ほどあるので、
そこが境界なのだが・・・はて、この差はなんだ?
と思いつつも、大して違いはなかろうと、ろくすっぽ調べることなく放置してました。


んで最近、配列の初期化をスタイリッシュに行いたいと思い立ち、以下のソースに出会った。


//int[100]{1,1,1,1,1.....}と同じ
int[] intArray = Enumerable.Repeat(1, 100).ToArray();

//string[10]{"a","a","a"....}と同じ
string[] strArray = Enumerable.Repeat("a", 10).ToArray();


うん、スタイリッシュ。

速さについては知らないが、さほどコールされない初期化処理なら問題にはならんでしょう。
それよりも、初期化処理にfor文を書かずに済む分、非常に見栄えがよろしい。

ところが以下のような多次元配列の初期化が通らない。


int[,] array = Enumerable.Repeat(Enumerable.Repeat(1, 100).ToArray(), 100).ToArray();

なんでもint[,]にint[*][*]を変換できないのだとか。

     |
 \  __  /
 _ (m) _ピコーン
    |ミ|
  /  `´  \
   ('A`)
   ノヽノヽ
     くく   もしや、別物。。。


んでよくよく調べてみると、最初に書いた表記の差は、ジャグ配列と多次元配列という、
全く別ものであることが分かった。


int[][] a; がジャグ配列
int[,] a; が多次元配列


int[][]は四角い配列にする必要がないとかで、直感的に”低速そうだなぁ”と思ったのだが、
よく良く調べてみるとどうも違う。

int[][]は内部的には一次元配列を切り替えて処理するため、
単純な二次元配列よりも高速なのだという。


ほぅ・・・


じゃぁ、二次元配列の強みは?というと、
アンセーフコード化したときにポインタアクセスするのに便利。
さらに、アンセーフコードでポインタアクセスすると高速。
・・・って、おい。

マネージドコードじゃ、いいところ無しかぁ・・


ではジャグ配列の実力とやらを検証してみると
内部的に一次元配列と言いながらも、一次元配列より15%程遅い。

そして、四角い配列はアンマーネジコードで線形アクセスすると早い。
なら最初から一次元配列にしとけばいいんじゃぁ・・・

今までなんとなく二次元配列を使用してましたが、
速度が必要になる画像処理やゲームの世界では、極力一次元配列で実装したほうが良さそう。
このエントリーをはてなブックマークに追加
LINEで送る

のっぴきいかねぇ

世の中にはやってはならんことというのが幾つかある。
その理由や度合いは様々だが、いたしかたない事もある。

今回は標準モジュールの設計がプア過ぎて、
親ウィンドウ閉じちゃうようなひょっとこなダイアログを
さらにコンストラクタで呼び出すという、ひょっとこ面の頭にヤカン載っけて沸かしてしまうような状態のプログラムを
納期との兼ね合いでどうしても動作させるようにする方法のご紹介。

ObjectDisposedExceptionを吐いているので、それを無視すれば良い。

メッセージはきっとこんな感じで出ているでしょう
「破棄されたオブジェクトにアクセスできません。
オブジェクト名 'Form1' です。」

Program.csをこんな感じに変更

try {
Application.Run(new Form1());
} catch (ObjectDisposedException ode){
}

き、きもちわるい・・・・


まちがっても
catch (Exception e)
などと記載しないように、きっとこんなのプログラマが書いたらSEは死んでしまう。


とりあえず・・・とりあえず、これでエラーを吐かずに動く。
現場では動くプログラムこそ正義。

悲しいけど、これ仕事なのよね。
このエントリーをはてなブックマークに追加
LINEで送る

シェーダについて

先日ピクセルシェーダでは遅いというような記事を書いたが、
もう少し掘り下げて調査をしてみると、どうやらその考え方はかなり古いようです。

現在のGPUは統合シェーダという設計思想に基づいてハードが設計されており、
〜シェーダ用をN基とかそういう実装では無いそうで・・・


プログラマ側からしてみると、バーテックスシェーダやピクセルシェーダと言う区切りで各処理を実装していくと思う。

しかし、そういう処理のステップでその処理を行うというだけで、
物理的に処理を行うチップがどうこうという訳ではなくなっていたというわけ。
(※とりわけ最新事情というわけではなく、この設計思想は5年以上昔の話です)


結局、長い間DirectX9がソフトのシェアを握りっぱなしになっていて、
そのへんの情報に鈍感になっていたのだなぁと思う。

しかしながら、XNAはまだDirectX9系のままな訳で、
ジオメトリシェーダは使用できないままというのも現状なんだよなぁ
・・・

実際のところ、OSレベルでの切り替えが進まないとDirectX10以降でゲームを開発しても
結局それが販売に繋がらなくなってしまう。

じゃぁ、一体いつになればジオメトリシェーダを大手を振って使えるようになるかと言えば、
それはまだ3年以上先の話なんじゃないだろうか・・・


ピクセルシェーダでの実装に話を戻すと、統合シェーダという設計思想や、ピクセルシェーダ後期の状態を見ればあながち間違いではないような気がする。(と言うよりむしろ、そちらのほうが主流のように思う)


しかし、データの転送にテクスチャを用意しなければならないし、
その使用制限もきつい、さらに言えば処理済みの結果を使うチャンスが残されていない。

何よりループ処理に処理を食われてしまう問題から逃げるのに労力を取られる気がする・・


しかしながら、ピクセルシェーダのほうが負荷数が非常に大きいことから、並列化、高速化、最適化はピクセルシェーダのほうが進んでいるように書かれている文献も多く見られた。

これは統合シェーダとしてみた時にも通用するアーキテクチャなのか不明なんだけど、
その流れがあったことを考えれば、最適化はされているような気がする。


個人的にはプログラムのしやすいバーテックスシェーダ優秀説を唱えたいのだが、
実際のところはどうなんじゃろうか・・
このエントリーをはてなブックマークに追加
LINEで送る

 | HOME | 

PAGE TOP ▲

Appendix

■春条

■春条

生息地は愛知
車と甘い物が好きな31歳
特技は無限昼寝

MONOからSharpDXを使う
変態的な手法で、
.NET Frameworkを使わずに
ゲーム作りやってます。

Search

Calender

« | 2011-04 | »
S M T W T F S
- - - - - 1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30

Twitter

Recent Entries

DTIブログポータルへ
このブログを通報
Report Abuse

利用規約