MultiClet用LLVMコンパイラ:WhetStoneベンチマーク

多細胞アーキテクチャの議論では、その中に存在する自然な並列性の量の文脈における特定のタスクへの適用性がしばしば議論されました。 そのため、さまざまなベンチマーク、特にCoreMark 実行する際に、グループ内のセルが作業中に並行して実行される十分な数のコマンドを抽出できないアルゴリズムのかなり厳密なシーケンスのため、このようなプログラムとマルチセルラーアーキテクチャとの矛盾について話しました。 この記事では、WhetStoneベンチマークを使用して、より示唆的な条件でマルチレットを評価します。


WhetStoneテストは、実行される計算の性質がCoreMarkの利点と異なります。条件付き遷移テストを除く、それに含まれるすべてのテストは、ある程度の内部並列性を持っています。 テストは2つのバージョンで実行されました。 最初の-Multiclet R1-LLVMコンパイラの現在のバージョンは、次のオプションでコンパイルされました:

-ffast-math -fno-builtin -O3 

2番目のオプションである-Multiclet R1 *、-テストは、現在コンパイラーに追加されている「最適化された」手動の高度な最適化の導入により実行されました。 手動の改良は、ループの複数の反復を組み合わせることにより、コンパイラーが線形セクションを増やすのに役立つように削減されました。

結果

システムMHzMWIPS / MHzMFLOPS1 / MHzMFLOPS2 / MHzMFLOPS3 / MHzCOS MOPS / MHzEXP MOPS / MHzFIXPT MOPS / MHzIF MOPS / MHzEQUAL MOPS / MHz
マルチクレットR1 *1000.7210.2560.2120.1620.0180.0083.5690.4171.57
RPi 2 v7-A710000.5850.280.2910.2480.0110.0061.3141.2090.981
RPi 3 v8-A5312000.6040.2760.290.2480.010.0071.2671.5611.014
ARM v8-A5313000.6420.2680.2410.2390.0280.0041.1971.4360.439
Core i7 4820K39000.8870.3410.3080.1670.0230.0140.9981.5040.251
コアi7 1 CP30660.8730.3250.2950.1740.0250.0130.8920.9580.167
天才II30000.7990.3070.270.1110.0260.0160.8351.0010.167
アスロン6422110.7850.3080.2720.1040.0260.0160.8320.9990.187
チュリオン64 M19000.8840.3020.2580.1450.0260.0160.8270.9880.187
コアi5 2467M23000.8530.2960.2980.1630.0220.0130.8070.9930.222
コア2デュオ1 CP24000.8850.3370.3070.1980.0240.0120.8040.810.176
セレロンC2 M2000年0.8680.2970.2960.1940.0230.0120.7780.7810.172
コア2デュオm18300.8780.3370.3050.1970.0240.0120.7510.7850.174
マルチクレットr11000.3110.1570.1530.0290.0180.0080.7140.0810.143
セレロンm12950.8320.3240.2970.1780.0220.0120.6310.9230.173
ラズベリーパイ10000.3910.1370.1460.1230.0090.0040.6171.0140.805
アスロンXP20880.8560.3070.2740.1390.0260.0160.5760.9980.166
Pentium Pro2000.790.3320.2780.1460.0230.0130.5750.7550.149
アスロン4バートン18000.8460.3050.2720.1370.0260.0160.5710.9880.165
セレロンa4500.760.2910.2760.140.0220.0120.5690.7510.147
ペンティアム4E30000.390.1820.1640.0580.0140.0060.3230.270.126
アトムm16000.3480.1760.1570.0510.010.0070.2520.7440.11
ペンティアム419000.3830.2140.1880.0560.0120.0060.2410.4270.118
Pentium MMX2000.6150.3280.2670.0790.0250.0130.1980.730.186
ペンティアム1000.6040.3220.2670.0780.0250.0130.1920.5680.183
80486DX2660.1820.0760.0680.0260.0080.0050.1050.2120.017
*有望なLLVMコンパイラ最適化を使用するオプション

マルチレットは、CoreMark / MHzよりもMWIPS / MHzではるかに自信があるように見えることがわかります(この記事で以前に公開された図)。 次のことがわかります。



WhetStoneに含まれるテストは、4つのグループに分けることができます。 最初のグループには、浮動小数点計算のパフォーマンスのテストが含まれます。 これらのテストの結果により、 MFLOPS1MFLOPS2MFLOPS3のパフォーマンスが決まります。 LLVMコンパイラの追加の最適化を使用すると、3つのテストすべてで大幅に高速化されることがわかります。

MFLOPS1インジケーターの例によって得られた加速度の性質を考慮し、例として浮動小数点演算の最初のテストを使用して、この結果がどのように達成されるかを調べます。 Cテストコード:

 timea = dtime(); { for (ix=0; ix<xtra; ix++) { for(i=0; i<n1*n1mult; i+=5) { e1[0] = (e1[0] + e1[1] + e1[2] - e1[3]) * t; e1[1] = (e1[0] + e1[1] - e1[2] + e1[3]) * t; e1[2] = (e1[0] - e1[1] + e1[2] + e1[3]) * t; e1[3] = (-e1[0] + e1[1] + e1[2] + e1[3]) * t; } t = 1.0 - t; } t = t0; } timeb = dtime(); 

既存のバージョンのLLVMを使用してテストをコンパイルすると、内部ループの本体に対して次のアセンブリコードが取得されます。

 jmp LBB2_4 SR4 := rdq #IR7, 2160 SR5 := rdq #IR7, 2152 SR6 := rdq #IR7, 2144 SR7 := rdq #IR7, 2136 SR8 := rdq #IR7, 2128 SR9 := rdq #IR7, 2120 SR10:= subf @SR6, @SR5 SR11:= subf @SR5, @SR6 SR12:= addf @SR5, @SR6 SR5 := addf @SR10, @SR4 SR10:= addf @SR11, @SR4 SR4 := addf @SR10, @SR7 SR7 := mulf @SR4, @SR8 SR10:= addf @SR5, @SR7 SR5 := subf @SR4, @SR10 SR11:= subf @SR10, @SR4 SR4 := mulf @SR10, @SR8 SR10:= mulf @SR5, @SR8 SR5 := addf @SR12, @SR10 SR10:= addf @SR11, @SR5 SR11:= mulf @SR5, @SR8 SR5 := mulf @SR10, @SR8 SR10:= addf @SR5, @SR6 SR5 := mulf @SR10, @SR8 wrq @SR9, #IR7, 2760 wrq @SR5, #IR7, 2752 wrq @SR11, #IR7, 2744 wrq @SR4, #IR7, 2736 wrq @SR7, #IR7, 2728 

このセクションの命令の多くは、並行して実行できることがわかります。 ただし、複数の反復を1つに組み合わせると、メモリなしでセルラー媒体内で実行されるコード部分を大幅に拡張でき、反復間の中間結果を保存する時間も節約できます。

反復を結合する手順の後、ループの本体は次の形式になります
 jmp LBB2_4 SR4 := rdq #IR7, 272 SR5 := rdq #IR7, 264 SR6 := rdq #IR7, 256 SR7 := rdq #IR7, 248 SR8 := rdq #IR7, 320 SR9 := rdq #IR7, 240 SR10 := rdq #IR7, 232 SR11 := addf @SR4, @SR5 SR5 := addf @SR7, @SR6 SR12 := addf @SR11, @SR6 SR13 := subf @SR12, @SR7 SR12 := mulf @SR13, @SR8 SR14 := addf @SR12, @SR4 SR4 := addf @SR14, @SR11 SR11 := subf @SR14, @SR6 SR6 := addf @SR11, @SR7 SR11 := subf @SR13, @SR6 SR12 := subf @SR6, @SR13 SR13 := mulf @SR11, @SR8 SR11 := addf @SR5, @SR13 SR5 := addf @SR12, @SR11 SR12 := addf @SR11, @SR4 SR13 := mulf @SR5, @SR8 SR5 := mulf @SR12, @SR8 SR12 := addf @SR13, @SR7 SR7 := mulf @SR12, 0x3f000000 SR12 := subf @SR5, @SR7 SR5 := addf @SR12, @SR6 SR6 := addf @SR12, @SR11 SR13 := subf @SR5, @SR11 SR11 := addf @SR5, @SR4 SR4 := mulf @SR13, @SR8 SR5 := mulf @SR11, @SR9 SR11 := addf @SR4, @SR7 SR4 := subf @SR11, @SR12 SR12 := subf @SR6, @SR11 SR6 := mulf @SR12, @SR8 SR11 := subf @SR13, @SR12 SR12 := addf @SR6, @SR7 SR6 := mulf @SR8, @SR11 SR11 := addf @SR4, @SR12 SR4 := mulf @SR12, @SR8 SR13 := mulf @SR11, @SR8 SR11 := addf @SR4, @SR5 SR4 := addf @SR13, @SR7 SR5 := mulf @SR4, 0x3f000000 SR4 := subf @SR11, @SR5 SR7 := addf @SR4, @SR12 SR12 := addf @SR6, @SR4 SR6 := mulf @SR12, @SR8 SR12 := addf @SR6, @SR5 SR13 := addf @SR6, @SR11 SR6 := subf @SR12, @SR4 SR4 := subf @SR7, @SR12 SR7 := mulf @SR4, @SR8 SR4 := addf @SR7, @SR5 SR7 := addf @SR6, @SR4 SR6 := addf @SR4, @SR13 SR11 := mulf @SR7, @SR8 SR7 := mulf @SR6, @SR8 SR6 := addf @SR11, @SR5 SR5 := mulf @SR6, 0x3f000000 SR6 := subf @SR7, @SR5 SR7 := addf @SR6, @SR12 SR11 := addf @SR6, @SR4 SR12 := subf @SR7, @SR4 SR4 := addf @SR7, @SR13 SR8 := moveq @SR8 SR9 := moveq @SR9 SR10 := moveq @SR10 SR7 := mulf @SR12, @SR8 SR13 := mulf @SR4, @SR9 SR4 := addf @SR7, @SR5 SR7 := subf @SR4, @SR6 SR6 := subf @SR11, @SR4 SR4 := mulf @SR6, @SR8 SR9 := subf @SR12, @SR6 SR6 := addf @SR4, @SR5 SR4 := mulf @SR8, @SR9 SR9 := addf @SR7, @SR6 SR7 := mulf @SR6, @SR8 SR11 := mulf @SR9, @SR8 SR9 := addf @SR7, @SR13 SR7 := addf @SR11, @SR5 SR5 := mulf @SR7, 0x3f000000 SR7 := subf @SR9, @SR5 SR11 := addf @SR7, @SR6 SR6 := addf @SR4, @SR7 SR4 := mulf @SR6, @SR8 SR12 := addf @SR4, @SR5 SR13 := addf @SR4, @SR9 SR4 := subf @SR12, @SR7 SR7 := subf @SR11, @SR12 SR9 := mulf @SR7, @SR8 SR11 := subf @SR6, @SR7 SR6 := addf @SR9, @SR5 SR7 := mulf @SR8, @SR11 SR9 := addf @SR4, @SR6 SR4 := addf @SR13, @SR6 SR11 := mulf @SR9, @SR8 SR9 := mulf @SR4, @SR8 SR4 := addf @SR11, @SR5 SR5 := mulf @SR4, 0x3f000000 SR4 := subf @SR9, @SR5 SR9 := addf @SR7, @SR4 SR7 := addf @SR4, @SR6 SR6 := mulf @SR4, @SR8 SR11 := mulf @SR9, @SR8 SR9 := addf @SR11, @SR5 SR11 := subf @SR7, @SR9 SR7 := subf @SR9, @SR4 SR4 := mulf @SR9, @SR8 SR9 := mulf @SR11, @SR8 SR11 := addf @SR9, @SR5 SR9 := addf @SR7, @SR11 SR7 := mulf @SR11, @SR8 SR11 := mulf @SR9, @SR8 SR8 := addf @SR11, @SR5 SR5 := mulf @SR8, 0x3f000000 wrq @SR10, #IR7, 384 wrq @SR6, #IR7, 376 wrq @SR4, #IR7, 368 wrq @SR7, #IR7, 360 wrq @SR5, #IR7, 352 

テストの2番目のグループは、基本的な数学関数の速度を評価し、 COS MOPSおよびEQUAL MOPSによって特徴付けられます。 主な負荷は数学ライブラリにかかるため、コンパイラの最適化はこれらのテストのパフォーマンスに大きな影響を与えません。 これらのテストの結果に大きなマイナスの影響を与えたのは、使用した数学ライブラリが古いP1プロセッサ用に作成されており、新しいR1プロセッサの多くの利点を使用していなかったためです。

テストの3番目のグループは、整数演算パフォーマンステスト( FIXPT MOPS指数 )とアレイパフォーマンステスト( EQUAL MOPS指数)を組み合わせることができます。 このグループのテストは、最初のグループの生産性を向上させるすべてのプロセスの影響を受けます。さらに、ループの反復を組み合わせて得られる線形セクションの増加は、標準のLLVMコンパイラ最適化ツールを使用して最適化できます。 これらの最適化により、必要な中間計算の数が大幅に削減され、R1の最終テストスコアが対応するIntelおよびARMスコアよりも1.5〜2倍高いという事実につながります。

最後のグループには、IF MOPSメトリックを使用した条件分岐パフォーマンステストが含まれます。 このテストのパフォーマンスが低いのは、テストの順序が厳密であり、その結果、必要な量の並列性が不足しているためです。

したがって、プロセッサの現在のリビジョンは、十分な長さの線形セクションと内部に十分な数の相互依存命令を備えており、ARMおよびIntelコアの現在のバージョンに匹敵する実行速度を提供します。 インジケーターMFLOPS1MFLOPS2MFLOPS3で良好な結果が達成されています。 FIXPT MOPSおよびEQUAL MOPSの優れた結果は、 マルチセルラーアーキテクチャの機能だけでなく、増加した線形セクションで実行されるアルゴリズムのコンパイラー最適化の結果とも関連しています。 COS MOPSおよびEXP MOPSは 、数学ライブラリの最適化への十分な注意によって決定される指標でないため、今後改善される予定です。

コンパイラ自体に関しては、 前回の記事の執筆以来、マルチセルラーアーキテクチャの機能が大幅に拡張されています。

  1. 64ビット整数演算のサポートが追加されました。
  2. デバッグ情報を生成する機能が追加されました。
  3. ターゲットが追加されました(-targetオプション)。これにより、単精度のリアルタイム演算のみを使用してアセンブラーコードが生成されます(double、long double型は、float型のように32ビットのサイズです)。
  4. 32ビットの書き込み命令のみの使用を保証するコンパイラオプションが追加されました(32ビット値のみを書き込むことができるR1プロセッサの外部メモリの実装の特性により、この必要性が生じました)。
  5. ライブラリ関数memset()、memcpy()、memmov()は最適に実装されています。
  6. ベクトル命令のコンパイラーサポートの可能性について研究が行われましたが、R1プロセッサー自体でサポートされているベクトル命令のセットが限られているため、その結果はこの機能を実装する必要性を明らかにしませんでした。

一般に、LLVMコンパイラはバージョン3.8.1に更新されています。

Source: https://habr.com/ru/post/J307512/


All Articles