Renesas



Section1
Section2
Section3
Section4
Section5
Section6




ここではRXに新規に採用された機能を中心にRXコアの性能を体験してみましょう。

全体のバス構成です。この部分がハーバードアーキテクチャです。命令バスとオペランドバスは64ビット幅でICLKで動作します。他には内部メインバス、周辺バスがあります。それでは、CPUのハーバードアーキテクチャを紹介します。

RXはSuperHファミリと同じ、5段のパイプラインを採用しています。IF、D、E、M、WBの5段のステージで構成しています。これはパイプラインの基本動作で、あくまで理想的な動きです。実際にはノンハーバードアーキテクチャの場合、命令1のメモリアクセスステージと命令4のインストラクションフェッチでバスの競合が発生しています。そうするとこの2つのステージは同時に実行することができません。また、命令2と命令5でも同様に競合が発生していますので、同時に実行することができません。実際のパイプライン動作はこのようになります。命令1のメモリアクセスは実行されますが、命令2以降のパイプラインは停止してしまいます。これをパイプラインストールといい、停止している間プログラム実行が遅延してしまいます。したがって、このように命令2以降パイプラインストールが発生するたびにプログラム実行が遅延していきます。

それではハーバードアーキテクチャの場合はどのようになるでしょう。ハーバードアーキテクチャの場合は命令バスとオペランドバスが分離されていますので、このように命令1と4、命令2と5のメモリアクセスとインストラクションフェッチの競合は発生しません。つまり同時に実行することができます。メモリアクセスの頻度が多いアプリケーションほどハーバードアーキテクチャの効果が高くなります。

演習で使用したプログラムのメイン関数部です。LEDのシフト処理を繰り返し行っていますが、各シフト処理の間にメモリアクセスを行う演算処理を数万回実行しています。演習ではLEDのシフト表示を開始するところからLEDを4回シフトし終えたところまでの処理時間をRX600とH8SXでそれぞれ計測し、処理時間の比較をします。

プログラムの実行結果です。RX600では150.9ms、H8SXでは235msとなっています。ハーバードアーキテクチャの採用によりRX600の方が約1.6倍性能が向上しています。

RXのFPUはこのように汎用レジスタを使用して演算をすることができます。

SuperHファミリなどFPU専用レジスタを使用して演算を行うFPUは、演算結果を汎用レジスタまたはメモリに転送する必要があります。そのため、専用レジスタと汎用レジスタ間のデータ転送が多くなり、遅くなってしまいます。

RXのFPUは汎用レジスタを使用しますので、データ転送がない分効率が良くなります。FPU専用レジスタとしてはFPSWのみです。RX搭載のFPUはレジスタ間だけでなく、メモリと汎用レジスタ間との浮動小数点演算も行うことができます。

用意されているFPU命令は8種類あります。四則演算、比較、データ変換です。特長はデータ変換命令です。データ変換命令は整数を浮動小数点に変換したり、その逆の変換をするための命令です。RXはこのようなデータ変換にランタイムライブラリを使用せず、専用命令で高速にデータ変換を行うことができます。FPUの例です。プログラムはfloat型のaf変数とint型のibとans変数を用意して、afとibを加算して整数型の変数ansに代入します。ibは演算時フロート型に変換されて演算されます。演算後イント型に変換されてans変数に代入されます。このプログラムをコンパイルしてみます。FPU命令を出力しないオプションを付けてコンパイルした結果です。プログラム量としては45バイトとなります。

この部分でデータ変換のランタイムライブラリを呼び出してます。この処理を行っているのがこの部分です。浮動小数点の加算をしている部分がこの部分で、ランタイムライブラリで行われています。また加算結果を整数に変換しているのがこの部分になります。合計3つのランタイムライブラリが実行されます。FPU命令を出力するオプションに切り替えてコンパイルした結果です。プログラム量は21バイトとなり、FPU命令を使用しないものと比較すると約半分になります。データ変換命令の効果としてはこの2箇所がそれぞれ命令で展開され、バイト数の削減に貢献しています。また、FPU命令未使用時の45バイトはランタイムライブラリを除いたバイト数となりますので、FPU命令を使用した場合では半分以上のプログラムサイズおよびサイクル数の削減に効果があります。

演習で使用した評価用プログラムです。処理内容はサインやコサイン、平方根など複数の浮動小数点演算を繰り返し行っています。演算を開始するところから演算が終了するまでの処理時間を計測し、RX600とH8SXで比較します。

実行結果です。RX600は18.9msですが、H8SXはFPUが搭載されていませんので109msかかっています。FPUを搭載することで、浮動小数点演算処理が格段に向上します。

RXはバスを階層化してレイヤーに分けています。CPUバスは命令バスとオペランドバスが分離されているハーバードアーキテクチャになっています。また、内部メインバスがメインバス1と2に分かれています。メインバス1のバスマスタは、CPUです。メインバス2のバスマスタはDMAコントローラおよびDTCで、データ転送のために使用します。このようなバス構成にするとDMAのデータ転送とCPUの実行を並列に行うことができます。たとえば、CPUが内蔵ROMから命令をフェッチするのとDMAコントローラがA/D変換した結果を内蔵RAMに転送する動作は、一切バスが競合しませんので、平行して行うことができます。

内蔵周辺バスも2つに分かれています。殆どの周辺機能が接続されている内蔵周辺バス2とICUおよびDMAコントローラが接続されている内蔵周辺バス1で構成されています。DMAC(r)はDMAのレジスタアクセス時で、DMAC(m)はデータ転送時を示しています。内蔵周辺バス2は周辺クロック、最大50MHzで動作しますが、内蔵周辺バス1はCPUクロック、最大100MHzで動作します。

RX600とH8SXのバス構成を比較して見ましょう。H8SXもシステムバスと内蔵周辺バスに分かれていますが、システムバスは1つで構成されています。たとえばCPUが内蔵ROMやRAMをアクセスしているときにDMAコントローラが周辺機能からRAMにデータ転送をしようとする場合、バスの競合が発生するため、CPUまたはDMAコントローラのどちらかの動作が一時的に停止してしまいます。それに対してRXはメインバスが2つに分かれているため同時にアクセスすることができます。

DMAコントローラの内部ブロック図です。バスマスタ調停部はメインバス2に接続されているDMAコントローラとDTCのバス調停を行っています。

DMAコントローラとCPUのバス動作を表した図です。DMAコントローラは1データ転送に最小3クロックかかります。リードとライトの間で1サイクル空いており、この間でバス権を開放し、CPUが動作するサイクルスチール方式です。通常はDMAコントローラがバスを占有していないときだけCPUが動作できますが、RXは内部メインバスを2つに分けているため、DMA転送中でもDMAコントローラのリード/ライトターゲットが重なっていなければ、CPUは並行して動作することが可能です。

H8SXとRXで同じプログラムを動作させDMA転送の性能比較を体験する演習です。プログラムはDMA転送とLED点灯制御を並行して行います。メイン関数では、LED点灯箇所をシフトしていく処理を繰り返し行い、ループ中は変数“main_cnt”を常にインクリメントしています。DMA転送はA/D変換データをRAMへ128k回、連続して転送します。なおRXの動作周波数は、H8SXと比較するために50MHzとしています。

演習プログラムの動作イメージです。スイッチ3をオンにするとDMA転送が開始されます。DMA転送と並行してCPUはメイン関数でLED表示をシフトする制御をしており、そのなかでループカウンタをインクリメントしています。またDMA転送開始と同時にコンペアマッチタイマを起動させて転送時間を計測しています。転送条件はこのようになっています。

演習プログラムのメイン関数部です。メイン関数の処理はLEDのシフト表示を行っているだけです。着目点は、各LEDのシフト処理の間に100万回ループ処理をしている部分です。1回ループするごとにmain_cnt変数をインクリメントしています。main_cnt変数の値を確認することで、DMA転送中にメイン関数がどれくらい並列に処理できているかわかります。DMAコントローラの転送条件です。

RX600の実行結果です。cmt_cnt_dataはDMAコントローラ起動と同時にスタートするコンペアマッチタイマのカウント値です。main_cntはDMAコントローラ起動と同時にカウントを開始するメイン関数内のforループカウント値です。tra_speedはDMA転送終了後に算出したDMA転送時間です。cpu_cntはコンペアマッチタイマ 1カウント当たりのメイン関数内forループのカウント数です。転送速度は約20.9msで、DMA転送中にmain_cntは65534回カウントされています。

H8SXの実行結果です。main_cntはDMAコントローラ起動と同時にカウントを開始するメイン関数内のforループカウント値です。msecはDMA転送終了後に算出したDMA転送時間です。clkptrnsは1データ転送に必要としたサイクル数です。転送速度は約26.2msで、RX600とそれほど変わりませんが、DMA転送中にmain_cntは21845回しかカウントされていないことがわかります。

高速割り込みは、通常の割り込みに比べ、割り込み要求から割り込みプログラムをフェッチするまでの処理とリターン命令からプログラムが戻るまでの処理を高速にすることができます。通常の割り込みは、要求が発生してから割り込みプログラムをフェッチするまでに6サイクルとなります。それに対して高速割り込みは4サイクルとなっています。また、割り込みプログラムから戻る場合、通常の割り込みは6サイクルかかりますが、高速割り込みは専用命令を使用して戻るため、3サイクルで戻ることができます。高速割り込みはBPSWとBPCがあり、これらの専用レジスタにCPUステータスと戻りアドレスを格納します。さらに割り込みプログラムの分岐アドレスを専用のベクタレジスタから読み出すため、高速になります。

通常、割り込みルーチン内で汎用レジスタの退避、復帰が入ります。高速割り込みは汎用レジスタを高速割り込みの専用レジスタとして割り当てることができるため、このレジスタ退避、復帰処理が不要となります。つまり、割り込みルーチン内でのレジスタの退避、復帰を削減できるためさらに高速になります。高速割り込みの演習です。演習プログラムは外部割込みのIRQ8とIRQ9の2つを使用します。IRQ8は通常割り込み、IRQ9を高速割り込みとして使用します。スイッチ1がIRQ8の割り込みで、LED2と3を点滅させます。

スイッチ2がIRQ9の割り込みで、同じくLED2と3を点滅させます。点滅間隔は割り込みルーチンが10万回発生するたびに切り替えています。それぞれの割り込みで点滅間隔の違いを見てみます。今回の演習ではRXのCPUクロックを25MHzに設定して計測しています。通常割り込みであるIRQ8の割り込みルーチンでは汎用レジスタの退避、復帰処理が入っています。

汎用レジスタR3〜R5の退避に3サイクルかかり、復帰も同様に3サイクルかかります。また、RTE命令の実行に6サイクルかかります。合計で12サイクルとなります。高速割り込みであるIRQ9は速割り込み専用レジスタとしてR10〜R13の4つを指定しています。従って、IRQ9割り込みルーチンでは指定した汎用レジスタを使用するため、汎用レジスタの退避、復帰処理がなくなります。この指定はRX Standard ToolchainダイアログのCPUタブで行います。また、高速割り込み専用のRTFI命令を使用して戻るためサイクル数が削減され、速くなります。

処理時間の結果です。上が通常割り込みのIRQ8割り込みの処理時間で、下が高速割り込みのIRQ9割り込みの処理時間です。この処理時間は割り込み処理を10万回続けて行って出た処理時間になります。累計の時間差は36msなので、1回の割り込みで360nsの差となります。CPUの動作周波数を25MHzとして計測していますので、CPUサイクルに換算すると9サイクルの差となります。