Created
June 27, 2020 22:49
-
-
Save bitbank2/8edf801ee835125c9a0c3f7ea1b3f998 to your computer and use it in GitHub Desktop.
An example of why it's important to know your target machine when writing software
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// Arduino Perf | |
// | |
// This sketch is to show how much time it takes for the CPU to work | |
// with different variable types. Knowing that you're running on an | |
// 8-bit CPU vs a 32-bit CPU can have a huge effect on the performance | |
// of your code and your design choices. The Cortex-M4F has a hardware | |
// floating point unit, so integer versus float doesn't make much difference. | |
// while the AVR has to calculate floating point values using software and | |
// is much slower at it than integer calculations. It's also clear that the | |
// native word size is 8-bits because working with anything larger slows | |
// down the code. | |
// | |
// The limited resolution of the time returned by micros() causes the Nano 33 results | |
// to look like all times are equal when they're actually not. However, The actual | |
// times are close enough to demonstrate the point of this exercise. | |
// | |
// Results on an 8-bit AVR (e.g. Arduino Uno) | |
// 8-bits: 140 us | |
// 16-bits: 288 us | |
// 32-bits: 276 us | |
// 64-bits: 1154 us | |
// float: 2760 us | |
// | |
// Results on a 32-bit Cortex-M (e.g. Arduino Nano 33 BLE) | |
// 8-bits: 31 us | |
// 16-bits: 31 us | |
// 32-bits: 31 us | |
// 64-bits: 31 us | |
// float: 31 us | |
// | |
void setup() { | |
Serial.begin(115200); | |
} | |
void loop() { | |
uint32_t u32, u32Sum; | |
uint64_t u64, u64Sum; | |
uint16_t u16, u16Sum; | |
uint8_t u8, u8Sum; | |
float fSum; | |
int delta; | |
unsigned long ulTime; | |
unsigned iLoopCount; | |
int mask; | |
iLoopCount = 200; | |
mask = 0x1234; | |
ulTime = micros(); | |
u8Sum = 0; | |
for (u8=1; u8<=iLoopCount; u8++) { | |
u8Sum += u8 ^ mask; | |
} | |
delta = (int)(micros() - ulTime); | |
Serial.println(u8Sum, DEC); // need to print it or it might get optimized out of the code | |
Serial.print("uint8_t time - "); | |
Serial.print(delta, DEC); | |
Serial.println(" microseconds"); | |
ulTime = micros(); | |
u16Sum = 0; | |
for (u16=1; u16<=iLoopCount; u16++) { | |
u16Sum += u16 ^ mask; | |
} | |
delta = (int)(micros() - ulTime); | |
Serial.println(u16Sum, DEC); // need to print it or it might get optimized out of the code | |
Serial.print("uint16_t time - "); | |
Serial.print(delta, DEC); | |
Serial.println(" microseconds"); | |
ulTime = micros(); | |
u32Sum = 0; | |
for (u32=1; u32<=iLoopCount; u32++) { | |
u32Sum += u32 ^ mask; | |
} | |
delta = (int)(micros() - ulTime); | |
Serial.println(u32Sum, DEC); // need to print it or it might get optimized out of the code | |
Serial.print("uint32_t time - "); | |
Serial.print(delta, DEC); | |
Serial.println(" microseconds"); | |
ulTime = micros(); | |
u64Sum = 0; | |
for (u64=1; u64<=iLoopCount; u64++) { | |
u64Sum += u64 ^ mask; | |
} | |
delta = (int)(micros() - ulTime); | |
Serial.println((uint32_t)u64Sum, DEC); // need to print it or it might get optimized out of the code | |
Serial.print("uint64_t time - "); | |
Serial.print(delta, DEC); | |
Serial.println(" microseconds"); | |
ulTime = micros(); | |
fSum = 0; | |
for (u32=1.0; u32<=iLoopCount; u32++) { | |
fSum += (float)(u32 ^ mask); // incurs additional delay to convert to float | |
} | |
ulTime = micros() - ulTime; | |
Serial.println(fSum, DEC); // need to print it or it might get optimized out of the code | |
Serial.print("float time - "); | |
Serial.print((int)ulTime, DEC); | |
Serial.println(" microseconds"); | |
delay(5000); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment