0

OpenCLコンパイラが最適化するために生成するマシンコードを理解しようとしています。したがって、ツールm2s-opencl-kc(multi2simから)を使用して* .clファイルをオフラインコンパイルし、中間ファイル(スイッチ:-a)を*.isaファイルとして保持しました。この*.isaには、私が探しているもののように見える「分解」セクションが含まれています...

注:私のアセンブリの知識は少し「古い」ものです。Pentium386/486CPUなどの古いCPU用のアセンブリを作成しました。ですから、私は実際にベクトル命令を読むのに問題がありますが、それらについての理論的な知識はあります。

[... OTHER STUFF ... ]
; --------  Disassembly --------------------
00 ALU_PUSH_BEFORE: ADDR(32) CNT(6) KCACHE0(CB2:0-15) KCACHE1(CB0:0-15)
      0  x: MOV         R2.x,  0.0f
         z: SETGT_INT   R0.z,  1,  KC0[0].y
         t: MULLO_INT   ____,  R1.x,  KC1[1].x
      1  w: ADD_INT     ____,  R0.x,  PS0
      2  y: ADD_INT     R2.y,  PV1.w,  KC1[6].x
      3  x: PREDE_INT   ____,  R0.z,  0.0f      UPDATE_EXEC_MASK UPDATE_PRED
01 JUMP  POP_CNT(1) ADDR(9)
02 ALU: ADDR(38) CNT(5) KCACHE0(CB1:0-15)
      4  x: MOV         R2.x,  0.0f
         y: MOV         R3.y,  0.0f
         w: LSHL        ____,  R2.y,  2
      5  z: ADD_INT     R2.z,  KC0[0].x,  PV4.w
03 LOOP_DX10 i0 FAIL_JUMP_ADDR(8)
    04 ALU: ADDR(43) CNT(11) KCACHE0(CB2:0-15)
          6  y: ADD_INT     R3.y,  R3.y,  1
             w: LSHL        ____,  R3.y,  2
          7  x: SETGT_INT   R3.x,  KC0[0].y,  PV6.y
             z: ADD_INT     ____,  R2.z,  PV6.w
             w: ADD_INT     ____,  PV6.w,  8
          8  x: ASHR        R0.x,  PV7.w,  4
             y: LSHR        R0.y,  PV7.z,  2
             z: BFE_UINT    R0.z,  PV7.w,  0x00000002,  0x00000002
[... some more ... ]

私が疑問に思っているのは、コマンドの前にある数字と文字の意味です。私が理解したように、コンパイラはいくつかの「複雑な」命令を次のように生成しました。

00 ALU_PUSH_BEFORE: ADDR(32) CNT(6) KCACHE0(CB2:0-15) KCACHE1(CB0:0-15)

(質問:それはいわゆる「VeryLong InstructionWord」ですか?)

そして、この「複雑な」命令は、次のような複数の「単純な」命令で構成されています。

      0  x: MOV         R2.x,  0.0f
         z: SETGT_INT   R0.z,  1,  KC0[0].y
         t: MULLO_INT   ____,  R1.x,  KC1[1].x
      1  w: ADD_INT     ____,  R0.x,  PS0
      2  y: ADD_INT     R2.y,  PV1.w,  KC1[6].x
      3  x: PREDE_INT   ____,  R0.z,  0.0f      UPDATE_EXEC_MASK UPDATE_PRED

これらの「単純な」命令は、各ベクトル単位の命令のようです。4つのベクトル単位は、x、y、z、およびwによって参照されます。しかし、「t」とは何ですか?それは別のベクトル単位ですか?「サイプレス」GPU用にコンパイルしました...

さて、数字について...これらは「行番号」のようなものですか?先行ゼロ:複素数命令のシリアル番号...?先行ゼロなし:単純命令のシリアル番号...?

メモリアクセスの待機状態がないと仮定すると、同じシリアルを持つすべての「単純な」命令を1サイクルで「論理的に」実行できると思います。たとえば、(上記の複雑な命令の)次の命令はサイクル0で「実行」されます。

      0  x: MOV         R2.x,  0.0f
         z: SETGT_INT   R0.z,  1,  KC0[0].y
         t: MULLO_INT   ____,  R1.x,  KC1[1].x

「実行された」とは、ある種の(たとえば4サイクルの)パイプライン処理があることを意味します。これは、上記の命令がサイクル0で実行を開始し、サイクル3の後に終了する必要があることを意味します。

パイプラインに関する質問

次の命令(「1」など)がレジスタR2.xを読み取るとどうなりますか?それはR2.xの古い値(命令「0」の前)を読み取るのでしょうか、それとも命令「0」が終了するまで命令「1」を遅らせるのでしょうか?それとも、これは「気にしない」状況(未定義の結果を生成する)であり、コンパイラーがこれが決して起こらないように注意しなければならない状況ですか?

メモリアクセスに関する質問

レジスタへのアクセスは、データフェッチサイクル中に待たずに実行できると思います。メモリアクセスには、アクセスするメモリの種類に応じて、追加のサイクルが必要になります。

  • 「__private」メモリは、ほとんどがレジスタにマップされている必要があります。
  • __ローカルメモリ(同じグループの作業項目間で最大64KBを共有):現在のGPUで何サイクル余分に期待する必要がありますか?
  • __グローバルメモリ:これは、たとえば256MBからxGBの外部DRAMである必要があります。ここで何サイクル余分に期待する必要がありますか?私の知る限り、このメモリはGPUデバイス用にキャッシュされていません。
  • __定数メモリは__グローバルメモリのようにする必要がありますが、__ローカルメモリを使用してキャッシュされます

「ISA」の良いチュートリアルはありますか?

よろしく、ステファン

4

1 に答える 1

2

「番号付き」セクションのそれぞれは、単一のVLIWです。次に例を示します。

  4  x: MOV         R2.x,  0.0f
     y: MOV         R3.y,  0.0f
     w: LSHL        ____,  R2.y,  2

これは、使用可能な3つのALU、つまり「x」、「y」、および「w」を使用する1つの命令です。次のように、最大​​並列命令を構成する「z」と「t」を使用することもできます。

  4  x: MOV         R2.x,  0.0f
     y: MOV         R3.y,  0.0f
     z: MOV         R3.z,  0.0f
     w: LSHL        ____,  R2.y,  2
     t: LSHL        ____,  R2.z,  4

それでも、これはシェーダーコアの5つのALUレーンすべてに「フィード」する単一のVLIW命令であり、5つの操作が1つのステップで並行して実行されます。

しかし、「t」とは何ですか?それは別のベクトル単位ですか?

はい、「t」は「超越」と呼ばれる5番目のスカラー単位であり、またはのような超越計算を実行するために使用できます。また、通常のスカラー演算も実行できますが、「x」から「w」で可能なすべてのスカラー演算が「t」でも実行できるわけではないという制限があります。したがって、理想的には、各コアは1つのステップで5つのスカラー演算を実行できます。CPUのSSE命令とは異なり、これらの5つのユニットは独立して動作することに注意してください。SSEユニットでは、複数のデータに並行して適用できる操作は1つだけです。sin(x)cos(x)およびVLIWアーキテクチャ。

それらの

01 JUMP  POP_CNT(1) ADDR(9)

命令は明らかに、(オフチップ)メモリからのデータのフェッチや制御フロー命令など、ALUで実際に操作を実行しない特別な命令です。

メモリレイテンシの見積もりを取得するには、AMDのOpenCLプログラミングガイドの付録D-デバイスパラメータを参照してください。

__constantメモリはメモリとまったく同じではありません。すべて__localの作業項目で同じである独自のメモリスペースがチップ上にあり、ドキュメントによると、コヒーレンシロジックがないため、メモリの約2倍の速度でアクセスできます。作業項目の間に必要です。__local

インターネット上の一部の情報源は、(AMD)GPUにはキャッシュメモリがなく、LDSメモリを使用してキャッシュを明示的にエミュレートする必要があると述べています。一部のドキュメントで、L1およびL2キャッシュへの参照があります。

いずれにせよ、GPUは、1つのスレッドがデータの待機で停止したときに、実行の「コンテキスト」を非常に高速に切り替えることで、メモリの待機時間を「隠す」のに非常に優れていることに注意してください。選択するのに十分な並列タスクが与えられると、GPUは、待機する必要のあるタスクと交換できる、実行の準備ができているタスクを常に見つける可能性があります。

于 2013-07-13T17:11:58.987 に答える