Per Svensson
Joined: 03 Oct 2004 Posts: 235 Location: Gothenburg, Sweden
|
Posted: Sat Oct 21, 2023 11:54 pm Post subject: AVR numeric benchmark |
|
|
I happened to dig up an old benchmark I wrote many years ago.
I think it could still be useful for many Bascom programmers to see what CPU-time is used for various math operations.
It is especially useful to realize what should be avoided, if one can do it another way, or using another datatype.
Especially when it comes to floating point.
Multiplying by 0.3333 instead of dividing by 3 is much faster. Not to mention trigonometric function. It is so much faster to use Pythagoras rule rather than Sine or Cosine if he task so permits.
Shifting an integer N bits left or right is also much faster than multiplying or dividing by 2^N
But the most fascinating is how much CPU one can save by shifting a SINGLE variable the same way, without loosing significance. Take a look at the bottom of the test where some figures really stick out-.
'The actual numerical results are not shown. Just the datatypes and the used operator.
'Like: DATATYPE = DATATYPE (OPERATION) DATATYPE föllowed by clockcycles and execution time.
' or BYTE = BYTE * BYTE CLOCKSCYCLES TIME(us)
TIME is shown for the actual $CRYSTAL setting.
Example1: B=B+B: 9 0.56us <--- Multiplying two bytes. Returning a byte use 9 CPU clocks.
Example2: I=I*S: 331 20.69us <--- Mult integer by single. Returning an integer use 331 CPU clocks.
Example3: L=SQR(L): 1037 64.81us <--- Squareroot of a long. Returning an long use 1037 CPU clocks.
If there is an interest in the source code, I can upload it
/Per
BasCom_AVR 2.0.8.6 Compiled:20123-10-24
Math benchmark at 16MHz clock
Operation: Clocks, Time(us)
---------- BYTE -----------
B=B+B: 9 0.56us
B=B*B: 10 0.63us
B=B xor B: 9 0.56us
---------- WORD -----------
W=W+W: 20 1.25us
W=W*W: 39 2.44us
W=W/W: 257 16.06us
W=W\W: 257 16.06us
W=W xor W: 20 1.25us
Shift(W,Right,: 59 3.69us
---------- INTEGER -----------
I=I+I: 20 1.25us
I=I*I: 39 2.44us
I=I/I: 333 20.81us
I=I\I: 333 20.81us
I=I xor I: 20 1.25us
Shift(I,Right,8,Signed): 79 4.94us
---------- LONG -----------
L=L+L: 41 2.56us
L=L*L: 87 5.44us
L=L/L: 857 53.56us
L=L\L: 857 53.56us
L=SQR(L): 961 60.06us
Shift(L,Right,12): 121 7.56us
Shift(L,Right,12,Signed): 149 9.31us
---------- SINGLE -----------
S=S+S: 211 13.19us
S=S*S: 242 15.13us
S=S/S: 569 35.56us
Shift(S,12): 73 4.56us
S=Log(S): 73 4.56us
S=Sin(S): 1806 112.88us
---------- DOUBLE -----------
D=D+D: 451 28.19us
D=D*D: 683 42.69us
D=D/D: 1951 121.94us
Shift(D,12): 1 0.06us Shifting a DOUBLE is not supported)
S=Log(D): 177 11.06us
D=Din(D): 14639 914.94us
-------- ASSIGNMENT ---------
B <= B: 4 0.25us
I <= I: 12 0.75us
L <= L: 20 1.25us
S <= S: 39 2.44us
---- MIXED TYPE OPERATIONS -----
L=I+I: 44 2.75us
I=B+B: 18 1.13us
S=B+B: 369 23.06us
I=I+S: 276 17.25us
I=I*S: 311 19.44us
------- STRING TO NUMERIC --------
B <= VAL('57'): 210 13.13us
I <= VAL('-12345'): 465 29.06us
W <= VAL('12345'): 452 28.25us
S <= VAL('-12345.6789'): 2206 137.88us
L <= VAL('-123456789'): 789 49.31us
------- TYPE CONVERSION --------
I <= B: 11 0.69us
B <= lsb(I): 8 0.50us
I <= S: 202 12.63us
S <= I: 117 7.31us
L <= S: 232 14.50us
S <= L: 122 7.63us
D <= L: 167 10.44us
D <= S: 141 8.81us
L <= D: 181 11.31us
S <= D: 170 10.63us
----- MULT Versus SHIFT LEFT ------
S = S*512 = -2781337.00: 303 18.94us
Shift S,left,9 = -2781337.00: 74 4.63us
D=D*512 = -2781337.00: 546 34.13us
Shift D,left,9 = -2781337.00: 1 0.06us
----- DIVIDE Versus SHIFT RIGHT ------
S = S/512 = -10.61: 635 39.69us
Shift S,right,9,signed = -10.61: 73 4.56us
D = D/512 = -10.61: 2013 125.81us
Shift D,right,9,signed = -10.61: 1 0.06us
L = L/512 = -10.61: 835 52.19us
Shift L,right,9,signed = -10.61: 122 7.63us
( Observe that shifting a Single really )
( works as a substitute for MULT/DIV ! )
Let us push this test a little bit harder
by dividing 123.45679E6 by 2^0...2^31
FAST MULTIPLICATION OF A SINGLE BY 2^N USING LEFT-SHIFT
(Multiply123.45679E6 by 2^0...2^31)
--------------------------------------------------------------
123.45679E6 * 1 = 123.45679E6 22.75000us
Shift 123.45679E6,LEFT,0 = 123.45679E6 4.68750us
123.45679E6 * 16 = 1.97531E9 20.75000us
Shift 123.45679E6,LEFT,4 = 1.97531E9 4.68750us
123.45679E6 * 256 = 31.60494E9 22.18750us
Shift 123.45679E6,LEFT,8 = 31.60494E9 4.68750us
123.45679E6 * 4096 = 505.67903E9 20.18750us
Shift 123.45679E6,LEFT,12 = 505.67903E9 4.68750us
123.45679E6 * 65536 = 8.09086E12 21.62500us
Shift 123.45679E6,LEFT,16 = 8.09086E12 4.68750us
123.45679E6 * 1048576 = 129.45383E12 19.62500us
Shift 123.45679E6,LEFT,20 = 129.45383E12 4.68750us
123.45679E6 * 16777216 = 2.07126E15 21.06250us
Shift 123.45679E6,LEFT,24 = 2.07126E15 4.68750us
123.45679E6 * 268435456 = 33.14018E15 19.06250us
Shift 123.45679E6,LEFT,28 = 33.14018E15 4.68750us
FAST DIVISION OF A SINGLE BY 2^N USING RIGHT-SHIFT
(Divide 123.45679E6 by 2^0...2^31)
---------------------------------------------------------
123.45679E6 / 1 = 123.45679E6 44.37500us
Shift 123.45679E6,RIGHT,0,SIGNED = 123.45679E6 4.62500us
123.45679E6 / 16 = 7716049.00000 42.37500us
Shift 123.45679E6,RIGHT,4,SIGNED = 7716049.00000 4.62500us
123.45679E6 / 256 = 482253.00000 43.81250us
Shift 123.45679E6,RIGHT,8,SIGNED = 482253.00000 4.62500us
123.45679E6 / 4096 = 30140.81000 41.81250us
Shift 123.45679E6,RIGHT,12,SIGNED = 30140.81000 4.62500us
123.45679E6 / 65536 = 1883.80100 43.25000us
Shift 123.45679E6,RIGHT,16,SIGNED = 1883.80100 4.62500us
123.45679E6 / 1048576 = 117.73756 41.25000us
Shift 123.45679E6,RIGHT,20,SIGNED = 117.73757 4.62500us
123.45679E6 / 16777216 = 7.35860 42.68750us
Shift 123.45679E6,RIGHT,24,SIGNED = 7.35860 4.62500us
123.45679E6 / 268435456 = 0.45991 40.68750us
Shift 123.45679E6,RIGHT,28,SIGNED = 0.45991 4.62500us |
|