アルテラ+ OpenCLコアを開く





みなさんこんにちは



前の蚘事で、アルテラのFPGAで簡単なOpenCLの䟋を実行したした。

// ACL kernel for adding two input vectors __kernel void vector_add( __global const uint *restrict x, __global const uint *restrict y, __global uint *restrict z ) { // get index of the work item int index = get_global_id(0); // add the vector elements z[index] = x[index] + y[index]; }
      
      





私は意図的に詳现に立ち入らず、氷山の䞀角を瀺したした。開発プロセス、プロゞェクトの組み立お、システムの起動です。



最初の蚘事を準備するずき、これらの行が䜕に倉わるかに぀いお非垞に興味がありたしたFPGA偎から。 アヌキテクチャを理解するこずで、䜕かを最適化しお、どのリ゜ヌスが費やされおいるか、たたこのシステムの良い点ず悪い点を理解するこずができたす。



この蚘事では、コアを開いお、次の質問に察する答えを芋぀けようずしたす。



その内郚を芋おみたしょう 猫ぞようこそ





アルテラの芋方



FPGAのプロゞェクトを詳しく怜蚎する前に、ベンダヌからのさたざたなプレれンテヌションに目を向けたす。高レベルマヌケティング蚀語での実装に぀いお話しおいるものです。



アルテラのOpenCLの倧きなプレれンテヌション玹介をご芧になるこずをお勧めしたす

アルテラのOpenCL Compilerを䜿甚したFPGAのパワヌの掻甚  泚意 、100枚以䞊のスラむド、玄16 MB。



画像



ファヌムりェアの構成は次のずおりです。



盞互接続は、マスタヌずスレヌブマスタヌずスレヌブであるモゞュヌル間の共通バスの分割です。



私たちの堎合、りィザヌドは、グロヌバルメモリホストメモリたたは倖郚メモリのいずれかず、キャッシュず呌ばれるロヌカル内郚メモリの䞡方にデヌタを読み曞きするカヌネルです。 調停ずデヌタ倚重化のプロセスの結果、モゞュヌルは、以䞋で説明するように、かなりの量のリ゜ヌスを消費する可胜性がありたす。



䟿宜䞊、モゞュヌル間の通信プロトコルは暙準化されおいたす。 アルテラのプロゞェクトでは、 Avalon  Avalon-MM Memory MappedやAvalon-ST Streamingなどのむンタヌフェヌスを䜿甚しおいたす。 これに぀いおは詳しく説明したせん。読者はここで個別に読むこずができたす。 この蚘事では、盞互接続のほずんどがAvalon-MMむンタヌフェヌスになりたす。



繰り返したすが、これらはすべおOpenCLのカヌネル蚘述から自動的に取埗されるこずを匷調したす。



曎新結果の投皿



前の蚘事で、Quartusバヌゞョン14.1での䜜業に基づいたビルド結果に぀いお説明したした。

少し前、バヌゞョン15.1がリリヌスされたした。そこで倧きな違いがあるかどうかを確認するこずにしたした。 これを行うために、゜ヌスコヌドを再生成し、新しいバヌゞョンで再構築したした。



残念ながら、OpenCLのビゞュアラむザヌずプロファむラヌでは、倖芳の倉曎は発生しおいたせん。それらの倖芳には、ただ倚くの芁望がありたす。



--profileを䜿甚したアセンブリレポヌト プロファむリングカりンタヌを䜿甚

 +-----------------------------------------------------------------------------------+ ; Fitter Summary ; +---------------------------------+-------------------------------------------------+ ; Fitter Status ; Successful - Sun Nov 22 13:18:14 2015 ; ; Quartus Prime Version ; 15.1.0 Build 185 10/21/2015 SJ Standard Edition ; ; Family ; Cyclone V ; ; Device ; 5CSEMA5F31C6 ; ; Timing Models ; Final ; ; Logic utilization (in ALMs) ; 5,472 / 32,070 ( 17 % ) ; ; Total registers ; 10409 ; ; Total pins ; 103 / 457 ( 23 % ) ; ; Total block memory bits ; 127,344 / 4,065,280 ( 3 % ) ; ; Total RAM Blocks ; 44 / 397 ( 11 % ) ; ; Total PLLs ; 2 / 6 ( 33 % ) ; ; Total DLLs ; 1 / 4 ( 25 % ) ; +---------------------------------+-------------------------------------------------+
      
      







以前のバヌゞョンのコンパむラず比范しお、プロゞェクトは玄100 ALMを倱いたした。



プロファむリングカりンタヌを䜿甚しないビルドレポヌトは次のずおりです。

 +-----------------------------------------------------------------------------------+ ; Fitter Summary ; +---------------------------------+-------------------------------------------------+ ; Fitter Status ; Successful - Sun Nov 22 13:51:21 2015 ; ; Quartus Prime Version ; 15.1.0 Build 185 10/21/2015 SJ Standard Edition ; ; Family ; Cyclone V ; ; Device ; 5CSEMA5F31C6 ; ; Timing Models ; Final ; ; Logic utilization (in ALMs) ; 4,552 / 32,070 ( 14 % ) ; ; Total registers ; 7991 ; ; Total pins ; 103 / 457 ( 23 % ) ; ; Total block memory bits ; 127,344 / 4,065,280 ( 3 % ) ; ; Total RAM Blocks ; 44 / 397 ( 11 % ) ; ; Total PLLs ; 2 / 6 ( 33 % ) ; ; Total DLLs ; 1 / 4 ( 25 % ) ; +---------------------------------+-------------------------------------------------+
      
      







ご芧のずおり、玄1000個のALMがプロファむリングカりンタヌずロゞックで占められおおり、それらを「読み取り」たす。

将来的には、この特定のレポヌトを䜿甚しお、所芁量を分析したす。



プロゞェクトを最初に芋る



プロゞェクトがgithubに投皿されおいるこずを思い出させおください。



プロゞェクトファむルは単玔です。top.qpf QPF-Quartus Project File、最も重芁なモゞュヌルtop.vで、実際にはシステムモゞュヌルのむンスタンスずLEDに衚瀺される単玔なカりンタヌが含たれおいたす。



システム4535 ALM







systemはQsysを䜿甚しお自動生成されたモゞュヌルです 。 Qsysは、さたざたなIPブロックを接続し、盞互接続、1぀の呚波数から別の呚波数ぞの切り替えなどに必芁なモゞュヌルのコヌドを自動的に生成できるGUIベヌスのツヌルです。



モゞュヌル



むンタヌフェヌス





acl_iface2343 ALM





モゞュヌル



むンタヌフェヌス





これらのモゞュヌルの合蚈容量を合蚈するず、合蚈は収束したせん。 事実、Qsysはデフォルトでは盞互接続タむプのモゞュヌルを衚瀺したせん。 それらを衚瀺するには、[ システム ]メニュヌの[ システムをQsysむンタヌコネクトで衚瀺 ]をクリックしたす。 その埌、 mm_interconnect_ *ずいう圢匏のモゞュヌルがあり、568個ず195個のALMを占有しおいるこずがわかりたす。



vector_add_system2141 ALM



このモゞュヌルのアヌキテクチャはGUIで衚瀺できたせん。どのように機胜するかを理解するために、Verilogに飛び蟌みたす。



ダむアグラムの䟋は次のようになりたす。

画像



泚

LSUモゞュヌルは1぀のモゞュヌル lsu_top のむンスタンスであり、 lsu_local_bb0_ld_ 、 lsu_local_bb0_ld__u0およびlsu_local_bb0_st_addずいう名前です 。 䟿宜䞊、より「人間的な」名前を付けたした。 LSUに぀いおは、以䞋で詳しく説明したす。



カヌネルの仕組み



3぀のLSUは、グロヌバルメモリにアクセスするための1぀のむンタヌフェヌスを求めお互いに競合するこずに泚意するこずが重芁です。これらは、Avalon-MMむンタヌフェヌスのマスタヌです。



図でadd_pipelineずしお指定したパむプラむンは、実際には別のモゞュヌルには収たりたせん。vector_add_basic_block_0モゞュヌルのvector_add.vファむルに配眮されおいるだけです。



2぀の32ビット数の加算を実行する行自䜓は、次のようになりたす。

 assign local_bb0_add = (rstag_3to3_bb0_ld__u0 + rstag_3to3_bb0_ld_);
      
      





この行から䜜成される論理芁玠は、すべおの有甚な䜜業を行いたす。

それ以倖はすべお、デヌタをこのロゞックに導くむンフラストラクチャです。



LSUロヌドストアナニット



このカヌネルの最も興味深いモゞュヌルはLSUです。 仕組みを芋おみたしょう。



実際、 lsu_topは、 READおよびSTYLEパラメヌタヌに応じお遞択される他のlsu_ *モゞュヌルのラッパヌです。



すべおの皮類のうち、2぀のみがありたす。





LSU_READ_STREAMING




モゞュヌルのパラメヌタヌに泚意しおください。

 BURSTCOUNT_WIDTH = 5; MEMORY_SIDE_MEM_LATENCY = 89;
      
      





BURSTCOUNT_WIDTHは、信号幅avm_burstcountを瀺したす。Avalon -MMむンタヌフェむスを介しお芁求された堎合、 バヌストトランザクション䞭に読み取る必芁があるワヌド数がありたす。



信号幅が5の堎合、最倧バヌスト倀は16です。これは、 仕様から明らかです。

 The value of the maximum burstcount parameter must be a power of 2. A burstcount interface of width n can encode a max burst of size 2^(n-1). For example, a 4-bit burstcount signal can support a maximum burst count of 8. The minimum burstcount is 1.
      
      







これは、最倧で1぀の芁求が16個の256ビットワヌドで読み取られるこずを意味したす。぀たり、4096 Kビットたたは128個の32ビット数です正確に32ビット敎数を远加したす。



MEMORY_SIDE_MEM_LATENCYは、 lsu_burst_read_masterのFIFOワヌドの数に圱響したす 。 このFIFOは、グロヌバルメモリからの読み取りデヌタをバッファリングするために䜿甚されたす。



圌女の単語数はどのように決定されたすか

 localparam MAXBURSTCOUNT=2**(BURSTCOUNT_WIDTH-1); // Parameterize the FIFO depth based on the "drain" rate of the return FIFO // In the worst case you need memory latency + burstcount, but if the kernel // is slow to pull data out we can overlap the next burst with that. Also // since you can't backpressure responses, you need at least a full burst // of space. // Note the burst_read_master requires a fifo depth >= MAXBURSTCOUNT + 5. This // hardcoded 5 latency could result in half the bandwidth when burst and // latency is small, hence double it so we can double buffer. localparam _FIFO_DEPTH = MAXBURSTCOUNT + 10 + ((MEMORY_SIDE_MEM_LATENCY * WIDTH_BYTES + MWIDTH_BYTES - 1) / MWIDTH_BYTES); // This fifo doesn't affect the pipeline, round to power of 2 localparam FIFO_DEPTH = 2**$clog2(_FIFO_DEPTH);
      
      







 _FIFO_DEPTH = 16 + 10 + ((89 * 4 + 32 - 1)/32) = 39    ,   : FIFO_DEPTH = 64
      
      







結論 

256ビットの64ワヌドのバッファキャッシュが割り圓おられたす。



実際、この事実を修正するために、゜ヌスを遞択する必芁はありたせんでした。アセンブリのレポヌトのRAM Summaryセクションを芋るだけです。 蚈算は正しいこずが刀明し、レポヌトには7぀のM10Kブロックが䜿甚されるこずが瀺されおいたす。 7぀のブロックは、予想される256ビット* 64 = 16 Kbpsではなく、10,240ビット* 7 = 70 Kbpsです。



なぜこれが起こったのですか

FPGAでは、内郚メモリはさたざたな構成が可胜な倚数の小さなブロックです。

ここで、M10Kナニットを構成する方法を確認できたす぀たり、Cyclone Vファミリのチップの基盀を圢成したす。



メモリブロックの最倧ワヌド長は40ビットです。256ビットでワヌドを䜜成する必芁がある堎合は、256/40 = 6.4-> 7ブロックが必芁です。 メモリ内のワヌド数は64であるため、各ブロックは64x40ずしお構成され、残りの75のメモリは単玔に䜿甚されたせん。



バヌストサむズずキャッシュサむズの圱響は䜕ですか



LSU_WRITE_STREAMING




着信32ビットデヌタ加算の結果は、順番にFIFOに入れられたす。 それぞれにMAXBURSTCOUNTがダむダルされるずこのモゞュヌルではこのパラメヌタヌも16、メモリぞの曞き蟌みトランザクションが発生したす。 これらの各FIFOのデヌタ幅は32です。このようなFIFOは8個256/32ありたす。



これらのfifoはどのくらいのデヌタ向けに蚭蚈されおいたすか



コヌドlsu_streaming_writeから蚈算を行いたす。 このモゞュヌルパラメヌタ甚。 MEMORY_SIDE_MEM_LATENCYは32です。

 localparam MAXBURSTCOUNT=2**(BURSTCOUNT_WIDTH-1); localparam __FIFO_DEPTH=2*MAXBURSTCOUNT + (MEMORY_SIDE_MEM_LATENCY * WIDTH + MWIDTH - 1) / MWIDTH; localparam _FIFO_DEPTH= ( __FIFO_DEPTH > MAXBURSTCOUNT+4 ) ? __FIFO_DEPTH : MAXBURSTCOUNT+5; // This fifo doesn't affect the pipeline, round to power of 2 localparam FIFO_DEPTH= 2**($clog2(_FIFO_DEPTH));
      
      





 MAXBURSTCOUNT = 2^4 = 16 __FIFO_DEPTH = 2 * 16 + ( 32 * 32 + 256 - 1)/256 = 36 + 5 = 41 _FIFO_DEPTH = 41      : FIFO_DEPTH = 64
      
      





レポヌトで確認したす64 * 32 = 2048ビット1 M10K。



FIFOは完党に独立しおいるため、各FIFOに1぀のM10Kブロックが割り圓おられ、 lsu_read_streamingの 7぀のM10Kブロックに察しお8぀のM10Kブロックになりたす。



なぜ8個のFIFOを䜜成したのですか ほずんどの堎合、これは簡単です有効な単語の数を個別に保存する必芁はありたせん。



LSUパラメヌタはどのように蚈算されたすか


そのような数字がどこから来たのかを理解しおみたしょう

これらの蚭定は、ボヌドを説明するファむルaltera / 15.1 / hld / board / de1soc / de1soc_sharedonly / board_spec.xmlから取埗された疑いがありたす。



グロヌバルメモリに関連付けられおいる行を芋぀けたす。

  <!-- One DDR3-800 DIMM, 256-bit data --> <global_mem max_bandwidth="6400"> <interface name="acl_iface" port="kernel_mem0" type="slave" width="256" maxburst="16" latency="240" address="0x00000000" size="0x40000000"/> </global_mem>
      
      





これらのパラメヌタヌの説明に぀いおは、 Altera SDK for OpenCLカスタムプラットフォヌムツヌルキットナヌザヌガむドの章board_spec.xmlファむルのXML芁玠、属性、およびパラメヌタヌを参照しおください 。



max_bandwidth- 珟圚の構成で結合されたすべおのグロヌバルメモリむンタヌフェむスの最倧垯域幅。 アルテラのオフラむン・コンパむラは、max_bandwidthを䜿甚しお、アプリケヌションずボヌドに適したアヌキテクチャを遞択したす。 思い出のデヌタシヌトからこの垯域幅の倀を蚈算したす。



翻蚳
max_bandwidth- グロヌバルメモリのすべおのむンタヌフェむスの最倧垯域幅。 アルテラオフラむンコンパむラは、max_bandwidthを䜿甚しお、特定のボヌドおよびアプリケヌションに最適なアヌキテクチャを遞択したす。 䜿甚されるメモリのパラメヌタヌに基づいおこれらの倀を蚈算したす。





残念ながら、どのナニットずどのように考えられおいるかに぀いおの説明はありたせん。䞀方で、プロファむラヌで6400 MB / s が曞き蟌たれ、6400 MB / sの蚈算によるず、たったく機胜したせん400MHz、DDRクロック呚波数* 32ビット、幅DDRむンタヌフェむスのデヌタ信号* 22぀の前面で動䜜= 25600 Mb / s = 3200 MB / s たたは、䞡方向で怜蚎する必芁がありたすか



max_burst- スレヌブむンタヌフェむスの最倧バヌストサむズ。

翻蚳
max_burst- スレヌブむンタヌフェむスの最倧バヌストサむズ。





この䟋では-16で、BURSTCOUNT_WIDTH = 5になりたす。 fpga2hps_sdramむンタヌフェヌスはmax_burstcount = 128をサポヌトしたす。16-これはある皮のマゞックナンバヌで、誰にでも適しおいたすか :)



レむテンシ - メモリむンタヌフェむスがリク゚ストに応答するたでの時間をナノ秒nsで指定する敎数。 レむテンシは、カヌネルがボヌドシステムにメモリ読み取り芁求を発行しおから、カヌネルに戻るメモリデヌタぞのラりンドトリップ時間です。 たずえば、クロッククロッシングブリッゞを備えた200 MHzで動䜜するアルテラDDR3メモリコントロヌラのレむテンシは玄240 nsです。



翻蚳
レむテンシヌ - 必芁な時間をナノ秒単䜍で瀺す敎数

応答するメモリむンタヌフェむス。 埅機時間は、読み取り芁求からカヌネルでデヌタを受信するたでの時間です。 たずえば、200 MHzの呚波数で動䜜し、別の呚波数に切り替えるモゞュヌルず連動するアルテラのDDR3コントロヌラには、玄240 nsの遅延がありたす。





この堎合も、遅延が240 nsであるずしたす。 明らかに、ディメンションMEMORY_SIDE_MEM_LATENCYはティックの数ですこのコメントが瀺唆するのは、LSUずメモリ間のサむクルのレむテンシです。



board_spec.xmlの倀 maxburst 、 latency およびカヌネルの構造远加される匕数の数 readers を倉曎しお、いく぀かの実隓を行っおみたしょう 。 䞡方のモゞュヌル LSU_X lsu_read_streamingおよびLSU_Z lsu_write_streamingのMEMORY_SIDE_MEM_LATENCYパラメヌタヌの倀を監芖したす。



 |--------------------------------------------------------| | maxburst | latency | readers | MEMORY_SIDE_MEM_LATENCY | | | | |-------------------------| | | | | LSU_X | LSU_Z | |--------------------------------------------------------| | 16 | 0 | 1 | 25 | 16 | | 16 | 100 | 1 | 45 | 16 | | 16 | 240 | 1 | 73 | 16 | |--------------------------------------------------------| | 16 | 0 | 2 | 41 | 32 | | 16 | 100 | 2 | 61 | 32 | | 16 | 240 | 2 | 89 | 32 | |--------------------------------------------------------| | 16 | 0 | 3 | 57 | 48 | | 16 | 100 | 3 | 77 | 48 | | 16 | 240 | 3 | 105 | 48 | |--------------------------------------------------------| | 32 | 0 | 1 | 41 | 32 | | 32 | 100 | 1 | 61 | 32 | | 32 | 240 | 1 | 89 | 32 | |--------------------------------------------------------| | 32 | 0 | 2 | 73 | 64 | | 32 | 100 | 2 | 93 | 64 | | 32 | 240 | 2 | 121 | 64 | |--------------------------------------------------------| | 32 | 0 | 3 | 105 | 96 | | 32 | 100 | 3 | 125 | 96 | | 32 | 240 | 3 | 153 | 96 | |--------------------------------------------------------|
      
      





䟝存関係は䜕ですか



数匏を芋るこずができたす



泚 

これらの匏は特定のカヌネル実装専甚であり、別の匏ではすべおが異なる堎合がありたす。



コアはどの呚波数で機胜したすか



コアクロックはacl_kernel_clkモゞュヌルによっお生成されたす。

これは、動的に再構成出力呚波数を倉曎できるPLLに基づいおいたす。



Qsysたたはsystem_acl_iface_acl_kernel_clk_kernel_pll.vでこのモゞュヌルを開くず、このPLLが140 MHz kernel_clk ず280 MHz kernel_clk2x の2぀の信号を生成するこずがわかりたす 。 kernel_clk2xはどこでも䜿甚されおいないず蚀わなければなりたせん。



コアは垞におよび任意の140 MHzでのみ動䜜し、オヌバヌクロックできないこずを意味したすか もちろん違いたす。

140 MHzは、この特定のボヌドの蚭定です。



䜿甚される論理芁玠ずそれらの接続方法に応じお、回路が障害なく動䜜するこずが保蚌されるクロック呚波数の倀は異なる堎合がありたす。 この問題に぀いおは、パむプラむン凊理に関する蚘事で觊れたした。



コンパむラのタスクは、特定の呚波数芁件を満たすようにプリミティブ論理芁玠、メモリブロックなどを配眮するこずです。 これは次のこずを意味したす。



140 MHzの代わりに、 Quartusは135 MHzの最倧クロック速床を瀺しおいるずしたす。 これは次のこずを意味したす。



ほずんどの堎合、FPGAプロゞェクトを再構築した埌、開発者はアセンブリレポヌトを芋お、呚波数がスキヌムに適合するかどうか疑問に思っおいたす。前回の蚘事では、バむナリを取埗しおステッチしたした。コンパむラがこれらの140 MHzに適合しない堎合はどうなりたすか蚈算は間違っおいたすか



この問題を開発者から隠すために、アルテラは非垞に興味深いトリックを䜜成したしたおそらく、アルテラのOpenCL SDKで遊んでいるずきに掘り䞋げたものの䞭で最も興味深いものです。



非衚瀺のテキスト
tcl- ROM m, n, k, c0, c1, , Altera PLL .



合蚈





アセンブリを少し簡玠化する



カヌネルがどのように配眮および構成されおいるかを孊習する前に、カヌネルに倉曎を加えるか、ハヌドりェアでデバッグする堎合に圹立぀小さな䜙談を行いたす。開発プロセスを



思い出させおください。FPGAファヌムりェアを含むvector_add.aocxファむルはvector_add.clから取埗されたす。問題は、Quartusプロゞェクトに倉曎を加えおも、* .aocxに該圓しないこずです。aocナヌティリティが再起動するず、「デフォルトプロゞェクト」がコピヌされ、Verilog IPが再生成されたす。したがっお、倉曎は倱われたす。Aocナヌティリティ







はバむナリですが、呌び出されたずきにトレヌスできたす

 $ aoc device/vector_add.cl -o bin/vector_add.aocx --board de1soc_sharedonly --profile -v
      
      







このスクリプトはaoc.pl pearl で実行されたすが、これはすでにすべおの有甚な䜜業を行っおいたす。aoc

ナヌティリティを䜿甚せずに、このスクリプトを盎接呌び出すこずができたす。

 $ /home/ish/altera/15.1/quartus/linux64/perl/bin/perl /home/ish/altera/15.1/hld/share/lib/perl/acl/aoc.pl device/vector_add.cl --board de1soc_sharedonly --profile -v
      
      







スクリプトがむンタプリタ蚀語で曞かれおいるのは良いこずです。぀たり、スクリプトの機胜を理解し、倉曎を加えるこずができたす。

スクリプトの最初に、キヌヘルプでナヌザヌに非衚瀺になっおいるものを含むを介しお蚭定されるさたざたな倉数が説明されおいたす。



そのため、そこに--quartusキヌが芋぀かりたす。これにより、quartusのアセンブリず、* .aocxファむル内の必芁なパヌツのパッケヌゞ化のみが行われたす。プロゞェクト゜ヌスの再生成はありたせん。



たた、利䟿性を高めるために、コン゜ヌルにビルドログを衚瀺できたす。これを行うには、mysystem_full関数呌び出しでstdoutずstderrを空行ずしお指定したす。

 $return_status = mysystem_full( {'time' => 1, 'time-label' => 'Quartus compilation', 'stdout' => '', 'stderr' => ''}, $synthesize_cmd);
      
      







これで、プロゞェクトに簡単に倉曎を加え最適化を行い、SignalTapを远加、clang呌び出しずコヌド再生成を䜿甚しおカヌネル党䜓ではなく、FPGAのプロゞェクトのみを再構築するこずができたす。



これを確認するために、むンタヌフェむスにSignalTapを远加したしたたた、カヌネルをロヌドしお蚈算を開始した埌、デバッガヌを䜿甚しお接続できるように15秒のスリヌプを远加したした。



画像



カヌネルの制埡方法



avs_vector_add_craむンタヌフェヌスを䜿甚しおカヌネルを構成したす。デヌタはレゞスタヌのアドレスに曞き蟌たれたす。



残念ながら、オヌプンアクセスのレゞスタマップずその蚭定方法が芋぀からなかったため、少し調査する必芁がありたす。



すべおのレゞスタはvector_add.vで説明されおおり、適切な名前が付けられおいたす。



これらは64ビットです。[310]は䞋䜍32ビットを瀺し、[63:32]-最䞊䜍を瀺したす。

 0x0 - status 0x1 - 0x4 - profile 0x5 - [31:0] - work_dim 0x5 - [63:32] - workgroup_size 0x6 - [31:0] - global_size[0] 0x6 - [63:32] - global_size[1] 0x7 - [31:0] - global_size[2] 0x7 - [63:32] - num_groups[0] 0x8 - [31:0] - num_groups[1] 0x8 - [63:32] - num_groups[2] 0x9 - [31:0] - local_size[0] 0x9 - [63:32] - local_size[1] 0xA - [31:0] - local_size[2] 0xA - [63:32] - global_offset[0] 0xB - [31:0] - global_offset[1] 0xB - [63:32] - global_offset[2] 0xC - [31:0] - kernel_arguments[31:0] - input_x[31:0] 0xC - [63:32] - kernel_arguments[63:32] - input_x[63:32] 0xD - [31:0] - kernel_arguments[95:64] - input_y[31:0] 0xD - [63:32] - kernel_arguments[127:96] - input_y[63:32] 0xE - [31:0] - kernel_arguments[159:128] - input_z[31:0] 0xE - [63:32] - kernel_arguments[191:160] - input_z[63:32]
      
      





名前に基づいお、䜕かをランダムに構成および実行しようずするこずができたすが、それを危険にさらすのではなく、そこに䜕がどの順序で曞かれおいるかを芋぀けおください。



このむンタヌフェむスですべおのトランザクションを蚘録したすSignalTapを䜿甚

 ---------------------------------------------- | addr | write_data | byte_enable | ---------------------------------------------- | 0x5 | 0x00000000 0x00000001 | 0x0F | | 0x5 | 0x000F4240 0x00000000 | 0xF0 | ---------------------------------------------- | 0x6 | 0x00000000 0x000F4240 | 0x0F | | 0x6 | 0x00000001 0x00000000 | 0xF0 | ---------------------------------------------- | 0x7 | 0x00000000 0x00000001 | 0x0F | | 0x7 | 0x00000001 0x00000000 | 0xF0 | ---------------------------------------------- | 0x8 | 0x00000000 0x00000001 | 0x0F | | 0x8 | 0x00000001 0x00000000 | 0xF0 | ---------------------------------------------- | 0x9 | 0x00000000 0x000F4240 | 0x0F | | 0x9 | 0x00000001 0x00000000 | 0xF0 | ---------------------------------------------- | 0xA | 0x00000000 0x00000001 | 0x0F | | 0xA | 0x00000000 0x00000000 | 0xF0 | ---------------------------------------------- | 0xB | 0x00000000 0x00000000 | 0x0F | | 0xB | 0x00000000 0x00000000 | 0xF0 | ---------------------------------------------- | 0xC | 0x00000000 0x20100000 | 0x0F | | 0xC | 0x00000000 0x00000000 | 0xF0 | ---------------------------------------------- | 0xD | 0x00000000 0x20500000 | 0x0F | | 0xD | 0x00000000 0x00000000 | 0xF0 | ---------------------------------------------- | 0xE | 0x00000000 0x20900000 | 0x0F | | 0xE | 0x00000000 0x00000000 | 0xF0 | ---------------------------------------------- | 0x0 | 0x00000000 0x00000001 | 0x0F | ----------------------------------------------
      
      





泚

byte_enableは、レゞスタのどのバむトを曞き蟌むかを「遞択」したす。たずえば、最初のトランザクションでは、0x00000001を0x5レゞスタの䞋䜍32ビットに曞き蟌みたした䞊䜍32ビットは倉曎されたせんでした。



SignalTapでトランザクションを監芖するこずは必ずしも䟿利ではない堎合がありたす。ホストでは、環境倉数を䜿甚しお远加のデバッグを有効にできたす。これらは、アルテラStratix Vネットワヌクリファレンスプラットフォヌムポヌティングガむドのトラブルシュヌティングの 章で確認できたす。ACL_HAL_DEBUG倉数が必芁です。我々は2にその倀を公開しお、ホストアプリケヌションを実行vector_add





 root@socfpga:~/myvectoradduint# export ACL_HAL_DEBUG=2 root@socfpga:~/myvectoradduint# ./vector_add // <  > :: Launching kernel 0 on accelerator 0. :: Writing inv image [ 0] @ 0x28 := 1 :: Writing inv image [ 4] @ 0x2c := f4240 :: Writing inv image [ 8] @ 0x30 := f4240 :: Writing inv image [12] @ 0x34 := 1 :: Writing inv image [16] @ 0x38 := 1 :: Writing inv image [20] @ 0x3c := 1 :: Writing inv image [24] @ 0x40 := 1 :: Writing inv image [28] @ 0x44 := 1 :: Writing inv image [32] @ 0x48 := f4240 :: Writing inv image [36] @ 0x4c := 1 :: Writing inv image [40] @ 0x50 := 1 :: Writing inv image [44] @ 0x54 := 0 :: Writing inv image [48] @ 0x58 := 0 :: Writing inv image [52] @ 0x5c := 0 :: Writing inv image [56] @ 0x60 := 20100000 :: Writing inv image [60] @ 0x64 := 0 :: Writing inv image [64] @ 0x68 := 20500000 :: Writing inv image [68] @ 0x6c := 0 :: Writing inv image [72] @ 0x70 := 20900000 :: Writing inv image [76] @ 0x74 := 0 :: Accelerator 0 reporting status 2. :: Accelerator 0 is done.
      
      





0x28は、5番目の64ビットレゞスタのバむトオフセットであるこずに気付くかもしれたせん。

アドレスずデヌタが䞀臎するこずがわかりたすが、このデバッグでは、れロレゞスタにトランザクションに関する情報がありたせんACL_HAL_DEBUGが 5に蚭定されおいる堎合でも。



蚭定結果



カヌネルを調敎した埌、れロレゞスタの最䞋䜍ビットが動いお、蚈算を開始したす。



非衚瀺のテキスト
, .

status ?

?





コアシミュレヌション



これで、カヌネルの構成方法がわかりたした。シミュレヌトしたしょう。

カヌネルには、チュヌニング甚ずデヌタ読み取り甚の2぀のむンタヌフェむスしかありたせん割り蟌みを蚭定するためのむンタヌフェむス1぀の信号サむズがありたすが、あたり興味がありたせん。



カヌネルをシミュレヌトするには、実際ず同じようにすべおを行う必芁がありたす。



もちろん、Linuxやホストアプリケヌションをシミュレヌトするこずは望たしくないため、最初の近䌌ずしお、次のスキヌムに制限するこずができたす。

画像



カヌネルを構成するためのドラむバヌは、SignalTapのおかげで明らかになったカヌネル蚭定を䜿甚した、次のタスクの単玔な呌び出しです。

 task cra_write( input bit [3:0] _addr, bit [63:0] _data, bit [7:0] _byteenable ); $display("%m: _addr = 0x%x, _data = 0x%x, _byteenable = 0x%x", _addr, _data, _byteenable ); @( posedge clk ); cra_addr <= _addr; cra_wr_data <= _data; cra_byteenable <= _byteenable; cra_wr_en <= 1'b0; @( posedge clk ); cra_wr_en <= 1'b1; @( posedge clk ); cra_wr_en <= 1'b0; // dummy waiting repeat (10) @( posedge clk ); endtask
      
      







非衚瀺のテキスト
 initial begin wait( ram_init_done ); wait( test_data_init_done ); cra_write( 4'h5, 64'h000F424000000000, 8'hF0 ); cra_write( 4'h5, 64'h0000000100000000, 8'hF0 ); cra_write( 4'h6, 64'h00000000000F4240, 8'h0F ); cra_write( 4'h6, 64'h0000000100000000, 8'hF0 ); cra_write( 4'h7, 64'h0000000000000001, 8'h0F ); cra_write( 4'h7, 64'h0000000100000000, 8'hF0 ); cra_write( 4'h8, 64'h0000000000000001, 8'h0F ); cra_write( 4'h8, 64'h0000000100000000, 8'hF0 ); cra_write( 4'h9, 64'h00000000000F4240, 8'h0F ); cra_write( 4'h9, 64'h0000000100000000, 8'hF0 ); cra_write( 4'hA, 64'h0000000000000001, 8'h0F ); cra_write( 4'hA, 64'h0000000000000000, 8'hF0 ); cra_write( 4'hB, 64'h0000000000000000, 8'h0F ); cra_write( 4'hB, 64'h0000000000000000, 8'hF0 ); cra_write( 4'hC, 64'h0000000020100000, 8'h0F ); cra_write( 4'hC, 64'h0000000000000000, 8'hF0 ); cra_write( 4'hD, 64'h0000000020500000, 8'h0F ); cra_write( 4'hD, 64'h0000000000000000, 8'hF0 ); cra_write( 4'hE, 64'h0000000020900000, 8'h0F ); cra_write( 4'hE, 64'h0000000000000000, 8'hF0 ); cra_write( 4'h0, 64'h0000000000000001, 8'h0F ); end
      
      







蚈算を行う必芁があるデヌタを準備するために、事前にパックされたアドレスでメモリに曞き蟌たれる同様のタスクを䜜成したす。 アドレスの割り圓おを誰かシステムに䟝頌する必芁はありたせん。デモンストレヌションでは、タスクの条件に応じお必芁に応じお2x1000000の数字を曞く必芁はありたせん-動䜜を確認するには数千個で十分です。デヌタを曞き蟌たない堎合、x䞍明な倀がメモリから読み取られたす。これらのセルには䜕も曞き蟌たれたせんでした。



シミュレヌションの結果を確認したす16進数圢匏の䞀時的な建物のすべおの数字スクリヌンショットは別のりィンドりで開くこずをお勧めしたす開始信号が来たす





そしお、いく぀かのストロヌクの埌、䞡方のLSUは同時にberstaのサむズにデヌタを読み出すための芁求を露出さが0x10に等しい= 16興味深いこずに、3぀の芁求は、最初にのみ受け入れられLSU_X、次いでからLSU_Yそれは信号を瀺しavm_waitrequest堎合にのみ受け入れられるリヌド芁求をwaitrequestはれロに等しい。ご想像のずおり、リク゚ストが亀互に行われない理由は、シェダラヌずグロヌバルメモリぞの盞互接続の問題です。



なぜ正確に3぀の芁求があったのですか

LSUのFIFOのワヌド数は64であり、4぀の読み取り芁求が予想されたすが、このようなトリックがありたした。

 parameter READTHRESHOLD = FIFODEPTH - MAXBURSTCOUNT - 4; assign too_many_reads_pending = (reads_pending + fifo_used) >= READTHRESHOLD; // make sure there are fewer reads posted than room in the FIFO
      
      







読み取り芁求を3぀送信したした3 x 16 = 48ワヌド16ワヌドのスペヌスはただありたすが、4ワヌドが完了するたで読み取りは停止したす。 12の小さなバヌストはありたせん。このモゞュヌルはその方法を知りたせんその意味はありたせん-ロゞックの無駄です。



しばらく埌に、デヌタを読み出すようになっ信号を参照。LSU_X_avm_readdatavalidずすぐ露出信号LSU_X_o_valid、その䞭の32ビットデヌタ知らせるLSU_X_o_readdataは、さらなる凊理のために準備ができお、私たちはコヌキングLSU_X_i_stallのいずれかに蚭定されおいたす。実際、デヌタを远加するコンベダヌにはLSU_Yからのデヌタがありたせん。したがっお、LSU_Y_avm_readdatavalidが到着するたで、すべおがシャットダりンしたす。そしお、LSU_Y_o_validを蚭定したす。



これに続く次のメゞャヌは、有効性に぀いおLSU_Z_i_writedataに通知するLSU_Z_i_valid です。远加パむプラむンは1぀のメゞャヌで機胜したした。LSU_Zは、必芁な量のデヌタの蓄積を埅機しおいたす。これは、もちろん16 256ビットワヌドであり、曞き蟌みトランザクションを䜜成したす。同時に、LSU_XずLSU_Yは、FIFOが空になるず読み取りトランザクションを実行したす。LSU_X_i_stallずLSU_Y_i_stallはコックされおいないこずに泚意しおください。これは、パむプラむンがシャットダりンせず、各クロックが新しいデヌタを受信するこずを意味したす。













倚くのトランザクションを調べた結果、より倚くのギャップが発生しないこずは明らかです。



結論

パむプラむンが停止するこずはない最初の段階を陀いおため、最倧のパフォヌマンスで動䜜するこずは明らかであり、この単玔な䟋では狭いリンクが圌です。読み取りは256ビットワヌドを䜿甚しお行われるため、8぀の32ビット数の䞊列加算を敎理するこずは理にかなっおいたす。その堎合、ボットネクはメモリアクセスで発生する可胜性が高くなりたす。䜿甚に加算噚のプロシヌゞャ・EED番号特別な意味はありたせん



シミュレヌションのおかげで、RTLコヌドにいく぀かの倉曎バヌスト長やキャッシュサむズなどを加えお、これが蚈算の速床にどのように圱響するかを確認し、非垞に迅速に答えを確認できたす。これを10〜15分埅぀必芁はありたせんQuartusでプロゞェクト党䜓を再構築するには、シミュレヌタでシミュレヌションを実行したす。



もちろん、* .clファむルを線集しおたずえば、特別なディレクティブを䜿甚しおアヌキテクチャを倉曎する必芁がありたす。コヌドを再生成し、シミュレヌションを実行しお、プロゞェクト党䜓を組み立おずに結果のゲむンを確認するこずもできたす。



おわりに



vector_addカヌネルがFPGA偎から䜕に倉わるか、そしおどのように構成されおいるかを孊びたした。



ご芧のずおり、FPGA開発者が抱えおいた倚くの問題れロから䜜成した堎合は解決されたした。



もちろん、自動的に行われるこずが最適であるずいう事実ではありたせん。

非衚瀺のテキスト
, Quartus'a ( , ) «».

, :



, : — FPGA.



, , FPGA , Advisor ', GUI , . ( Altera).





䜎レベルの最適化ず手動チュヌニングが最埌のステップです。gccをビルドした埌、アセンブラヌに頻繁に入りたすかたず、* .clで高床な最適化を実行し、Quartusの蚭定で遊ぶ必芁がありたす。



コアをシミュレヌトする機䌚があるのは良いこずです。手元に鉄ボヌドがなくおも、コアのパフォヌマンスを掚定できたす。



ご枅聎ありがずうございたした コメントたたは個人のメヌルで質問やコメントをお埅ちしおおりたす。



All Articles