今回は、Blocklyを使って開発したプログラムの実行速度面に着目した実験がテーマです。
Blocklyは、Google社が提供する、グラフィカルにブロックを組み上げることでプログラムを開発できる、ビジュアルプログラミング開発環境です。
見た目からして、「子供向け👦👧の教育用開発環境だな」、等と勘違いしてしまいますが、いざ使って見ると、ブロックを使ったプログラム開発は楽しいのです。本HPにてArduinoで作成している程度の、ちょっとしたプログラムであれば充分に実用的な開発環境として使うことができます。
すごくお気に入りですw(1^−^)w。
何しろ、自作オリジナル16ビットCPUコアMoscoviumの開発環境としてBlocklyを採用してしまった程です(下図)。

Googleが提供する「Blocklyデモ」と言う環境には、JavaScriptやPython等、スクリプト系の言語に変換する機能が搭載されています。スクリプト系言語の多くは「インタープリタ(通訳)」と呼ばれる実行形態です。毎回、ソースリストを読み込んで解釈しては実行して行くため、一般に実行速度が遅いという特徴があります。
中には、仮想マシンの中間コードにコンパイルして実行する物もありますが、こちらも仮想マシンのエミュレータなので、実行速度としては似たり寄ったりです。
Blocklyを採用した開発環境は沢山あり、本HPでも以下の様な開発環境を使ってきました。
PICAXEへの興味は失っている(※)ので、今回比較するのは、UIFlowとBlockly for Moscoviumの2つです。
※あぁ、興味を無くしたのは、Blocklyに対して、ではなく、PICと言うマイコンに対して、です。
UIFlowは、M5StickC Plusの開発環境の一つです。
恐らく、M5StickC Plus上でPython処理系を実行しており、UIFlowが変換したPythonソースリスト(または中間コード?)をM5StickC Plusへダウンロードして実行している物と推察します。恐らく、インタープリタ方式ですね。
とは言え、M5StickC Plusのマイコンは、あのESP32 @240MHzです。Arduino DUE(Cortex-M3 @84MHz)と比較したベンチマークでは、圧倒的な処理速度を示していました。
我がオリジナル16ビットCPUコアMoscoviumの開発環境であるBlockly for Moscoviumは、コンパイラ方式を採用しています。Blocklyが出力したXML形式のソースリストを読み込んで、Moscoviumのアセンブラへ変換する、Blockly.XML→Moscovium.ASM変換スクリプトを有しています。
プログラムの実行はMoscoviumのネイティブ機械語なので、高速に実行できるのが特徴です。
と言っても、こちらは自作のオリジナルCPUである、Moscovium @24MHzです。Blockly for Moscoviumも、コンパイラ方式ではあるのですが、出力するコードは最適化されていません。
どっちが速いの?って言う比較実験をしてみましょう。
実行速度の比較に用いるプログラムは、マンデルブロ集合の計算とします。マンデルブロ集合の計算アルゴリズムに関しては、過去解説済みですので、こちらの記事をご参照ください。
32ビット単精度浮動小数を使うので、オリジナル32ビットCPUコアNihonium用のプログラムとします。以下にリンクしておきます。
Blockly for Moscovium版:mandelbrot.bxml
Blockly for MoscoviumのXMLタブに貼り付けて、ご利用ください。
個人的には、こちらの方が本命なので、フルセットの機能を有しています。コンパイルしてMoscoviumマイコンに書き込むと、シリアルモニタから以下のコマンドを受け付けています。
シリアルモニタコマンド仕様:
続いて、比較対象のUIFlow版プログラムを以下にリンクします。
UIFlow版:mandelbrot.m5f
こちらは、処理速度比較用のサブセット版です。サブセットの理由は以下の通りです。
実行速度の比較ができる、最低限のコーディングに留めてあります。
まずは、Moscoviumマイコンの装置を組み立ててみましょう。
32ビットNihoniumコア、単精度浮動小数演算ユニットS-FPU、SPI-TFT制御ユニット等が必要で、かつ、デュアルコア版が望ましいので、マイコンとしてはNHOC113DB9808を使います。Cmod A7ボード等、XilinxのFPGAに書き込むのに必要な、Moscoviumマイコンの設計データ(Vivadoのプロジェクトファイル一式を含む)はGitHubで提供しています。以下バナーよりアクセスしてください。

デザイン(回路)をCmod A7ボード(FPGA)に書き込む手順については、こちらをご確認ください。
以下に実験中の様子を示します。

実験サンプルに従って実験してみましょう。
実験サンプル:【 】内はシリアルモニタからの送信データ
【cond,32,100】
OK: cond 32, 0x461c4000
【mdbr,-500,0,2000】
OK+ start calculation
OK+ send any serial data to stop
OK+ CPU1:CPU2 = 64:64
OK: mdbr 1913[ms]
上に示したデュアルコア版での実行結果より、画像サイズ128×128[ドット]の計算時間は1.913sでした。デュアルコアのメインCPU1とサブCPU2が、仲良く64ラインずつ分け合って計算した事が報告されています。尚、シングルコア版では3.680sかかった事を申し添えておきます。
こちらの記事「#16-1 見せてもらおうか、Xtensa LX6コアの性能とやらを」でArduino DUEとESP32ボード用に作成したC言語版マンデルブロ集合計算ソフトウェア(mandelbrot.ino)と同等な範囲を同等な条件で描画しました(下図)。

過去記事で計測したDUEおよびESP32の計算時間を含めて以下表にまとめ、考察してみましょう。
| マイコン | CPU |
CPU 周波数 |
FPU | 開発環境 |
240×240[ドット] 計算時間(換算) |
備考 |
| NHOC113DB9808 | Nihonium | 24MHz | ○ |
Blockly for Moscovium |
12.94s | シングルコア |
| 6.73s | デュアルコア | |||||
| Arduino DUE | Cortex-M3 | 84MHz | × | Arduino(C言語) | 15.31s | シングルコア |
| ESP32ボード | Xtensa LX6 | 240MHz | ○ | 1.95s | シングルコア |
考察:
CPU動作周波数の不利(ハンディキャップ)を乗り越えて、結構良い線行っているではないか、我がNihonium+Blockly for Moscoviumは!
引き続き、M5StickC Plus+UIFlowで実験装置を構築して行きます。
M5StickC PlusでUIFlow環境を構築する方法に関しては、こちらの記事をご確認ください。立ち上げが済んだら、UIFlowでこちらのプログラムを読み込み、実行するだけです。
今回の主題は「Blocklyの実行速度」ですから、UIFlowとBlockly for Moscoviumで、詳細に比較してみたいと思います。まずは、最初の実験と同様、Moscovium版でデータを取得します。
実験サンプル:【 】内はシリアルモニタからの送信データ
【cond,120,100】
OK: cond 120, 0x461c4000
【mdbr,-700,0,3000】
OK+ start calculation
OK+ send any serial data to stop
OK+ CPU1:CPU2 = 64:64
OK: mdbr 2413[ms]
下図の様な画像が描画されたはずです。

マンデルブロ集合として、よく見かける代表的な画像ですね。
上の実行結果はデュアルコア版の計算でした。シングルコアで計算させるため、【sleep】コマンドでサブCPU2を停止(スリープ)させてみましょう。
【sleep】
OK: CPU2: sleep=1
【mdbr,-700,0,3000】
OK+ start calculation
OK+ send any serial data to stop
OK+ CPU1:CPU2 = 128:0
OK: mdbr 4698[ms]
処理時間を比較して見ると、デュアルコア:シングルコア=2.413s:4.698sということで、デュアルコアの方が約×1.95倍速と言う結果です。理論値は×2.0倍ですので、少し届きませんが、満足な結果ではあります。円周率πの計算では、もう少しオーバヘッドが大きくて、約×1.78倍速止まりでしたから……。
さて、漸く登場するM5StickC Plusのプログラムでも、同等な範囲を計算するような初期値が設定してあります。もし、条件や座標値を変更したい場合、UIFlowのエディタで以下の部分を変更してから実行してください。

実行すると、M5StickC PlusのTFTディスプレイにも画像が描画されます(下図)。

上写真の通り、UIFlowでの描画時間は76.639sでした。計測した描画時間を以下表にまとめ、考察を続けます。
| Blockly | マイコン |
CPU動作 周波数 |
マンデルブロ 計算時間[s] |
備考 |
| Blockly for Moscovium | NHOC113DB9808 | 24MHz | 4.698 | シングルコア |
| 2.413 | デュアルコア | |||
| UIFlow | M5StickC Plus | 240MHz | 76.639 |
シングルコア デュアルコアには非対応 |
考察:
さすがのESP32 @240MHzも、インタープリタ方式のPython処理系では、性能が引き出せない様ですね。UIFlowで少し凝ったプログラムを作った時、処理速度不足で、まともに動作できなかった経験が複数回在りました。こうしてデータで見てみると、「さもありなん」と言う感じです。
バグだらけで不愉快なUIFlowを我慢して使って来た理由は、
等でした。
1)楽しいBlocklyでの開発は、Moscoviumマイコンで心行くまで堪能できる様になったのだから、バグだらけのUIFlow(Blockly)を我慢して使う価値は無くなりました。これで心おきなく、UIFlowとは決別できそうです。
M5StickC Plusの@240MHz&デュアルコアは、Arduino開発環境で活用しないと勿体ないですしね。
とか何とか言いつつも、UIFlowを使う理由2)は残っているので、まあ、本当に簡単なプログラムの場合は、今後もUIFlowを使う場合があるかも……(弱腰)。


