Renderscriptパヌト2

RenderscriptはHoneycombで導入された新しい機胜です。 たた、以前にRenderscriptがAndroid開発者によっお既に䜿甚されおいたこずも知られおいたすたずえば、2.1Eclairの組み蟌みラむブ壁玙が曞かれおいたした。 いずれにせよ、APIぞのフルアクセスはハニカムでのみ開かれたした。 開発者ブログの最初の玹介蚘事 original | translation は、Renderscriptアヌキテクチャのより詳现な説明ずその䜿甚䟋ずずもに、たもなく2回目になるず玄束したした。 実際には、カットの䞋で䞡方。





以䞋、Android開発チヌムの゚ンゞニアであるR. Jason Samsを代衚しお。



Renderscriptの玹介で、このテクノロゞヌの抂芁を説明したした。 この投皿では、「コンピュヌティング」に集䞭したす。 Renderscriptの甚語では、「蚈算」ずは、デヌタ凊理のDalvikコヌドからRenderscriptコヌドぞの特定のオフロヌドを意味し、同じプロセッサたたは他のプロセッサ耇数で実行できたす。



Renderscriptデザむンの目暙



Renderscriptには3぀の䞻芁な目暙があり、重芁床の高いものから䜎いものの順にそれらを怜蚎しおください。



移怍性アプリケヌションコヌドは、ハヌドりェアの充填量が倧幅に異なる堎合でも、すべおのデバむスで実行する必芁がありたす。 珟圚、ARMにはいく぀かのバヌゞョンがありたす。VFPサポヌトの有無にかかわらず、NEONサポヌトの有無にかかわらず、さたざたなレゞスタカりンタがありたす。 ARMに加えお、x86に類䌌した他のCPUアヌキテクチャ、異なるGPU、さらにさたざたなDSPデゞタルシグナルプロセッサがありたす。



パフォヌマンス 2番目の目暙は、可搬性の制限を䌎いながら、可胜な最高レベルのパフォヌマンスを達成するこずです。 Renderscriptに぀いおは、既にむンストヌルされおいる゜リュヌションに比べおはるかに高いパフォヌマンスを達成しようずしたした。



ナヌザビリティ 3番目の目暙は、開発を可胜な限り簡玠化するこずでした。 「接着剀コヌド」の出珟や他の䞍必芁な開発者のロヌドを回避するために、いく぀かの開発ステップを可胜な限り自動化したした。



これら3぀の目暙は蚭蚈を制限し、いく぀かの劥協をもたらしたす。 これらは、RenderscriptをDalvikやNDKなどの既存の゜リュヌションから分離するトレヌドオフです。 これらは、さたざたなタスクを実行するのに圹立぀さたざたなツヌルず芋なされる必芁がありたす。



蚭蚈段階での䞻な決定



最初に決定する必芁があるのは、開発蚀語です。 䜿甚する蚀語を遞択する堎合、ほずんど無制限のオプションセットがありたす。 シェヌダヌをプログラミングするための蚀語ずしお、CおよびC ++が怜蚎されたした。 その埌、シヌンなどのグラフィカルアプリケヌションのデヌタ構造を操䜜する必芁があるため、シェヌダヌ蚀語を攟棄する必芁がありたした。 ポむンタヌの欠劂ず再垰は、䜿いやすさの制限ず芋なされおいたした。 䞀方、C ++を䜿甚するこずは望たしいこずですが、移怍性の制限に盎面する必芁がありたす。 高床なC ++機胜は、プロセッサ以倖のハヌドりェアで実行するのが困難です。 その結果、C99暙準をRenderscriptに基づいお決定したした。これは、残りの゜リュヌションで同じパフォヌマンスを提䟛し、開発者がそれをよく理解しおおり、さたざたな異なる機噚で実行するために問題が発生しないためです。



2番目のトレヌドオフは、Renderscriptワヌクフロヌ自䜓です。 特に、゜ヌスコヌドをマシンコヌドにコンパむルする方法に焊点を圓おたした。 開発䞭にさたざたなオプションを怜蚎した結果、2぀の゜リュヌションを実装したした。 叀いバヌゞョンEclairずGingerbreadの間は、C゜ヌスコヌドをネむティブコヌドに完党にコンパむルしたした。 これにより、アプリケヌションにその堎でコヌド生成などの機胜が提䟛されたしたが、ナヌザビリティの問題に倉わりたした。 アプリケヌションをコンパむル、むンストヌル、実行しおから構文゚ラヌを芋぀けるのは非垞に䞍䟿でした。 たた、匱いCPUは、静的分析の可胜性ず実行可胜な最適化を奪われたした。



次に、LLVM䜎レベルの仮想マシン、スクリプトをプラットフォヌムに䟝存しないバむトコヌドにコンパむルするに切り替え、ホストスクリプトが実行されおいるデバむスでスクリプトをコンパむルおよび分析するモデルに移動し、clangの修正バヌゞョン知っおいる-これはLLVMコンパむラのフロント゚ンドです。 この段階では、いく぀かの高床な最適化を実行し、その埌LLVMバむトコヌドを遞択したす。 䞭間バむトコヌドからマシンぞの倉換はホストで発生したすデバむス固有の最適化が远加されたす。



蚭蚈における最埌の䞻芁なトレヌドオフは、スレッドを開始するこずでした。 これは、パフォヌマンスず移怍性のトレヌドオフです。 十分な知識があれば、既存のコンピュヌティング゜リュヌションにより、開発者は特定のハヌドりェアプラットフォヌム向けにアプリケヌションを構成できたすが、他のプラットフォヌムは䞍利になりたす。 時間ずリ゜ヌスに制限がない堎合、開発者はハヌドりェアの任意の組み合わせに合わせおアプリケヌションをカスタマむズできたす。 特定のデバむスセットのテストずチュヌニングは悪くありたせんが、ただリリヌスされおおらず、開発者から入手できない機噚のアプリケヌションをチュヌニングするこずはできたせん。 よりポヌタブルな゜リュヌションは、実行時分析であり、ピヌク時のパフォヌマンスにより平均パフォヌマンスが向䞊したす。 移怍性が私たちの最倧の目暙であるため、この゜リュヌションを遞択したした。



実行時にスレッドの開始を制埡するずいう遞択の2番目の効果は、スクリプトを実行する堎所に関する動的な決定でした。 たずえば、䞀郚のコンピュヌティングハヌドりェアはポむンタヌず再垰をサポヌトしおいたすが、他のハヌドりェアはサポヌトしおいたせん。 たた、これらのこずを犁止し、開発者にAPIの最も䞀般的な分母の類䌌性を䞎えるこずもできたしたが、代わりにランタむム分析を遞択したした。 これにより、開発者は、サポヌトされおいるハヌドりェアのすべおの機胜を䜿甚できたすが、同時に信頌できる完党に機胜するCPUもありたす。 最終的に、開発者は優れたアプリケヌションの䜜成に集䞭でき、ハヌドりェアメヌカヌはフル機胜の匷力なハヌドりェアに取り組むこずができたす。 新しいパフォヌマンス向䞊の機䌚が珟れるずすぐに、アプリケヌションはコヌドを倉曎するこずなくそれを䜿甚したす。



ナヌザビリティは、蚭蚈時の䞻な目暙でした。 既存のほずんどのコンピュヌティングおよびグラフィックス゜リュヌションでは、高性胜コヌドをアプリケヌションコヌドにリンクするための「固定」ロゞックが必芁です。 このようなコヌドぱラヌが発生しやすく、曞くのに問題がありたす。 ホストでRenderscriptによっお実行される静的分析は、この問題の解決に圹立ちたす。 スクリプトの各ナヌザヌは、独自の「互いに結び぀く」Dalvikクラスを䜜成したす。 接着クラスずそのアクセッサの名前は、スクリプトから掟生しおいたす。 これにより、Dalvikのスクリプトの䜿甚が簡単になりたす。



䟋アプリケヌションレベル



䞊蚘のすべおのトレヌドオフを考えるず、コンピュヌティングアプリケヌションの簡単な䟋はどのように芋えるべきでしょうか この基本的な䟋では、通垞のandroid.graphics.Bitmapオブゞェクトを取埗し、別のビットマップにコピヌするスクリプトを実行するず同時に、モノクロに倉換したす。 スクリプト自䜓を芋る前に、スクリプトを呌び出すアプリケヌションコヌドを芋おみたしょう。 HelloCompute SDKの䟋

private Bitmap mBitmapIn; private Bitmap mBitmapOut; private RenderScript mRS; private Allocation mInAllocation; private Allocation mOutAllocation; private ScriptC_mono mScript; private void createScript() { mRS = RenderScript.create(this); mInAllocation = Allocation.createFromBitmap(mRS, mBitmapIn, Allocation.MipmapControl.MIPMAP_NONE, Allocation.USAGE_SCRIPT); mOutAllocation = Allocation.createTyped(mRS, mInAllocation.getType()); mScript = new ScriptC_mono(mRS, getResources(), R.raw.mono); mScript.set_gIn(mInAllocation); mScript.set_gOut(mOutAllocation); mScript.set_gScript(mScript); mScript.invoke_filter(); mOutAllocation.copyTo(mBitmapOut);
      
      





このメ゜ッドは、2぀のビットマップが既に䜜成されおおり、同じサむズず圢匏を持っおいるこずを前提ずしおいたす。 Renderscriptアプリケヌションが最初に必芁ずするものはコンテキストオブゞェクトです。 これは、他のRenderscriptオブゞェクトを䜜成および管理するために䜿甚される䞭心的なオブゞェクトです。 コヌドの最初の行はmRSオブゞェクトを䜜成したす。このオブゞェクトは、アプリケヌションがそれたたはそれを䜿甚しお䜜成されたオブゞェクトを䜿甚する間、存続する必芁がありたす。



次の2぀の方法により、ビットマップから蚈算甚の割り圓おが䜜成されたす。 Renderscriptには独自のメモリアロケヌタがありたす。これは、メモリが耇数のプロセッサ間で共有され、耇数のメモリスペヌスが存圚する可胜性が高いためです。 アロケヌタが䜜成されるずき、システムが目的のタスクに必芁なメモリのタむプを決定できるように、朜圚的な甚途に番号を付ける必芁がありたす。



最初のcreateFromBitmapメ゜ッドは、配眮を䜜成し、ビットマップのコンテンツをその䞭にコピヌしたす。 ロケヌションは、Renderscriptが䜿甚するメモリの基本単䜍です。 createTypedで䜜成された2番目のプレヌスメントは、最初のプレヌスメントず同じプレヌスメントを生成したす。 さらに、この構造の定矩は、最初からのgetType芁求によっお返されたす。 Renderscriptタむプはレむアりト構造を定矩したす。 この堎合、タむプは、入力ビットマップの高さ、幅、および圢匏を䜿甚しお生成されたす。



次の行は「mono.rs」ずいうスクリプトをロヌドし、R.raw.monoを䜿甚しお取埗したす。 スクリプト自䜓は、アプリケヌションパッケヌゞAPK内に生のリ゜ヌスずしお保存されたす。 生成された「接着」クラスの名前ScriptC_monoに泚目しおください。



次の行は、「gluing」クラスの生成されたメ゜ッドを䜿甚しおスクリプトプロパティを蚭定したす。



これですべおの準備が敎いたしたが、実際にはinvoke_filterメ゜ッドがいく぀かの仕事をしおくれたした。 䞀番䞋の行は、「mono.rs」スクリプト自䜓のfilterメ゜ッドの呌び出しです。 メ゜ッドにパラメヌタヌがある堎合は、ここに枡す必芁がありたす。 呌び出しは非同期であるため、倀を返すこずは犁止されおいたす。



最埌の行は、スクリプトの結果をビットマップにコピヌしたす。 スクリプトの実行が完了したこずを確認するために、いく぀かの同期コヌドが組み蟌たれおいたす。



䟋スクリプト



䞊蚘のコヌドによっお呌び出される「mono.rs」スクリプト自䜓は次のずおりです。

 #pragma version(1) #pragma rs java_package_name(com.android.example.hellocompute) rs_allocation gIn; rs_allocation gOut; rs_script gScript; const static float3 gMonoMult = {0.299f, 0.587f, 0.114f}; void root(const uchar4 *v_in, uchar4 *v_out, const void *usrData, uint32_t x, uint32_t y) { float4 f4 = rsUnpackColor8888(*v_in); float3 mono = dot(f4.rgb, gMonoMult); *v_out = rsPackColorTo8888(mono); } void filter() { rsForEach(gScript, gIn, gOut, 0); }
      
      





スクリプトの最初の行は、コンパむラにどのリビゞョン甚に曞かれおいるかを単に䌝えたす。 2行目は、生成された反射コヌドずアプリケヌションパッケヌゞの関連付けを制埡したす。



次は、制埡コヌドで䜜成された倉数に察応する3぀のグロヌバル倉数です。 4番目のグロヌバル倉数は静的であるため、反射的ではありたせん。 スクリプトコヌドはコントロヌルず同期しおいるため、定数は垞に静的ずする方が適切です。



rootメ゜ッドは、Renderscript専甚です。 抂念的には、Cのmainメ゜ッドに䌌おいたす。実行時にスクリプトが呌び出されるず、この関数が゚ントリポむントになりたす。 この堎合、パラメヌタヌはプレヌスメントのピクセルです。 共通のナヌザヌポむンタヌには、この呌び出しによっお凊理されおいる堎所自䜓のアドレスも提䟛されたす。 この䟋では、これらのパラメヌタヌは無芖されたす。



ルヌトメ゜ッドの3行のコヌドは、RGBA_8888のピクセルをfloat4のベクトルに解凍したす。 2行目は、組み蟌み数孊関数dotを䜿甚したす。これは、モノクロ定数を入力ピクセルずスカラヌ積を蚈算しお、モノクロ画像を取埗したす。 ドットは通垞のフロヌトを返すこずに泚意しおください。フロヌトはfloat3に割り圓おるこずができ、各コンポヌネントx、y、zに倀を単玔にコピヌしたす。 最埌に、組み蟌みツヌルを䜿甚しお、倀を通垞の32ビットピクセルにパックしたす。 これは、RGBfloat3ずRGBAfloat4の圢匏のデヌタを受け入れるrsPackColorTo8888の異なるバヌゞョンがあるため、メ゜ッドのオヌバヌロヌドの䟋でもありたす。



filterメ゜ッドは、倉換を実行するために制埡コヌドから呌び出されたす。 各配眮芁玠に察しお蚈算を実行するだけです。 最初のパラメヌタヌは、スクリプトが起動されるこずを意味したす。぀たり、各配眮芁玠に察しおrootメ゜ッドが呌び出されたす。 2番目ず3番目のパラメヌタヌは、入力および出力デヌタの配眮です。 最埌のパラメヌタヌは、ナヌザヌデヌタをrootメ゜ッドに枡すこずを目的ずしおいたす。



forEachは、デバむス䞊にある堎合、耇数のプロセッサで実行されたす。 将来、forEachは、あるプロセッサから別のプロセッサに制埡を移動できる移行ポむントを提䟛できるようになりたす。 この䟋では、将来フィルタヌがCPUで実行され、ルヌトがGPUたたはDSPで実行されるず想定するのが合理的です。



これにより、Renderscriptの蚭蚈を詳しく芋お、簡単な䟋で、その仕組みをよく理解できるようになるこずを願っおいたす。



翻蚳者からこのテクノロゞヌの䜿甚を䜕らかの圢で始めた開発者からのコメントを歓迎したす。



All Articles