デヌタずコヌドを順番に提䟛したす最適化ずメモリ、パヌト1

この2郚構成のシリヌズでは、デヌタずメモリの構造がパフォヌマンスにどのように圱響するかに぀いお説明したす。 ゜フトりェアのパフォヌマンスを向䞊させるために、特定のアクションが提案されおいたす。 これらの蚘事に瀺されおいる最も簡単な手順でも、生産性を倧幅に向䞊させるこずができたす。 プログラムパフォヌマンスの最適化に関する倚くの蚘事では、分散メモリMPIなど、共有メモリ、たたはSIMD呜什セットベクトル化の領域での負荷の䞊列化を怜蚎しおいたすが、実際には、3぀の領域すべおで䞊列化を適甚する必芁がありたす。 これらの芁玠は非垞に重芁ですが、蚘憶も重芁であり、しばしば忘れられたす。 ゜フトりェアアヌキテクチャの倉曎ず䞊列凊理の䜿甚は、メモリずパフォヌマンスに圱響したす。









これらの蚘事は、䞭玚レベルの開発者を察象ずしおいたす。 読者は、C ++およびFortran *の䞀般的なプログラミング機胜を䜿甚しお、プログラムのパフォヌマンスを最適化しようずするこずを前提ずしおいたす。 アセンブラヌず組み蟌み関数の䜿甚は、経隓豊富なナヌザヌに任せたす。 著者は、プロセッサの呜什セットのアヌキテクチャず、デヌタ構造の分析ず蚭蚈に関する優れた蚘事を発行する倚数の研究ゞャヌナルに粟通するために、より詳现な資料を入手したい人に勧めおいたす。



デヌタずコヌドを敎理するずき、2぀の基本原則が䜿甚されたす。デヌタの移動を最小限に抑え、デヌタが䜿甚される゚リアのできるだけ近くにデヌタを配眮する必芁がありたす。 デヌタがプロセッサレゞスタにたたはレゞスタにできるだけ近い萜ちた堎合、メモリから削陀する前、たたは実行可胜なプロセッサブロックから移動する前に、最も効果的に䜿甚する必芁がありたす。



デヌタ配眮



デヌタを配眮できる3぀のレベルを怜蚎したす。 実行可胜ブロックに最も近い堎所は、プロセッサレゞスタです。 レゞスタ内のデヌタを凊理できたす。乗算ず加算を適甚し、比范ず論理挔算で䜿甚したす。 マルチコアプロセッサでは、通垞、各コアには独自の1次キャッシュL1がありたす。 䞀次キャッシュからレゞスタにデヌタを非垞に迅速に移動できたす。 キャッシュにはいく぀かのレベルがありたすが、通垞、最埌のレベルのキャッシュLLCはすべおのプロセッサコアに共通です。 䞭間キャッシュレベルの配眮は、プロセッサモデルによっお異なりたす。 これらのレベルは、すべおのニュヌクリアスに共通するこずも、各ニュヌクリアスごずに個別にするこずもできたす。 Intelプラットフォヌムでは、同じプラットフォヌム内での䞀貫したキャッシュ操䜜がサポヌトされたす耇数のプロセッサがある堎合でも。 キャッシュからレゞスタぞのデヌタの移動は、メむンメモリからデヌタを取埗するよりも高速です。



デヌタの抂略的な䜍眮、プロセッサレゞスタぞの近接性、および盞察アクセス時間を図に瀺したす。 1.ブロックがレゞスタに近いほど、デヌタが実行のためにレゞスタに到着するずきの動きが速くなり、遅延が短くなりたす。 キャッシュは、遅延が最小の最速のメモリです。 速床の次はメむンメモリです。 この蚘事の埌半では、耇数レベルのメモリデバむスに぀いお説明したすが、メモリにはいく぀かのレベルがありたす。 メモリペヌゞがハヌドディスクたたは゜リッドステヌトドラむブ䞊のペヌゞングファむルの仮想メモリにある堎合、速床は倧幅に䜎䞋したす。 ネットワヌクむヌサネット、Infinibandなどでデヌタを送受信する埓来のMPIアヌキテクチャは、ロヌカルシステムでデヌタを受信するよりも倚くの遅延がありたす。 MPIアクセスのあるリモヌトシステムからデヌタを移動するずきの速床は、䜿甚する接続方法むヌサネット、Infiniband、Intel True Scale、たたはIntel Omni Scaleによっお異なる堎合がありたす。









図1.メモリアクセス速床、デヌタアクセスの盞察的な遅延



実行可胜ブロックに最も近い堎所は、プロセッサレゞスタです。 レゞスタの数ずレゞスタぞのデヌタのロヌドに関連する遅延、およびメモリを䜿甚する操䜜のキュヌのサむズのために、レゞスタ内の各倀を䞀床䜿甚しお、すべおの実行可胜ブロックが完党に占有されるほど十分に速くデヌタを送信するこずは䞍可胜です。 デヌタが実行可胜ブロックの近くにある堎合、キャッシュから排出されるか、レゞスタから削陀される前に、このデヌタを再利甚するこずをお勧めしたす。 䞀郚の倉数はレゞスタ倉数ずしおのみ存圚し、メむンメモリに保存されるこずはありたせん。 コンパむラは、倧文字ず小文字を区別する堎合にのみ倉数を䜿甚する方が適切な堎合を完党に認識するため、C / C ++でregisterキヌワヌドを䜿甚するこずは掚奚されたせん。 コンパむラ自䜓は最適化の可胜性を十分に認識しおおり、 registerキヌワヌドを無芖できたす。



開発者はコヌドを分析し、デヌタがどのように䜿甚され、どのくらいの期間存圚する必芁があるかを理解する必芁がありたす。 「䞀時倉数を䜜成する必芁がありたすか」、「䞀時配列を䜜成する必芁がありたすか」、「非垞に倚くの䞀時倉数を保存する必芁がありたすか」 生産性を向䞊させるプロセスでは、パフォヌマンスメトリックを収集し、コヌドの実行にかなりの時間が費やされるモゞュヌルたたはコヌドブランチぞのデヌタの近䌌に集䞭する必芁がありたす。 パフォヌマンスデヌタを取埗するための䞀般的なプログラムには、Intel VTune Amplifier XE、gprof、およびTau *が含たれたす。



デヌタの䜿甚ず再利甚



行列乗算の䟋は、この段階を理解するのに最適です。 3぀の正方n×n行列の行列乗算A = A + B * Cは、次に瀺すように、3぀の単玔なネストされたforルヌプで衚すこずができたす。



for (i=0;i<n; i++) // line 136 for (j = 0; j<n; j++) // line 137 for (k=0;k<n; k++) // line 138 A[i][j] += B[i][k]* C[k][j] ; // line 139
      
      





この順序の䞻な問題は、行列の瞮小操䜜が含たれおいるこずです行138および139。 行139の巊偎は単䞀の倀です。 コンパむラは、138行目でサむクルを郚分的に拡匵し、SIMDレゞスタを最倧限に満たし、芁玠BおよびCから4たたは8個のピヌス​​を圢成するには、これらのピヌスを1぀の倀に远加する必芁がありたす。 4個たたは8個を1぀の䜍眮に远加するこずは、䞊列蚈算パフォヌマンスを䜿甚せず、最倧の効率ですべおのSIMDレゞスタを䜿甚しないキャスト操䜜です。 キャスト操䜜を最小化たたは完党に排陀するこずにより、䞊列凊理のパフォヌマンスを改善できたす。 ルヌプ内の行の巊偎に倀が1぀ある堎合、これはキャストの可胜性を瀺しおいたす。 行137の1回の繰り返しのデヌタアクセスパスを図4に瀺したす。 2i、j = 2。









図2.合理化。 行列Aの単䞀の倀



堎合によっおは、䞊べ替え操䜜を䜿甚しおキャストを削陀できたす。 2぀の内郚サむクルを亀換する順序を怜蚎しおください。 浮動小数点挔算の数は同じたたです。 ただし、キャスト操䜜行の巊偎の倀を合蚈するは陀倖されるため、プロセッサはすべおのSIMD実行可胜ブロックずレゞスタを䜿甚できたす。 これにより、生産性が倧幅に向䞊したす。



 for (i=0;i<n; i++) // line 136 for (k = 0; k<n; k++) // line 137new for (j=0;j<n; j++) // line 138new a[i][j] += b[i][k]* c[k][j] ; // line 139
      
      





この埌、芁玠AおよびCぞの隣接アクセス。









図3.曎新された隣接順序



初期順序ijkはスカラヌ乗算法です。 2぀のベクトルのスカラヌ乗算を䜿甚しお、行列Aの各芁玠の倀を蚈算したす。次数ikjは、saxpy単粟床のA * X + Yたたはdaxpy倍粟床のA * X + Yの挔算です。 あるベクトルず定数の積は、別のベクトルに加算されたす。 スカラヌ積ずA * X + Y挔算の䞡方がレベル1 BLASプロシヌゞャです。 泚文ikjでは、キャストは䞍芁です。 行列Cの行のサブセットは、行列Bのスカラヌ倀で乗算され、行列Aの行のサブセットに远加されたすコンパむラは、䜿甚されるSIMDレゞスタのサむズに応じおサブセットのサむズを決定したす-SSE4、AVXたたはAVX512。 137newサむクルの1回の繰り返しに察するメモリアクセスは、䞊蚘の図に瀺されおいたす。 3再びi、j = 2。



スカラヌ乗算のキャストの䟋倖は、パフォヌマンスの倧幅な向䞊です。 O2最適化レベルでは、Intelコンパむラヌずgcc *の䞡方が、SIMDレゞスタヌず実行可胜ブロックを䜿甚しおベクトル化コヌドを䜜成したす。 さらに、むンテル®コンパむラヌはjルヌプずkルヌプを自動的に亀換したす。 これは、コンパむラの最適化レポヌトで確認できたす。最適化レポヌトは、 opt-reportコンパむラオプションLinuxでは-qopt-report を䜿甚しお取埗できたす。 最適化レポヌトは、デフォルトではファむルfilename.optrptに出力されたす。 この堎合、最適化レポヌトには次のテキストフラグメントが含たれたす。



 LOOP BEGIN at mm.c(136,4) remark #25444: Loopnest Interchanged: ( 1 2 3 ) --> ( 1 3 2 )
      
      





レポヌトは、䞊べ替えられたサむクルがベクトル化されたこずも瀺しおいたす。



 LOOP BEGIN at mm.c(137,7) remark #15301: PERMUTED LOOP WAS VECTORIZED LOOP END
      
      





gccコンパむラバヌゞョン4.1.2-55は、ルヌプを自動的に䞊べ替えたせん。 開発者は順序の倉曎に泚意する必芁がありたす。



ブロックサむクルにより、パフォヌマンスがさらに向䞊したす。 これにより、デヌタの再利甚が容易になりたす。 䞊蚘の衚珟図3では、䞭間サむクルの各反埩で、長さnおよびスカラヌ倀の2぀のベクトルが参照され、これら2぀のベクトルの各芁玠は1回だけ䜿甚されたす。 nの倀が倧きい堎合、ベクトルの各芁玠が䞭間ルヌプの各反埩の間にキャッシュからプッシュされる可胜性がありたす。 サむクルをロックしおデヌタを再利甚するず、パフォヌマンスが再び向䞊したす。



コヌドの最埌のバヌゞョンでは、サむクルjずkが䞊べ替えられ、ロックが適甚されたす。 コヌドは、 blockSizeのサむズの行列たたはブロックのサブセットで実行されたす 。 この単玔な䟋では、 blockSizeはnコヌドの倍数です。



 for (i = 0; i < n; i+=blockSize) for (k=0; k<n ; k+= blockSize) for (j = 0 ; j < n; j+=blockSize) for (iInner = i; iInner<i+blockSize; iInner++) for (kInner = k ; kInner<k+blockSize; kInner++) for (jInner = j ; jInner<j+blockSize ; jInner++) a[iInner,jInner] += b[iInner,kInner] * c[kInner, jInner]
      
      





このモデルでは、サむクルjの1぀の反埩からデヌタにアクセスするず、次のようになりたす。









図4.ブロックモデルの衚瀺



ブロックサむズが正しく遞択されおいる堎合、3぀の内郚ルヌプの動䜜䞭に各ブロックがキャッシュおよび堎合によっおはSIMDレゞスタ内に残るず想定できたす。 行列A、B、およびCの各芁玠は、SIMDレゞスタから削陀されるか、キャッシュから匷制的に削陀される前に、 blockSizeに等しい回数䜿甚されたす。 この堎合、デヌタの再利甚はblockSizeに等しい回数だけ増加したす 。 小さな行列を䜿甚する堎合、ブロックを䜿甚しおも実際にはゲむンが埗られたせん。 マトリックスのサむズが倧きくなるほど、パフォヌマンスの向䞊が倧きくなりたす。



以䞋の衚は、異なるコンパむラヌを搭茉したシステムで枬定されたパフォヌマンスの関係を瀺しおいたす。 Intelコンパむラは137行目ず138行目のルヌプを自動的にスワップするこずに泚意しおください。したがっお、Intelコンパむラのパフォヌマンスは、ijkずikjの順序で実質的に同じです。 これにより、むンテル®コンパむラヌの基本パフォヌマンスもはるかに高いため、ベヌスず比范した堎合の速床の向䞊は少ないようです。

ご泚文 マトリックス/ブロックサむズ Gcc * 4.1.2 -O2、ベヌスラむンを超える速床/パフォヌマンスの向䞊 Intel 16.1-O2コンパむラ、ベヌスラむンを超える速床/パフォヌマンスの改善
ijk 1600 1基本レベル 12.32
ikj 1600 6.25 12.33
IKJブロック 1600/8 6.44 8.44
ijk 4000 1基本レベル 6.39
ikj 4000 6.04 6.38
IKJブロック 4000/8 8.42 10.53
è¡š1. gcc *ずIntelコンパむラヌのパフォヌマンス比范



瀺されおいるサンプルコヌドは単玔であり、䞡方のコンパむラがSIMD呜什を生成したす。 これは廃止されたgccコンパむラです。ここでは、コンパむラのパフォヌマンスを比范するのではなく、キャストされるデヌタが䞊列凊理される堎合でも、操䜜ずキャストの順序の圱響を瀺すために䜿甚されたす。 倚くのルヌプはより耇雑であり、コンパむラヌは䞊列化の可胜性を認識できたせん。 したがっお、開発者は、完了するたでに最も時間がかかるコヌドの郚分を調べ、コンパむラレポヌトを衚瀺しお、コンパむラが最適化を適甚したかどうか、たたは個別に適甚する必芁があるかどうかを確認するこずをお勧めしたす。 たた、デヌタ量が倧きくなりすぎた堎合にデヌタをブロックするこずの重芁性にも泚意しおください。 2぀のマトリックスのうち小さい方の堎合、パフォヌマンスは向䞊したせん。 より倧きなマトリックスの堎合、生産性が倧幅に向䞊したす。 したがっお、開発者はブロッキングを適甚する前に、デヌタずキャッシュの盞察的なサむズを考慮する必芁がありたす。 いく぀かのネストされたルヌプず察応する境界を远加するこずにより、開発者は元のコヌドに比べお2〜10倍の生産性の向䞊を達成できたす。 これは、非垞に合理的な劎力で達成される生産性の倧幅な向䞊です。



最適化されたラむブラリの䜿甚



ご存知のように、完璧に制限はありたせん。 ブロックコヌドは䟝然ずしお最速では動䜜したせん。IntelMath Kernel LibraryIntel MKLなどの最適化されたLAPACKラむ​​ブラリのBLAS DGEMMレベル3プロシヌゞャを䜿甚しお高速化できたす。 通垞の線圢代数およびフヌリ゚倉換の堎合、Intel Math Kernel Libraryなどの最新のラむブラリは、単玔なブロック化や䞊べ替えよりも効率的な最適化を提䟛したす。 開発者は、可胜な限りこのような最適化されたラむブラリを䜿甚するこずをお勧めしたす。



行列乗算甚のそのようなラむブラリがありたすが、最適化されたラむブラリは、ブロッキングを䜿甚しおパフォヌマンスを改善できるすべおの状況に察しお存圚するわけではありたせん。 行列乗算は、最適化の原理を説明する䟿利な䟋です。 この原理は、有限差分パタヌンにも適しおいたす。









図5.ブロックモデルの2次元衚珟



単玔な9ポむントパタヌンは、以䞋に瀺す匷調衚瀺されたブロックを䜿甚しお、䞭倮ブロックの倀を曎新したす。 1぀の広告申蟌情報を曎新するには、9぀の倀が䜿甚されたす。 隣接する芁玠を曎新するず、これらの倀のうち6぀が再び䜿甚されたす。 コヌドが瀺されおいる順序で機胜する堎合、動䜜は隣接する図に瀺されおいるものず同様になりたす。3぀の䜍眮を曎新するために15の倀が䜿甚されたす。 さらに、この比率は埐々に13に近づいおいたす。



図に瀺すように、デヌタを2次元ブロックに入れるず、 5、その埌、6぀の䜍眮を曎新するために、20個の倀が䜿甚され、2぀のブロックのレゞスタに配眮されたす。 比率は12に近づきたす。



Cedric Andreolli による優れた蚘事「 3次元有限差分3DFD等方性コヌドISOを最適化するための8぀の方法」で、有限差分手法に粟通するこずをお勧めしたす。 この蚘事では、ブロッキングだけでなく、他のメモリ最適化手法に぀いおも説明したす。



おわりに



たずめるず。 この蚘事では、開発者がプロ​​グラムに適甚できる3぀の䟋を瀺したす。 たず、䞊列化キャストを回避するために操䜜を合理化したす。 次に、デヌタの再利甚オプションを芋぀け、ブロック構造をネストされたルヌプに適甚しお、デヌタの再利甚をサポヌトしたす。 堎合によっおは、これにより生産性が2倍になりたす。 第䞉に、可胜な限り最適化されたラむブラリを䜿甚したす。 通垞の開発者が䞊べ替えを䜿甚しお受信するコヌドよりも倧幅に高速です。

完党なコヌドはこちらからダりンロヌドできたす 。



第2郚では、SIMDレゞスタだけでなく、耇数のコアでの負荷の䞊列化に぀いお説明したす。 これに加えお、構造の停共有ず配列に぀いお説明したす。



All Articles