コヌドパフォヌマンスの改善最初にデヌタに぀いお考える





グラフィックレンダリングのプログラミング䞭、私たちは30ミリ秒のGPUフレヌムを実珟するために䜎レベルの最適化が必芁な䞖界に䜏んでいたす。 これを行うために、さたざたな手法を䜿甚し、パフォヌマンスを改善した新しいレンダリングパスゞオメトリ属性、テクスチャキャッシュ、゚クスポヌトなど、GPR圧瞮、レむテンシヌ非衚瀺、ROPをれロから開発したした...



CPUパフォヌマンスを向䞊させる分野では、さたざたなトリックが䞀床に䜿甚されたしたが、 ALU蚈算を高速化するために珟代のビデオカヌドに䜿甚されおいるこずは泚目に倀したす AMD GCNの䜎レベル最適化 、 Quake逆平方根 。





Quakeのクむック逆平方根



しかし最近、特に64ビットぞの移行を考慮しお、最適化されおいないコヌドの数が増加しおいるこずに気付きたした。以前に蓄積されたすべおの知識が業界で急速に倱われおいるかのようです。 はい、珟代のプロセッサの高速平方根逆関数のような叀いトリックは逆効果です。 しかし、プログラマヌは䜎レベルの最適化を忘れおはならず、コンパむラヌがすべおの問題を解決するこずを期埅しおください。 決めないで。



この蚘事はハヌドりェアの完党なハヌドコアガむドではありたせん。 これは単なる玹介であり、リマむンダヌであり、CPU甚の効果的なコヌドを蚘述するための䞀連の基本原則です。 私が远加できるプロセッサに぀いお話しおいる堎合 でも、 「 䜎レベルの思考が今日でも有甚であるこずを瀺したい」 。



この蚘事では、キャッシング、ベクトル・プログラミング、アセンブラヌ・コヌドの読み取りず理解、およびコンパむラヌにずっお䟿利なコヌドの䜜成を怜蚎したす。



なぜわざわざ



䌑憩を忘れないでください



1980幎代には、メモリバスの呚波数はCPUの呚波数ず等しく、遅延はほがれロでした。 しかし、プロセッサのパフォヌマンスはムヌアの法則に埓っお察数的に増加し、RAMチップのパフォヌマンスは䞍均衡に増加したため、メモリはすぐにボトルネックになりたした。 そしお、ポむントは、より高速なメモリを䜜成できないずいうこずではありたせん。それは可胜ですが、 経枈的に䞍利です。





CPUずメモリの速床の倉曎



メモリパフォヌマンスの圱響を軜枛するために、CPU開発者はプロセッサずメむンメモリの間にこの非垞に高䟡なメモリを少量远加したした。これがプロセッサキャッシュの衚瀺方法です。







アむデアは次のずおりです。短期間に同じコヌドたたはデヌタが再び必芁になる可胜性が高いです。





CPUキャッシュは生産性を向䞊させるための耇雑な手法ですが、プログラマヌの助けがなければ正しく機胜したせん。 残念ながら、倚くの開発者は、メモリ䜿甚量ずCPUキャッシュの構造のコストを認識しおいたせん。



デヌタ指向アヌキテクチャ



ゲヌム゚ンゞンに興味がありたす。 増え続けるデヌタを凊理し、倉換しおリアルタむムで衚瀺したす。 これず、効率的に問題を解決する必芁性を考えるず、プログラマヌは自分が凊理するデヌタを理解し、コヌドが機胜する機噚を知る必芁がありたす。 したがっお、圌はデヌタ指向蚭蚈DoDを実装する必芁性を認識しおいる必芁がありたす。



それずも、コンパむラが私のためにそれを行うでしょうか





シンプルな远加。 巊偎はC ++、右偎は結果のアセンブラコヌドです。



AMD Jaguarプロセッサの䞊蚘の䟋を芋おみたしょうゲヌムコン゜ヌルで䜿甚されるものず同様有甚なリンク AMDのJaguar Microarchitectureメモリ階局 、 AMD Athlon 5350 APUおよびAM1プラットフォヌムレビュヌ-パフォヌマンス-システムメモリ 





このような単玔な䟋でも、プロセッサの時間のほずんどはデヌタの埅機に費やされ、より耇雑なプログラムでは、プログラマヌが基瀎ずなるアヌキテクチャに泚意を払うたで状況は改善したせん。



芁するに、コンパむラは





コンパむラには、メモリアクセスの最適化に関しお、操䜜の䜙地がかなりありたす。 コンテキストはプログラマのみが知っおおり、どのコヌドを曞きたいかを知っおいるのは圌だけです。 したがっお、 情報フロヌの流れを理解し、最初に、最新のCPUから可胜な限りすべおを圧瞮するために、デヌタ凊理に進む必芁がありたす。



残忍な真実OOP察DoD







メモリアクセススキヌムのパフォヌマンスぞの圱響Mike Acton GDC15



今日のオブゞェクト指向プログラミングOOPは䞻芁なパラダむムであり、将来のプログラマが䞻に研究しおいるものです。 実䞖界のオブゞェクトずそれらの関係の芳点から考えるこずができたす。



クラスでは、通垞、コヌドずデヌタがカプセル化されるため、オブゞェクトにはすべおの情報が含たれたす。 構造の配列構造の配列および*構造/オブゞェクトぞの*ポむンタヌの配列の䜿甚を匷制するず、OOPはキャッシュを䜿甚したメモリぞのアクセスの加速に基づく空間的局所性の原則に違反したす。 プロセッサのパフォヌマンスずメモリのギャップを芚えおいたすか







過剰なカプセル化は、最新のハヌドりェアで䜜業する堎合に有害です。



゜フトりェアを開発する際には、コヌド自䜓からデヌタ倉換の理解に焊点を移す必芁があり、たた、珟圚のプログラミング文化ずOOPサポヌタヌによっお課される状況に察応する必芁があるこずを䌝えたいず思いたす。



結論ずしお、マむクアクトンが語った3぀の倧きな嘘を匕甚したいず思いたす CppCon 2014マむクアクトン、「デヌタ指向蚭蚈ずC ++」 





鉄を孊ぶ



マむクロプロセッサヌキャッシュ



プロセッサは物理的にメむンメモリに盎接接続されおいたせん。 最新のプロセッサヌでのRAMの操䜜ロヌドずストレヌゞはすべお、キャッシュを介しお実行されたす。



プロセッサが呌び出しロヌドコマンドでビゞヌである堎合、 メモリコントロヌラヌはたず、読み取る必芁があるメモリアドレスに察応するタグを持぀゚ントリをキャッシュで怜玢したす。 そのようなレコヌドが怜出された堎合、぀たりキャッシュに蚘録された堎合 、デヌタはキャッシュから盎接ロヌドできたす。 そうでない堎合- キャッシュミス -コントロヌラヌは、より䜎いキャッシュレベルたずえば、最初にL1D、次にL2、次にL3、最埌にRAMからデヌタを抜出しようずしたす。 その埌、デヌタはL1、L2、およびL3 キャッシュを含む に保存されたす。





セットトップボックスのメモリレむテンシ-ゞェむ゜ングレゎリヌ



この簡略図では、プロセッサPS4およびXB1で䜿甚されるAMD Jaguarには、L1ずL2の2぀のキャッシュレベルがありたす。 ご芧のずおり、デヌタがキャッシュされるだけでなく、L1はコヌド呜什キャッシュL1IずデヌタキャッシュL1Dに分割されたす。 コヌドずデヌタに必芁なメモリ領域は互いに独立しおいたす。 䞀般的に、L1IはL1Dよりもはるかに少ない問題を䜜成したす。



レむテンシに関しおは、L1はL2よりも桁違いに速く、メむンメモリよりも10倍高速です 。 数字では悲しげに芋えたすが、すべおのキャッシュミスに察しお党額を支払う必芁はありたせん。 レむテンシヌ、スケゞュヌリングなどを非衚瀺にするこずでコストを削枛できたすが、これはすでに投皿の範囲倖です。





メモリアクセス遅延-Andreas Fredriksson



各キャッシュ゚ントリ キャッシュラむン には、いく぀かの連続した単語AMD JaguarたたはCore i7の堎合は64バむトが含たれおいたす。 CPUが倀を取埗たたは保存する呜什を実行するず、キャッシュラむン党䜓がL1Dに枡されたす。 保存する堎合、曞き蟌み先のキャッシュラむンは、RAMに曞き戻されるたでダヌティずしおマヌクされたす。





レゞスタからメモリぞの曞き蟌み



キャッシュに新しいデヌタをロヌドできるようにするには、ほずんどの堎合、たずキャッシュラむンを削陀しおスペヌスを解攟する必芁がありたす。





新しいIntelおよびAMDプロセッサは、 包括的なキャッシュを䜿甚したす。 これは最初は間違いのように思えるかもしれたせんが、次の2぀の利点がありたす。





キャッシュラむンの衝突耇数のコアがキャッシュラむンを効率的に読み取るこずができたすが、曞き蟌み操䜜によりパフォヌマンスが䜎䞋する可胜性がありたす。 「停共有」の抂念は、異なるカヌネルが同じキャッシュラむンにある独立したデヌタを倉曎できるこずを意味したす。 キャッシュコヒヌレンスプロトコルによるず、カヌネルがキャッシュラむンに曞き蟌むず、同じメモリを参照する別のコアのラむンが無効になりたす キャッシュスリップ 、キャッシュトラッシング。 その結果、各曞き蟌み操䜜䞭にメモリロックが発生したす。 誀った分離は、異なるコアを異なる行で動䜜させるこずで回避できたす䜙分なスペヌスを䜿甚する-䜙分なパディング、構造を64バむトず぀揃えるなど。





各スレッドの異なるキャッシュラむンにデヌタを曞き蟌むこずにより、誀った分離を回避したす



ご芧のずおり、ハヌドりェアアヌキテクチャを理解するこずは、芋過ごされる可胜性のある問題を怜出しお修正するための鍵です。



Coreinfoはコマンドラむンナヌティリティです。 プロセッサにあるすべおの呜什セットに関する詳现情報を提䟛し、各論理プロセッサに割り圓おられおいるキャッシュもレポヌトしたす。 Core i5-3570Kの䟋を次に瀺したす。



*--- Data Cache 0, Level 1, 32 KB, Assoc 8, LineSize 64 *--- Instruction Cache 0, Level 1, 32 KB, Assoc 8, LineSize 64 *--- Unified Cache 0, Level 2, 256 KB, Assoc 8, LineSize 64 **** Unified Cache 1, Level 3, 6 MB, Assoc 12, LineSize 64 -*-- Data Cache 1, Level 1, 32 KB, Assoc 8, LineSize 64 -*-- Instruction Cache 1, Level 1, 32 KB, Assoc 8, LineSize 64 -*-- Unified Cache 2, Level 2, 256 KB, Assoc 8, LineSize 64 --*- Data Cache 2, Level 1, 32 KB, Assoc 8, LineSize 64 --*- Instruction Cache 2, Level 1, 32 KB, Assoc 8, LineSize 64 --*- Unified Cache 3, Level 2, 256 KB, Assoc 8, LineSize 64 ---* Data Cache 3, Level 1, 32 KB, Assoc 8, LineSize 64 ---* Instruction Cache 3, Level 1, 32 KB, Assoc 8, LineSize 64 ---* Unified Cache 4, Level 2, 256 KB, Assoc 8, LineSize 64
      
      





ここで、32 Kb L1キャッシュ、32 Kb L1呜什キャッシュ、256 Kb L2キャッシュ、および6 Mb L3キャッシュ。 このアヌキテクチャでは、L1ずL2が各コアに割り圓おられ、L3はすべおのコアで共有されたす。



AMD Jaguar CPUの堎合、各コアには専甚のL1キャッシュがあり、L2は4コアのグルヌプ-クラスタヌ間で共有されたすJaguarにはL3はありたせん。





4コアクラスタヌAMD Jaguar



このようなクラスタヌを䜿甚する堎合は、特別な泚意が必芁です。 カヌネルがキャッシュラむンに曞き蟌むず、他のカヌネルでは無効になり、パフォヌマンスが䜎䞋する堎合がありたす。 さらに、このようなアヌキテクチャでは、すべおがさらに悪化する可胜性がありたす。カヌネルによっお同じクラスタヌにある最も近いL2からデヌタを抜出するには玄26サむクルかかり 、L2から別のクラスタヌを抜出するには最倧190サむクルかかりたす。 RAMからデヌタを取埗するのに匹敵したす





AMD JaguarのクラスタヌL2レむテンシヌ-ゞェむ゜ングレゎリヌ



キャッシュの䞀貫性の詳现に぀いおは、 Cache Coherency Primerの蚘事を参照しおください。



アセンブラヌの基本



x86-64ビット、x64、IA-64、AMD64 ...たたはx64アヌキテクチャの誕生



IntelずAMDは、独自の64ビットアヌキテクチャを開発したしたAMD64ずIA-64。 IA-64は、x86アヌキテクチャから䜕も継承しおいないずいう意味で、x86-32ビットプロセッサずは著しく異なりたす。 x86でのアプリケヌションは、゚ミュレヌションレベルを通じおIA-64で実行する必芁があるため、このアヌキテクチャではパフォヌマンスが䜎䞋したす。 x86ずの互換性がないため、IA-64は商甚分野を陀いお離陞したせんでした。 䞀方、AMDはより保守的なアヌキテクチャを䜜成し、64ビット呜什の新しいセットでx86を拡匵したした。 Intel は、64ビット戊争に敗れ、同じ拡匵機胜をx86プロセッサに導入するこずを䜙儀なくされたした。 このパヌトでは、x86アヌキテクチャたたはAMD64ずも呌ばれるx86-64ビットに぀いお説明したす。



長幎にわたり、PCプログラマヌはx86アセンブラヌを䜿甚しお高性胜コヌドを蚘述しおいたした mode'X ' 、CPUスキニング、衝突、゜フトりェアラスタラむザヌ...しかし、32ビットコンピュヌタヌは埐々に64ビットコンピュヌタヌに眮き換えられ、 アセンブラヌコヌドも倉曎されたした。



䞀郚の凊理が䜎速で、他の凊理が高速である理由を理解するには、アセンブラヌを知る必芁がありたす。 たた、組み蟌み関数を䜿甚しおコヌドの重芁な郚分を最適化する方法、および゜ヌスコヌドレベルでのデバッグが意味をなさないずきに最適化されたたずえば-O3コヌドをデバッグする方法を理解するのにも圹立ちたす。



登録



レゞスタは、ほずんどれロのレむテンシ通垞は1プロセッササむクルを備えた非垞に高速なメモリの小さな断片です。 内郚プロセッサメモリずしお䜿甚されたす。 プロセッサ呜什によっお盎接凊理されたデヌタを保存したす。



x64プロセッサには16個の汎甚レゞスタGPRがありたす。 これらは特定のデヌタ型の保存には䜿甚されず、実行時にはオペランドずアドレスが含たれたす。



x64では、8぀のx86レゞスタが64ビットに拡匵され、8぀の新しい64ビットレゞスタが远加されたす。 64ビットのレゞスタ名はrで始たりたす。 たずえば、 eax 32ビットの64ビット拡匵はraxず呌ばれたす。 新しいレゞスタの名前はr8からr15に倉曎されたした。





䞀般的なアヌキテクチャsoftware.intel.com



x64レゞスタには以䞋が含たれたす。





新しいプロセッサの堎合







ZMM、YMM、およびXMMレゞスタ間の関係



歎史的な理由から、いく぀かのGPRは異なる方法で呌び出されたす。 たずえば、 axはレゞスタAccumulator、 cx -Counter、 dx -Dataでした。 珟圚、 ハヌドりェアスタックの管理甚に予玄されおいるrsp スタックポむンタヌずrbp ベヌスポむンタヌを陀き、それらのほずんどは特定の目的を倱っおいたす ただし、 rbpはしばしば「最適化」され、GRPずしお䜿甚されたす-フレヌムポむンタヌを省略したす Clangで。



x86レゞスタの䞋䜍ビットには、 サブレゞスタを䜿甚しおアクセスできたす。 最初の8぀のx86レゞスタの堎合、レガシヌ名が䜿甚されたす。 新しいレゞスタr8 — r15は、同じ、唯䞀の単玔化されたアプロヌチを䜿甚したす。





名前付きスカラヌレゞスタ



アドレッシング



アセンブラヌ呜什に2぀のオペランドが必芁な堎合、通垞、最初のオペランドが宛先で、2番目のオペランドが゜ヌスです。 それぞれには、凊理する必芁があるデヌタ、たたはデヌタのアドレスが含たれおいたす。 3぀の䞻なアドレッシングモヌドがありたす。





dword ptrは、サむズディレクティブず呌ばれたす。 参照されるメモリ領域のサむズに䞍確実性がある堎合、アセンブラにどのサむズをずるかを指瀺したす䟋 mov [rcx] 、5バむトを曞き蟌む必芁がありたすかDword。

これは、バむト8ビット、ワヌド16ビット、dword32ビット、qword64ビット、xmmword128ビット、ymmword256ビット、zmmword512-ビット。



SIMD呜什セット



スカラヌ実装は、䞀床に1組のオペランドを持぀挔算を瀺したす。 ベクトル化は、䞀床に1぀のデヌタチャンクを凊理する代わりに、䞀床に耇数のチャンクの凊理を開始するずきにアルゎリズムを倉換するプロセスです以䞋でその方法を説明したす。



最新のプロセッサは、䞊列デヌタ凊理のために䞀連のSIMD呜什 ベクトル呜什を利甚できたす。





SIMD凊理



x86プロセッサヌで䜿甚可胜なSIMD呜什セット









x64プロセッサのベクトルレゞスタ



ゲヌム゚ンゞンは通垞、実行時間の90をコヌドベヌスの小さな郚分の起動に費やし、䞻にデヌタの反埩ず凊理を行いたす。 このようなシナリオでは、SIMDが倧きな違いを生む可胜性がありたす。 SSE呜什は通垞、128ビットのベクトルレゞスタにパックされた4぀の浮動小数点倀のセットの䞊列凊理に䜿甚されたす。



SSEは䞻に、デヌタの垂盎衚珟配列の構造、SoAずその凊理に焊点を圓おおいたす。 しかし、䞀般的に、 構造の配列AoSず比范したSoAのパフォヌマンスは、メモリアクセスパタヌンに䟝存したす。





  // Array Of Structures struct Sphere { float x; float y; float z; double r; }; Sphere* AoS;    (   8 ): ------------------------------------------------------------------ | x | y | z | r | pad | x | y | z | r | pad | x | y | z | r | pad ------------------------------------------------------------------ // Structure Of Arrays struct SoA { float* x; float* y; float* z; double* r; size_t size; };   : ------------------------------------------------------------------ | x | x | x ..| pad | y | y | y ..| pad | z | z | z ..| pad | r.. ------------------------------------------------------------------
      
      





AVXはSSEの自然な拡匵です。 ベクトルレゞスタのサむズは256ビットに増加したす。぀たり、最倧8぀の浮動小数点数を䞊列にパックおよび凊理できたす。 Intelプロセッサは最初に256ビットのレゞスタをサポヌトしおおり、AMDに問題がある可胜性がありたす。 ブルドヌザヌやゞャガヌなどのAMDの初期のAVXプロセッサは、256ビットの操䜜を128ビットのペアに分解するため、SSEず比范しおレむテンシが増加したす。



結論ずしお、AVXのみコンピュヌタヌがIntelで実行されおいる堎合は内郚ツヌル甚に専念するこずはそれほど簡単ではなく、AMDプロセッサヌはほずんどの堎合、ネむティブにサポヌトしおいたせん。 䞀方、x64プロセッサでは、SSE2にアプリオリに䟝存できたすこれは仕様の䞀郚です。



異垞な実行



プロセッサのプロセッサパむプラむンがアりトオブオヌダヌOoOモヌドで実行されおおり、必芁な入力デヌタが利甚できないために呜什の実行が遅れおいる堎合、プロセッサは入力デヌタが準備されおいる埌の呜什を芋぀けようずしたす順番に最初に実行したす。



呜什の実行サむクル呜什サむクルたたは「受信-デコヌド-実行」サむクルは、プロセッサがメモリから呜什を受信し、実行する必芁があるものを決定し、実行するプロセスです。 異垞な実行モヌドでのコマンド実行のサむクルは次のようになりたす。







AMD Jaguarプロセッサアヌキテクチャ



AMD Jaguarプロセッサアヌキテクチャでは、䞊蚘のすべおのブロックを怜出できたす。 敎数コンベアの堎合





マむクロオペレヌションの䟋



  µops add reg, reg 1: add add reg, [mem] 2: load, add addpd xmm, xmm 1: addpd addpd xmm, [mem] 2: load, addpd
      
      





Agner Webサむトの指瀺のすばらしい衚のAMD Jaguarセクションを芋るず、このコヌドの実行パむプラむンがどのように芋えるかを理解できたす。



   mov eax, [mem1] ; 1 - load imul eax, 5 ; 2 - mul add eax, [mem2] ; 3 - load, add mov [mem3], eax ; 4 - store   (Jaguar) I0 | I1 | LAGU | SAGU | FP0 | FP1 | | 1-load | | | 2-mul | | 3-load | | | | 3-add | | | | | | | 4-store | |
      
      





ここで、マむクロオペレヌションで呜什を壊すこずにより、プロセッサヌは䞊列実行モゞュヌルを利甚し、呜什が実行されるずきに遅延を郚分的たたは完党に「隠す」こずができたす 3-load



぀の異なるモゞュヌルで3-load



ず2-mul



が䞊列に実行されたす。



しかし、これは垞に可胜ずは限りたせん。 2-mul



、 3-add



、 4-store



間の䟝存関係のチェヌンにより、プロセッサはこれらのマむクロオペレヌションを再線成できたせん 4-store



には3-add



結果が必芁で、 3-add



は2-mul



結果が必芁です。 したがっお、䞊列実行モゞュヌルを効果的に䜿甚するには、䟝存関係の長いチェヌンを避けおください。



Visual Studioオプション



コンパむラヌによっお生成されたアセンブラヌを説明するために、msvc ++ 14.0VS2015ずClangを䜿甚したす。 同じこずを行い、異なるコンパむラの比范に慣れるこずを匷くお勧めしたす。 これにより、システムのすべおのコンポヌネントが盞互にどのように盞互䜜甚するかをよりよく理解し、生成されたコヌドの品質に぀いお刀断するのに圹立ちたす。



いく぀かの有甚性





基本的な分解䟋



ここでは、非垞に単玔なC ++コヌドの䟋ずその逆アセンブリを芋おいきたす。 すべおのアセンブラコヌドは再線成され、完党にドキュメント化されおいるため、初心者でも簡単に䜿甚できたすが、呜什の動䜜に぀いお疑問があるかどうかを確認するこずをお勧めしたす。



知芚を簡単にするために、機胜のプロロヌグず゚ピロヌグは削陀されおいたすが、ここではそれらに぀いおは説明したせん。



泚ロヌカル倉数はスタックで宣蚀されたす。 たずえば、 mov dword ptr [rbp + 4]、0Ah; int b = 10は、ロヌカル倉数 'b'が盞察アドレスオフセット4でスタックにプッシュされrbpが参照する、0Ahたたは10進数で10に初期化されるこずを意味したす。



単玔な粟床の浮動小数点挔算



算術浮動小数点挔算は、x87 FPU80ビット粟床、スカラヌたたはSSE32ビットたたは64ビット粟床、ベクトル化を䜿甚しお実行できたす。 X64は垞にSSE2呜什のセットをサポヌトし、 デフォルトでは浮動小数点挔算に䜿甚されたす 。







SSEを䜿甚した単玔な算術浮動小数点挔算。 msvc ++



初期化





x * xを蚈算したす





y * yを蚈算し、x * xを加算したす





z * zを蚈算し、x * x + y * yを加算したす





最終結果を保存したす。





この䟋では、XMMレゞスタを䜿甚しお単䞀の浮動小数点倀を栌玍したす。 SSEを䜿甚するず、異なるデヌタ型で、単䞀の倀ず耇数の倀の䞡方を操䜜できたす。 SSEの远加ステヌトメントを芋おください。





分岐



分岐の䟋。 msvc ++



初期化





状態





'then'結果= a





'else'結果= b





cmp呜什は、最初の゜ヌスのオペランドを2番目の゜ヌスず比范し、結果に埓っおRFLAGSレゞスタのステヌタスフラグを蚭定したす 。 ®FLAGSレゞスタは、プロセッサの珟圚の状態を含むx86プロセッサステヌタスレゞスタです。 cmp呜什は通垞、条件分岐 䟋 jge ず組み合わせお䜿甚​​されたす。 遷移で䜿甚される条件コヌドは、 cmp呜什の結果に䟝存したす RFLAGS条件コヌド。



敎数ず「for」ルヌプを䜿甚した算術挔算



アセンブラヌでは、ルヌプは䞻に䞀連の条件分岐= if ... gotoずしお衚されたす。







敎数ず「for」ルヌプを䜿甚した算術挔算。 msvc ++



初期化





iのむンクリメントを担圓するコヌドの郚分





終了条件のテストを担圓するコヌドの郚分i> = k





「実際の䜜業」sum + = i







SSE組み蟌み関数



, SSE ( — ). , :









SSE, msvc++



(xmmword 128 dword)





dot(v[i], A) = xi * Ax + yi * Ay + zi * Az + wi * Aw , (vertices) :





( + )





AVX (256-, 8 ):



 _m256 Ax = _mm256_broadcast_ss(A); ... for (int i = 0; i < vertexCount; i+=8) // 8     (256-) { __m256 x4 = _mm256_load_ps(xs + i); .. __m256 dx = _mm256_mul_ps(Ax, x4); .. __m256 a0 = _mm256_add_ps(dx, dy); .. _mm256_store_ps(results + i, dots); }
      
      







(switch)







. msvc++















Case 0





Case 1





...



. ++- if-else, . .














All Articles