MachiKania type Pの実行速度
2022年7月26日
現在、Raspberry Pi Pico用のMachiKaniaを、ケンケンさんと共同で開発中です。これは、MachiKania Type M, Type ZとコンパチブルなBASICコンパイラーを搭載し、表示装置にLCDを使った、Raspberry Pi Pico用のMachiKaniaで、コードネームにPhyllosomaと名付けたものです。正式名称は、MachiKania Type Pになる予定です。近々、公式にversion 1.0を公開します。
Type MやType Zでは、プログラムの実行にMMC/SDカードやNTSCディスプレイが必要でしたが、Type Pではそういったものが無い環境でもBASICプログラムを高速で実行し、I2CやSPIなどのインターフェースで外部機器を制御することが可能です。従って、組み込み用途でのMachiKania Type Pの利用も、ニーズとしてあると考えています。
Raspberry Pi Pico用には、C/C++による開発環境やMicroPythonによる開発環境がすでに提供されていて、これらはニーズに応じて便利に使えます。C/C++で開発すると最速の実行速度が得られる一方、開発環境の構築に手間がかかり、かつ、外部機器との接続用のSDKの呼び出し方も複雑です。他方で、MicroPythonでの開発は外部機器の制御も分かりやすく、開発にかける時間を少なくできますが、実行速度がそれほど速くはありません。
MachiKaniaはC/C++と同じコンパイル形式なので、最速でないにせよ、ある程度の高速実行が可能です。また、Pythonほど強力ではありませんが、オブジェクト指向プログラミングも可能です。
そこで、MachiKaniaの利便性を評価するため、MachiKania・C/C++・MicroPythonで、実行速度の差がどれぐらいあるのか、調べてみました。
速度測定に利用したC/C++コンパイラー (gcc)、MicroPython、MachiKania Type Pのバージョンは、次の通りです。
ベンチマークテストに使ったプログラムは、古のPCのベンチマークによく使われていてASCIIARTと呼ばれている、マンデルブロ集合を表示するものを使いました。
gcc用には以下のコード。
MicroPython用には以下のコード。
MachiKania用には以下のコード。
gccの実行結果。
MicroPythonの実行結果。
MachiKaniaの実行結果。
実行結果の最後に、計算に要した時間を、μ秒で表示しています。この結果から、CはMachiKaniaより2.31倍速く、MachiKaniaはMicroPythonより4.56倍速いことが分かりました。
上のテストでは、Raspberry Pi Pico上で計算し、結果をPC側にUSB接続を使って転送しています。この転送手続きは115200 bpsのCOM接続で行われているため、ある程度の遅延を生じます。そこで、結果の表示は行わず計算だけ行なった場合の速度についても、比較してみました。
gccのコード。
MicroPythonのコード。
MachiKaniaのコード。
gccの実行結果
MicroPythonの実行結果。
MachiKaniaの実行結果。
この場合、CはMachiKaniaより2.42倍速く、MachiKaniaはMicroPythonより7.11倍速いことが分かりました。
上のテストから、組み込み開発用途としてのMachiKania Type Pの立ち位置は
といった所になりそうです。加えて、MachiKaniaはゲーム開発のためのプラットフォームですから、LCD表示型のゲームを作るのに便利であることは言うまでもありません。
Type MやType Zでは、プログラムの実行にMMC/SDカードやNTSCディスプレイが必要でしたが、Type Pではそういったものが無い環境でもBASICプログラムを高速で実行し、I2CやSPIなどのインターフェースで外部機器を制御することが可能です。従って、組み込み用途でのMachiKania Type Pの利用も、ニーズとしてあると考えています。
Raspberry Pi Pico用には、C/C++による開発環境やMicroPythonによる開発環境がすでに提供されていて、これらはニーズに応じて便利に使えます。C/C++で開発すると最速の実行速度が得られる一方、開発環境の構築に手間がかかり、かつ、外部機器との接続用のSDKの呼び出し方も複雑です。他方で、MicroPythonでの開発は外部機器の制御も分かりやすく、開発にかける時間を少なくできますが、実行速度がそれほど速くはありません。
MachiKaniaはC/C++と同じコンパイル形式なので、最速でないにせよ、ある程度の高速実行が可能です。また、Pythonほど強力ではありませんが、オブジェクト指向プログラミングも可能です。
そこで、MachiKaniaの利便性を評価するため、MachiKania・C/C++・MicroPythonで、実行速度の差がどれぐらいあるのか、調べてみました。
速度測定に利用したC/C++コンパイラー (gcc)、MicroPython、MachiKania Type Pのバージョンは、次の通りです。
gcc: GNU Arm Embedded Toolchain Version 10-2020-q4-major Raspberry Pi Pico C/C++ SDK Version 1.4.0 MicroPython: Raspberry Pi Pico MicroPython Version 1.19.1 MachiKania: MachiKania Type P Version 0.9.2また、実行はすべて、TeraTerm (version 4.106)からUSB-serialで、115200 bpsで接続した状態で行いました。
ベンチマークテストに使ったプログラムは、古のPCのベンチマークによく使われていてASCIIARTと呼ばれている、マンデルブロ集合を表示するものを使いました。
gcc用には以下のコード。
#include <stdio.h> #include "pico/stdlib.h" int main() { int i,x,y,flag,ct; float a,b,t,ca,cb; stdio_init_all(); sleep_ms(3000); ct=time_us_32(); for(y=-13;y<14;y++){ for(x=-39;x<40;x++){ ca=(float)x*0.0458; cb=(float)y*0.08333; a=ca; b=cb; flag=0; for(i=0;i<16;i++){ t=a*a-b*b+ca; b=2*a*b+cb; a=t; if ((a*a+b*b)>4) { flag=1; break; } } if (!flag) { putchar(' '); } else { if (i>9) i=i+7; putchar(48+i); } } putchar(0x0d);putchar(0x0a); } printf("%d\n",time_us_32()-ct); while(1); return 0; }
MicroPython用には以下のコード。
import time time.sleep(1.0) start=time.ticks_us() for y in range(-13,14): for x in range(-39,40): ca=x*0.0458 cb=y*0.08333 a=ca b=cb flag=0 for i in range(0,16): t=a*a-b*b+ca b=2*a*b+cb a=t if (a*a+b*b)>4: flag=1 break if flag==0: print(" ",end="") else: if i>9:i=i+7 print(chr(48+i),end="") print("") print(time.ticks_us()-start)
MachiKania用には以下のコード。
USEVAR CA,CB,FLAG Z=CORETIMER() FOR Y=-13 TO 13 FOR X=-39 TO 39 CA#=FLOAT#(X)*0.0458 CB#=FLOAT#(Y)*0.08333 A#=CA# B#=CB# FLAG=0 FOR I=0 TO 15 T#=A#*A#-B#*B#+CA# B#=2*A#*B#+CB# A#=T# IF (A#*A#+B#*B#)>4 THEN FLAG=1 BREAK ENDIF NEXT IF FLAG=0 THEN PRINT " "; ELSE IF I>9 THEN I=I+7 PRINT CHR$(48+I); ENDIF NEXT PRINT NEXT PRINT CORETIMER()-Z A$=INPUT$()(ただし、MACHIKAP.INIで「LCDOUTOFF」を指定)
gccの実行結果。
MicroPythonの実行結果。
MachiKaniaの実行結果。
実行結果の最後に、計算に要した時間を、μ秒で表示しています。この結果から、CはMachiKaniaより2.31倍速く、MachiKaniaはMicroPythonより4.56倍速いことが分かりました。
上のテストでは、Raspberry Pi Pico上で計算し、結果をPC側にUSB接続を使って転送しています。この転送手続きは115200 bpsのCOM接続で行われているため、ある程度の遅延を生じます。そこで、結果の表示は行わず計算だけ行なった場合の速度についても、比較してみました。
gccのコード。
#include <stdio.h> #include "pico/stdlib.h" static volatile unsigned char g_dummy_char; #define putchar(a) do {\ g_dummy_char=a;\ } while(0) int main() { int i,x,y,flag,ct; float a,b,t,ca,cb; stdio_init_all(); sleep_ms(3000); ct=time_us_32(); for(y=-13;y<14;y++){ for(x=-39;x<40;x++){ ca=(float)x*0.0458; cb=(float)y*0.08333; a=ca; b=cb; flag=0; for(i=0;i<16;i++){ t=a*a-b*b+ca; b=2*a*b+cb; a=t; if ((a*a+b*b)>4) { flag=1; break; } } if (!flag) { putchar(' '); } else { if (i>9) i=i+7; putchar(48+i); } } putchar(0x0d);putchar(0x0a); } printf("%d\n",time_us_32()-ct); while(1); return 0; }
MicroPythonのコード。
import time time.sleep(1.0) start=time.ticks_us() for y in range(-13,14): for x in range(-39,40): ca=x*0.0458 cb=y*0.08333 a=ca b=cb flag=0 for i in range(0,16): t=a*a-b*b+ca b=2*a*b+cb a=t if (a*a+b*b)>4: flag=1 break if flag==0: pass #print(" ",end="") else: if i>9:i=i+7 #print(chr(48+i),end="") #print("") print(time.ticks_us()-start)
MachiKaniaのコード。
USEVAR CA,CB,FLAG Z=CORETIMER() FOR Y=-13 TO 13 FOR X=-39 TO 39 CA#=FLOAT#(X)*0.0458 CB#=FLOAT#(Y)*0.08333 A#=CA# B#=CB# FLAG=0 FOR I=0 TO 15 T#=A#*A#-B#*B#+CA# B#=2*A#*B#+CB# A#=T# IF (A#*A#+B#*B#)>4 THEN FLAG=1 BREAK ENDIF NEXT IF FLAG=0 THEN rem PRINT " "; ELSE IF I>9 THEN I=I+7 rem PRINT CHR$(48+I); ENDIF NEXT rem PRINT NEXT PRINT CORETIMER()-Z A$=INPUT$()(ただし、MACHIKAP.INIで「LCDOUTOFF」を指定)
gccの実行結果
MicroPythonの実行結果。
MachiKaniaの実行結果。
この場合、CはMachiKaniaより2.42倍速く、MachiKaniaはMicroPythonより7.11倍速いことが分かりました。
上のテストから、組み込み開発用途としてのMachiKania Type Pの立ち位置は
- Cで開発した場合の半分ぐらいの速度で、高速実行できる
- 実行速度は、MicroPythonより数倍速い
- オブジェクト指向型BASICを用いて、容易にコードを組むことができる
- LCDとMMCカードのライブラリーが組み込まれており、制御が容易
- PWM、SPI、I2C、UART、ADCのライブラリーが組み込まれており、制御が容易
といった所になりそうです。加えて、MachiKaniaはゲーム開発のためのプラットフォームですから、LCD表示型のゲームを作るのに便利であることは言うまでもありません。