|
最新の記事
カテゴリ
おすすめキーワード(PR)
ファン
|
愚痴りたくなった。
率直に言って、OpenGL ES2.0のシェーダーコンパイラ設計した奴、バカだろ。 シェーダー内に宣言しているuniformと呼ばれるコンスタントレジスタが使用されていないとマッピングされず、マッピングが固定できないのが大問題。それならそれで、最適化を抑制するプレフィクスなり、共有を示唆するプレフィックスなりオプションなりあればよいのだが、それもない。 ならば、ダミーのファンクション内でuniformを使用してコンパイラを騙そうとしても、そのファンクション自体も最適化されてしまうことで、やはりuniformも数珠繋ぎ状にカットされてしまう。 これの何が問題かというと、コンスタントレジスタがプログラムオブジェクト(バーテックス&フラグメントシェーダーをリンクした実効バイナリ)間で共有する事ができなくなるので、プログラムオブジェクトが変わる度に、使用するGPUコンスタントレジスタをすべて更新しなければならなくなるのだ。 たとえば、スキニングに使用するマトリックスパレットは通常同一メッシュ内なら変更する必要はないのだが、クラスタ単位でマトリックスパレットを設定し直すという間抜けな事をしなければならない。 この間抜けな設計によって OpenGL ES2.0のシェーダーコンパイラを使用するすべてのデバイスが無用なパフォーマンスダウンを被ることになる。 おまけに、ヘッダーすらインクルードできないうえに、外部参照シンボルの解決もやってくれないので、分割コンパイルができない。 史上最悪だねこれは。ありえない。
1〜1,000,000までの平方根の逆数を求め、値をバッファに格納するという処理を、通常の直列処理と、blocksというApple製ラムダ式と、Grand Central Dispatch(GCD)を使った並列処理で比べてみました。2コアなので2スレッド以上は意味が無いと断定し、2スレッドのみ使用しました。
ターゲット機は、iPhone4S(2CPUコア)と、iPhone4(1 CPUコア)です。 ボタン押し下げイベントハンドラ内で処理をスタートさせています。 結果、 [iPhone4S] 直列処理: 2.8m秒 並列処理: 1.4m秒 2CoreのiPhone4Sでは、処理時間が、丁度半分という嘘みたいな結果となりました。 このような、並列処理に向いた処理では、2コアの効果が高いようです。 [iPhone4] 直列処理: 7.5m秒 並列処理: 13.1m秒 やばい結果がでてしまいました。 1コアのiPhone4では、GCDのオーバーヘッドのせいか、処理時間がほぼ倍になっています。 めんどくせー。 【通常のシーケンシャルな処理】 - (IBAction)buttonPressed: (id)sender { static const size_t NumElem = 1000000; double* buffer = new double[ NumElem ]; int64_t start = dispatch_time( DISPATCH_TIME_NOW, 0 ); for( size_t i = 0; i < NumElem; ++i ) { buffer[i] = 1.0/sqrt( (double)( i + 1 ) ); } int64_t end = dispatch_time( DISPATCH_TIME_NOW, 0 ); double delta = (double)( end - start )/1000000.0; m_Label.text = [ NSString stringWithFormat: @"%lf msec", delta ]; } - (void)addCount { ++m_Count; } 【 blocksによる並列処理】 - (IBAction)buttonMultiPressed: (id)sender { static const size_t NumElem = 1000000; double* buffer = new double[ NumElem ]; int64_t start = dispatch_time( DISPATCH_TIME_NOW, 0 ); m_Count = 0; dispatch_queue_t queue = dispatch_queue_create( "test", NULL ); dispatch_async( queue, ^{ for( size_t i = 0; i < NumElem/2; ++i ) { buffer[i] = 1.0/sqrt( (double)( i + 1 ) ); } [ self addCount ]; } ); dispatch_async( queue, ^{ for( size_t i = NumElem/2; i < NumElem/2; ++i ) { buffer[i] = 1.0/sqrt( (double)( i + 1 ) ); } [ self addCount ]; } ); dispatch_release( queue ); // 同期待ちします。 while( m_Count < 2 ) { } int64_t end = dispatch_time( DISPATCH_TIME_NOW, 0 ); double delta = (double)( end - start )/1000000.0; m_LabelMulti.text = [ NSString stringWithFormat: @"%lf msec", delta ]; } < 前のページ次のページ >
| |||||||||||||||||||||||||||||||||||||||||||||||||