Benchmarking test code for various operations
Fork of benchmark by
Benchmarking the performance of various mbed boards that I have
Using the excellent code by Igor, I have benchmarked the performance of the following platforms:
- mbed LPC1768
- mbed LPC11U24
- EA LPC4088 QuickStart Board
- mbed LPC1114FN28
- NUCLEO-F302R8
- FRDM-K64F
- NUCLEO-F411RE
- LPCXpresso4337
- Seeed Arch Max
- mbed LPC1768
The data can be found in this link: https://docs.google.com/spreadsheets/d/1d5BcNvC341xvktRJ6DC3wdlI6wuv0FjCvCqHAnfINmQ/pubhtml
For the hyperbolic tan (tanh) function, I made a graph showing how the clock speed of various ARM Cortex-M4 boards with FPU affects the computation time in microseconds.
main.cpp@2:fc68d524dd7d, 2015-11-19 (annotated)
- Committer:
- mcx
- Date:
- Thu Nov 19 21:41:58 2015 +0000
- Revision:
- 2:fc68d524dd7d
- Parent:
- 1:f91e7bc0e244
- Child:
- 3:ec2e20a9bd03
Working
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
igor_m | 0:6d89d8c13042 | 1 | #include "mbed.h" |
mcx | 1:f91e7bc0e244 | 2 | |
mcx | 1:f91e7bc0e244 | 3 | //https://developer.mbed.org/users/igor_m/code/benchmark/ |
igor_m | 0:6d89d8c13042 | 4 | /* This program determines the time it takes to perform floating point |
igor_m | 0:6d89d8c13042 | 5 | and integer operations. |
igor_m | 0:6d89d8c13042 | 6 | To determine the time it takes, a Timer is used to measure the time |
igor_m | 0:6d89d8c13042 | 7 | it takes to complete a large amount of iterations. The time for a single |
igor_m | 0:6d89d8c13042 | 8 | operation can then be determined. |
igor_m | 0:6d89d8c13042 | 9 | |
igor_m | 0:6d89d8c13042 | 10 | To increase accuracy of the results, an empty for loop is timed to determine |
igor_m | 0:6d89d8c13042 | 11 | the loop overhead and the overhead is subtracted from the time it takes to |
igor_m | 0:6d89d8c13042 | 12 | complete the operation loop. |
mcx | 1:f91e7bc0e244 | 13 | */ |
igor_m | 0:6d89d8c13042 | 14 | |
igor_m | 0:6d89d8c13042 | 15 | #define ITERATIONS 1000000 // Number of calculations. |
mcx | 2:fc68d524dd7d | 16 | #define CLOCK 48 // Clock freqency in MHz |
igor_m | 0:6d89d8c13042 | 17 | Timer timer; // Timer.. |
igor_m | 0:6d89d8c13042 | 18 | |
igor_m | 0:6d89d8c13042 | 19 | Serial pc(USBTX, USBRX); |
igor_m | 0:6d89d8c13042 | 20 | float number_of_cycles, single_operation_time; |
mcx | 2:fc68d524dd7d | 21 | volatile int a, b, c; // Int operands and result. Must be volatile! |
mcx | 2:fc68d524dd7d | 22 | //volatile float a, b, c; // Float operands and result. Must be volatile! |
mcx | 1:f91e7bc0e244 | 23 | //volatile double a, b, c; // Float operands and result. Must be volatile! |
igor_m | 0:6d89d8c13042 | 24 | |
igor_m | 0:6d89d8c13042 | 25 | int main() { |
igor_m | 0:6d89d8c13042 | 26 | |
igor_m | 0:6d89d8c13042 | 27 | unsigned int i, for_time, total_time, operation_time; |
igor_m | 0:6d89d8c13042 | 28 | a=2.3; |
igor_m | 0:6d89d8c13042 | 29 | b=5.33; |
igor_m | 0:6d89d8c13042 | 30 | |
igor_m | 0:6d89d8c13042 | 31 | timer.reset(); // Reset timer |
igor_m | 0:6d89d8c13042 | 32 | timer.start(); // Start timer |
mcx | 1:f91e7bc0e244 | 33 | pc.printf("Operations in progress.. May take some time.\r\n"); |
igor_m | 0:6d89d8c13042 | 34 | /* Determine loop overhead */ |
mcx | 1:f91e7bc0e244 | 35 | for (i=0; i<ITERATIONS; i++){} |
igor_m | 0:6d89d8c13042 | 36 | for_time=timer.read_us(); |
igor_m | 0:6d89d8c13042 | 37 | timer.stop(); |
igor_m | 0:6d89d8c13042 | 38 | |
igor_m | 0:6d89d8c13042 | 39 | /* Determine the total loop time */ |
igor_m | 0:6d89d8c13042 | 40 | timer.reset(); |
igor_m | 0:6d89d8c13042 | 41 | timer.start(); |
igor_m | 0:6d89d8c13042 | 42 | |
igor_m | 0:6d89d8c13042 | 43 | /* The operation takes place in the body of |
igor_m | 0:6d89d8c13042 | 44 | this for loop. */ |
mcx | 1:f91e7bc0e244 | 45 | for (i=0; i<ITERATIONS; i++){ |
igor_m | 0:6d89d8c13042 | 46 | |
mcx | 2:fc68d524dd7d | 47 | a = b; |
mcx | 1:f91e7bc0e244 | 48 | // c = a+b; |
mcx | 1:f91e7bc0e244 | 49 | // c = a*b; |
mcx | 1:f91e7bc0e244 | 50 | // c = a/b; |
mcx | 1:f91e7bc0e244 | 51 | // a = sqrt(b); |
mcx | 1:f91e7bc0e244 | 52 | // a = log(b); |
mcx | 1:f91e7bc0e244 | 53 | // a = tanh(b); |
igor_m | 0:6d89d8c13042 | 54 | |
igor_m | 0:6d89d8c13042 | 55 | } |
mcx | 1:f91e7bc0e244 | 56 | |
igor_m | 0:6d89d8c13042 | 57 | total_time=timer.read_us(); |
igor_m | 0:6d89d8c13042 | 58 | |
igor_m | 0:6d89d8c13042 | 59 | operation_time = total_time-for_time; // Calculate the time it took for the number of operations |
igor_m | 0:6d89d8c13042 | 60 | |
igor_m | 0:6d89d8c13042 | 61 | single_operation_time=float(operation_time)/float(ITERATIONS); |
igor_m | 0:6d89d8c13042 | 62 | number_of_cycles = single_operation_time*CLOCK; |
igor_m | 0:6d89d8c13042 | 63 | |
mcx | 1:f91e7bc0e244 | 64 | pc.printf("for overhead: \t\t%dus \r\n", for_time); |
mcx | 1:f91e7bc0e244 | 65 | pc.printf("total time: \t\t%dus \r\n", total_time); |
mcx | 1:f91e7bc0e244 | 66 | pc.printf("%d calculations took:\t%dus \r\n", ITERATIONS, operation_time); |
mcx | 1:f91e7bc0e244 | 67 | pc.printf("single operation took: \t\t%fus \r\n", single_operation_time); |
mcx | 1:f91e7bc0e244 | 68 | pc.printf("single operation took: \t\t%.3f cycles \r\n", number_of_cycles); |
igor_m | 0:6d89d8c13042 | 69 | } |