CMSIS DSPライブラリの使い方とアプリケーションの高速化
Arm Cortex-M3/M4は、DSP(Digital Signal Processing)命令を持ち、例えばSIMD(Single Instruction Multi Data)命令などが該当します。特に、Coretex-M4はDSPに特化したアプリケーションを想定して設計されており、高度なSIMDや積和演算命令をサポートします。加えて、Coretex-M4Fデバイスは浮動小数点演算のための演算ユニットであるFPU(floating point unit)を持ちます。この記事では、Armが定義するCMSIS(Cortex Microcontroller Software Interface Standard)準拠のDSPライブラリをIAR Embedded Workbench for Armでどのように活用するのか、また高速化の効果についてご紹介します。
DSP命令を使用する方法はいくつかあります。例えば、アセンブリコードで関数を記述したり、組込み関数を使用したりします。そして最も実用的なアプローチは、CMSIS準拠のDSPライブラリを使用することです。CMSIS DSPライブラリは、Cortex-Mシリーズ用に設計されたもので、行列や統計や高度な数式といった、DSPに最適化された関数を提供します。
ビルド済みのCMSIS DSPライブラリとそのソースコードはIAR Embedded Workbench for Armで提供されます。それでは、CMSIS DSPライブラリの使い方と、利用による高速化の効果を見ていきましょう。
CMSIS DSPライブラリの設定
IAR Embedded Workbench for Armで、Cortex-Mデバイスを選択することで、CMSIS DSPライブラリを利用することが可能になります。ここでは例として、Arm Coretex-M4F搭載デバイスとしてSTM32F407ZGを挙げます。
次に、General Options>Library Configuration(一般オプション>ライブラリ設定)でCMSISのDSPライブラリを使用するよう設定します。これでCのプリプロセッサにCMSISライブラリのパスがとおり、ビルド済みのライブラリがインポートされます。以上の設定だけでIAR Embedded Workbench for ArmでCMSIS DSPライブラリが使用可能になります。
CMSIS DSPライブラリを試してみましょう
CMSIS DSPライブラリの関数をどのように呼ぶのか、またその性能はどれくらいか見ていきましょう。平方根を求める関数を標準ライブラリと比較してみます。
#include <arm_math.h>
#include <math.h>
#include <stdio.h>
int main()
{
float32_t f_input_cmsis_dsp = 2;
float32_t f_result_cmsis_dsp;
float f_input = 2;
float f_result;
/* Using CMSIS-DSP library */
arm_sqrt_f32(f_input_cmsis_dsp,&f_result_cmsis_dsp);
printf("f1: %f\n",f_result_cmsis_dsp);
/* Standard math function */
f_result = sqrt(f_input);
printf("f2: %f\n",f_result);
return 0;
}
計算結果は同一です。
f1: 1.414214
f2: 1.414214
次に、性能を見てみましょう。
CYCLECOUNTERレジスタはコードを実行するのにどれだけの総クロック数がかかったかを確認するのに便利です。またCCSTEPレジスタは前回のブレーク時からの経過サイクル数を確認するのに便利です。
ブレークポイントを以下のように貼り、CCSTEPを見てみましょう。
今回の場合、CMSIS DSPのsqrt関数は標準ライブラリの10倍以上高速であるという結果でした。
arm_sqrt_f32 : 52 cycles
sqrt : 752 cycles
このシンプルな例から、CMSIS DSPは簡単に使用でき、かつ性能を大幅に改善できることがわかります。
高速フーリエ変換(FFT)の例
それでは、CMSIS DSPライブラリの使用例としてより実用的なものを見ていきましょう。ここでは、波形データから周波数を解析するデジタル信号処理で最も用いられる計算であるFFTを取り上げます。IAR Embedded Workbench for Armには、CMSIS DSPのデモプロジェクトがあります。以下では具体例として、STM32のプロジェクトを使ってみましょう。 ヘルプ>インフォメーションセンターにあるExample projectsから、ST>STM32F4xx>CMSIS and STM32CMSIS and STM32F4xx stdperiph lib 1.2.0RC2>DSP Lib demo projectを開いてください。
このワークプレイスは11のデモを含んでいます。
arm_fft_bin_exampleを見てみます。
このプロジェクトは、arm_fft_bin_data.cというファイルがあり、そこには10KHzの信号とホワイトノイズを含むデータの配列が含まれます。
FFTのアルゴリズムの入力は複素数である必要があるので、奇数番のデータが実際のデータ、偶数番のデータは虚数で0にしています。
ホワイトノイズを含む入力波形は上記です。
FFTの結果は常に対称で、このデモの出力は、特定の周波数の要素とホワイトノイズの両方を含みます。
それではメインのソースコードに戻り、CMSIS DSPライブラリの効果を見てみましょう。
arm_status status;
arm_cfft_radix4_instance_f32 S;
float32_t maxValue;
status = ARM_MATH_SUCCESS;
/* Initialize the CFFT/CIFFT module */
status = arm_cfft_radix4_init_f32(&S, fftSize,ifftFlag, doBitReverse);
/* Process the data through the CFFT/CIFFT module */
arm_cfft_radix4_f32(&S, testInput_f32_10khz);
/* Process the data through the Complex Magnitude Module for
calculating the magnitude at each bin */
arm_cmplx_mag_f32(testInput_f32_10khz, testOutput, fftSize);
/* Calculates maxValue and returns corresponding BIN value */
arm_max_f32(testOutput, fftSize, &maxValue, &testIndex);
コメントのとおり、最初の関数でFFTモジュールの初期化を行います。二番目の関数で、FFTの計算を行います。三番目の関数で、各FFTビンの大きさを複素数から求めています。そして四番目の関数で、最大値とインデックスを出力の配列から探しています。
結果は、先ほど紹介した値と全く同じです。
次に、CCSTEPにより、各関数の性能を見ていきましょう。
arm_cfft_radix4_init_f32 | 54 |
arm_cfft_radix4_f32 | 100256 |
arm_cmplx_mag_f32 | 26913 |
arm_max_f32 | 8744 |
総サイクル数は135,967です。CPUが100MHzで動作しているなら、処理時間は1,359msとなります。音声のサンプリング周波数は44KHz, 2048サンプリングには45,056msかかります。DSPの性能が高速であることがわかります。
それでは、Coretex-M3にコアを変えて、性能がどれほど変わるのか見てみましょう。
arm_cfft_radix4_init_f32 | 54 |
arm_cfft_radix4_f32 | 1852707 |
arm_cmplx_mag_f32 | 377358 |
arm_max_f32 |
23844 |
CPUが100MHzで動作しているなら、処理時間は22,539msとなります。これによりCortex-M4がいかにDSPアプリケーションに向けて最適化されているかがわかります。
まとめ
Cortex-Mプロセッサは、高性能な命令、特にCoretex-M4ではDSPアプリケーション向けの命令を提供します。システムの性能を引き出すために、IAR Embedded Workbench for ArmとCMSIS DSPライブラリを使うことを検討されてはいかがでしょうか。ソースコードは、\arm\CMSIS\DSP_Lib\Sourceにあり、使いたい関数が無い場合は、ご自身のライブラリを作ることも可能です。
IAR Embedded Workbench セルフハンズオンご紹介
お申し込み受付後に送付される演習キットを使用して、テキストと動画を見ながら、Arm Cortex-Mマイコン評価ボードによる「IAR Embedded Workbench for Arm」の基礎から実践的な使い方までが学べます。
組込みソフトウェアエンジニアでArm Cortex-Mマイコンの基礎的なプログラミングを習得したい方にお勧めです。