Github:
https://github.com/ryood/Nucleo_F446_FloatingPoint
mbedのDigitalOut::Write()とHAL_GPIO_WritePin()の差
まずは速度計測に使うGPIOをH/Lするのにかかる時間を比較しました。
mbed
#include "mbed.h" DigitalOut CheckPin1(D2); int main() { while (true) { CheckPin1 = 1; CheckPin1 = 0; } }
SW4STM32(一部)
/* Infinite loop */ /* USER CODE BEGIN WHILE */ while (1) { /* USER CODE END WHILE */ /* USER CODE BEGIN 3 */ HAL_GPIO_WritePin(CHK1_GPIO_Port, CHK1_Pin, GPIO_PIN_SET); HAL_GPIO_WritePin(CHK1_GPIO_Port, CHK1_Pin, GPIO_PIN_RESET); } /* USER CODE END 3 */
SW4STM32のコンパイルオプションで最適化を-O2にして測定しました。
Buildオプション
MCU GCC Compiler -mcpu=cortex-m4 -mthumb -mfloat-abi=hard -mfpu=fpv4-sp-d16 -D__weak=__attribute__((weak)) -D__packed=__attribute__((__packed__)) -DUSE_HAL_DRIVER -DSTM32F446xx -I../Inc -I../Drivers/STM32F4xx_HAL_Driver/Inc -I../Drivers/STM32F4xx_HAL_Driver/Inc/Legacy -I../Drivers/CMSIS/Device/ST/STM32F4xx/Include -I../Drivers/CMSIS/Include -O2 -g3 -Wall -fmessage-length=0 -ffunction-sections -c -fmessage-length=0 MCU GCC Linker -mcpu=cortex-m4 -mthumb -mfloat-abi=hard -mfpu=fpv4-sp-d16 -specs=nosys.specs -specs=nano.specs -T"../STM32F446RETx_FLASH.ld" -Wl,-Map=output.map -Wl,--gc-sections -lm
GPIO Write | 処理時間(ns) | Clock |
---|---|---|
mbed OS5 | 61.1 | 10.9 |
HAL | 126.2 | 22.5 |
意外ですがHALよりmbedの方が速いようです。MPUを180MHz駆動すると1クロックの周期は 1 / 180MHz ≒ 5.6nsとなるので、それを元にClockを計算しました。
SW4STM32のデバッガのDiassemblyでは当該部分は以下のようになっています。
104 HAL_GPIO_WritePin(CHK1_GPIO_Port, CHK1_Pin, GPIO_PIN_SET); 080012f8: mov r4, r0 080012fa: ldr r3, [sp, #16] 080012fc: bl 0x8000888 <HAL_GPIO_WritePin>
憶測ですが、HALの呼び出しはかなりコストが高いのかもしれません。STM32CubeにはLLというHALより低レベル(高速化が期待できる)のライブラリもありますが・・・
浮動小数点演算の比較
前回、mbedの空のループが速すぎましたが、float型の変数fvをvolatile指定していませんでした。volataile指定して最適化されないようにして計測し直しました。
mbed
#include "mbed.h" #include <stdio.h> #include <math.h> #define PI_F (3.14159265f) #define LOOP_N (1000) DigitalOut CheckPin1(D2); volatile float buffer[LOOP_N]; int main() { while (true) { CheckPin1 = 1; volatile float fv = 0.0f; for (int i = 0; i < LOOP_N; i++) { fv += 0.001f; //buffer[i] = fv + PI_F; // Add //buffer[i] = fv - PI_F; // Sub //buffer[i] = fv * PI_F; // Mul //buffer[i] = fv / PI_F; // Div buffer[i] = sinf(fv); //buffer[i] = cosf(fv); //buffer[i] = tanf(fv); //buffer[i] = expf(fv); //buffer[i] = logf(fv); //buffer[i] = powf(2.0f, fv); } CheckPin1 = 0; } }
SW4STM32(一部)
/* Infinite loop */ /* USER CODE BEGIN WHILE */ while (1) { /* USER CODE END WHILE */ /* USER CODE BEGIN 3 */ HAL_GPIO_WritePin(CHK1_GPIO_Port, CHK1_Pin, GPIO_PIN_SET); volatile float fv = 0.0f; for (int i = 0; i < LOOP_N; i++) { fv += 0.001f; //buffer[i] = fv + PI_F; // Add //buffer[i] = fv - PI_F; // Sub //buffer[i] = fv * PI_F; // Mul //buffer[i] = fv / PI_F; // Div buffer[i] = sinf(fv); //buffer[i] = cosf(fv); //buffer[i] = tanf(fv); //buffer[i] = expf(fv); //buffer[i] = logf(fv); //buffer[i] = powf(2.0f, fv); } HAL_GPIO_WritePin(CHK1_GPIO_Port, CHK1_Pin, GPIO_PIN_RESET); } /* USER CODE END 3 */
Buildオプション
MCU GCC Compiler -mcpu=cortex-m4 -mthumb -mfloat-abi=hard -mfpu=fpv4-sp-d16 -D__weak=__attribute__((weak)) -D__packed=__attribute__((__packed__)) -DUSE_HAL_DRIVER -DSTM32F446xx -I../Inc -I../Drivers/STM32F4xx_HAL_Driver/Inc -I../Drivers/STM32F4xx_HAL_Driver/Inc/Legacy -I../Drivers/CMSIS/Device/ST/STM32F4xx/Include -I../Drivers/CMSIS/Include -O2 -g3 -Wall -fmessage-length=0 -ffunction-sections -c -fmessage-length=0 MCU GCC Linker -mcpu=cortex-m4 -mthumb -mfloat-abi=hard -mfpu=fpv4-sp-d16 -specs=nosys.specs -specs=nano.specs -T"../STM32F446RETx_FLASH.ld" -Wl,-Map=output.map -Wl,--gc-sections -lm
測定データ(us)
- | mbed-cli | SW4STM32 | 差 | 差2 |
---|---|---|---|---|
no-op | 39 | 49.6 | 10.6 | |
add | 77.8 | 99 | 21.2 | 10.6 |
sub | 77.8 | 99 | 21.2 | 10.6 |
mul | 77.8 | 99 | 21.2 | 10.6 |
div | 145 | 165 | 20 | 9.4 |
sinf() | 569 | 525 | -44 | -54.6 |
cosf() | 621 | 591 | -30 | -40.6 |
tanf() | 986 | 966 | -20 | -30.6 |
expf() | 958 | 974 | 16 | 5.4 |
logf() | 946 | 998 | 52 | 41.4 |
powf() | 2625 | 2735 | 110 | 99.4 |
測定データの「差2」はGPIO出力の処理時間の差を考慮したmbedとSW4STM32の処理時間の差です。GPIO分を差し引いても四則演算ではmbedの方が速いです。アセンブラレベルで比較すれば何かわかるかもしれませんが、深みにハマりそうなのでやめておきます。
0 件のコメント:
コメントを投稿