Pages: 1 ... 3 4 [5] 6 7 ... 9   Go Down
Author Topic: Teensy 3.0  (Read 36268 times)
0 Members and 1 Guest are viewing this topic.
Greenville, IL
Offline Offline
Edison Member
*
Karma: 15
Posts: 1330
Warning Novice on board! 0 to 1 chance of errors!
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset


 To see a bench mark, I wrote a code to compare the Teensy 3.0 to the Uno. It calculates sin() of 0 to 400.

Rather impressive difference!

Code:
Code:
[code]
float sinanswers[401];

unsigned long time1 = 0;
unsigned long time2 = 0;
void setup()
{

  Serial.begin(9600); // USB is always 12 Mbit/sec
  delay(1000);
  Serial.print("Here");
  delay(4000);
  time1 = micros();
  for (int i = 0; i < 400; i++)
  {
    sinanswers[i] = sin(i);

  }
  time2 = micros();

  unsigned long elapsed = time2 - time1;
  for (int i = 0; i < 400; i++)
  {
    Serial.println(sinanswers[i]);
    Serial.print(" ");
    Serial.println(i);
  }

  Serial.print("time elasped = ");
  Serial.print(elapsed);
  Serial.print(" micros");
}

void loop()
{

}

Results:
Code:

  //time elasped = 29721 micros = teensy
  //time elasped = 47436 micros = Uno
[/code]
Logged


Greenville, IL
Offline Offline
Edison Member
*
Karma: 15
Posts: 1330
Warning Novice on board! 0 to 1 chance of errors!
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset


 This code was only tested on the Teensy 3.0. It would not fit in the SRAM of the Uno.

Code:
float sinanswers[1001];
float conanswers[1001];
float tananswers[1001];
unsigned long time1 = 0;
unsigned long time2 = 0;
void setup()
{

  Serial.begin(9600); // USB is always 12 Mbit/sec
  delay(1000);
  Serial.print("Here");
  delay(4000);
  time1 = micros();
  for (int i = 0; i < 1000; i++)
  {
    sinanswers[i] = sin(i);
    conanswers[i] = cos(i);
    tananswers[i] = tan(i);
  }
  time2 = micros();

  unsigned long elapsed = time2 - time1;
  for (int i = 0; i < 1000; i++)
  {
    Serial.println(sinanswers[i]);
    Serial.print(" ");
    Serial.println(i);
  }
  for (int i = 0; i < 1000; i++)
  {
    Serial.println(sinanswers[i]);
    Serial.print(" ");
    Serial.println(i);
    Serial.println(conanswers[i]);
  }
  for (int i = 0; i < 1000; i++)
  {
    Serial.println(sinanswers[i]);
    Serial.print(" ");
    Serial.println(i);
    Serial.println(tananswers[i]);
  }
  Serial.print("time elasped = ");
  Serial.print(elapsed);
  Serial.print(" micros");
}

void loop()
{

  }

Results:
Code:
//time elasped = 278183 micros = teensy
Logged


Nice, France
Offline Offline
Full Member
***
Karma: 11
Posts: 237
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

It won't fit in a Mega2560 either

Quote
Binary sketch size: 6,180 bytes (of a 258,048 byte maximum)
Estimated used SRAM memory: 12,747 bytes (of a 8192 byte maximum)
Logged

Left Coast, CA (USA)
Offline Offline
Brattain Member
*****
Karma: 361
Posts: 17303
Measurement changes behavior
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

May be OT,  but is the default int size on a Teensy 3.0 different then on a standard arduino? And if different any possible problems when using arduino libraries and others users sketches?

Lefty

Logged

Nice, France
Offline Offline
Full Member
***
Karma: 11
Posts: 237
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Rather impressive difference!
Code:

  //time elasped = 29721 micros = teensy
  //time elasped = 47436 micros = Uno

Is it?

Uno: 8bit, 16MHz, no FPU
Teensy 3.0: 32bit, 48 MHz, FPU (Cortex M4 has an FPU, right?)

Now, I understand that MPU clockspeed is not the only factor, there is also memory speed and instructions/cycle and address size and quality of implementation. But at 3x the clockspeed and with hardware FPU rather than software FP emulation, I would (naively?) have expected more than a 1.5x speedup.

Edit: you can't quote code? Really?
« Last Edit: October 14, 2012, 05:21:46 pm by Nantonos » Logged

Nice, France
Offline Offline
Full Member
***
Karma: 11
Posts: 237
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

May be OT,  but is the default int size on a Teensy 3.0 different then on a standard arduino? And if different any possible problems when using arduino libraries and others users sketches?

Yeah I would tend to use uint16_t and so on when benchmarking, to compare like with like.
« Last Edit: October 14, 2012, 05:43:21 pm by Nantonos » Logged

Offline Offline
Edison Member
*
Karma: 49
Posts: 1672
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
(Cortex M4 has an FPU, right?)

Not necessarily apparently. From wikipedia:
Quote
The Cortex-M4 adds DSP instructions and an optional single-precision floating-point unit. If the Cortex-M4 has the floating point unit, then it is known as the Cortex-M4F.

Pete
Logged

0
Offline Offline
God Member
*****
Karma: 26
Posts: 625
Always making something...
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

int is 32 bits on ARM and 16 bits on AVR.  You might think that would cause lots of compatibility problems, but so far it seems pretty rare.  There are some programs that depend upon rollover, but most of them use 8 bits with "byte", "unsigned char" or "uint8_t".  It seems most authors who use such tricks are pretty conscientious about declaring proper types for the expected number of bits.

On ARM, sometimes using 8 or 16 bits is actually slower than 32 bits.  The CPU registers are natively 32 bits, so in some cases the compiler is forced to insert logical and instructions to mask off the unused bits.

The M4 core on Teensy 3.0 does not have a FPU, so floating point isn't expected to be dramatically fast.
Logged

Belgium
Offline Offline
Edison Member
*
Karma: 68
Posts: 1926
Arduino rocks; but with my plugin it can fly rocking the world ;-)
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Rather impressive difference!
Code:

  //time elasped = 29721 micros = teensy
  //time elasped = 47436 micros = Uno

Is it?
I had the same reflection. But looking at the code I think we are comparing apples with pears.
I see that sin is defined as
Code:
extern double sin(double __x) __ATTR_CONST__;
and double is not a fixed in bytes according to http://en.wikipedia.org/wiki/Double-precision_floating-point_format
I'm not sure how to fix this but If you would print the result of sin(1.2) with teensy 3 and uno I expect to get different numbers.
Best regards
Jantje
Logged

Do not PM me a question unless you are prepared to pay for consultancy.
Nederlandse sectie - http://arduino.cc/forum/index.php/board,77.0.html -

Belgium
Offline Offline
Edison Member
*
Karma: 68
Posts: 1926
Arduino rocks; but with my plugin it can fly rocking the world ;-)
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

int is 32 bits on ARM and 16 bits on AVR.  You might think that would cause lots of compatibility problems, but so far it seems pretty rare.  There are some programs that depend upon rollover, but most of them use 8 bits with "byte", "unsigned char" or "uint8_t".  It seems most authors who use such tricks are pretty conscientious about declaring proper types for the expected number of bits.

On ARM, sometimes using 8 or 16 bits is actually slower than 32 bits.  The CPU registers are natively 32 bits, so in some cases the compiler is forced to insert logical and instructions to mask off the unused bits.

The M4 core on Teensy 3.0 does not have a FPU, so floating point isn't expected to be dramatically fast.
Paul
From my coding experiences I would not expect many C/C++ issues because Arduino is all source and it communicates with very strictly defined protocols. It would be a different story if you had to link in real binaries (I mean .lib .a .dll .o ...) and not the sources (I mean .c .cpp .h ...) or you had to communicate with other running programs.
The troubles I expect would be with the code that uses the registries directly or uses hardware specific things. I have read you made some simulation code so that should solve most of the migration problems.
Great work I would say.
Best regards
Jantje
Logged

Do not PM me a question unless you are prepared to pay for consultancy.
Nederlandse sectie - http://arduino.cc/forum/index.php/board,77.0.html -

Nice, France
Offline Offline
Full Member
***
Karma: 11
Posts: 237
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Paul, Pete, thanks for the clarification.

Jantje, I had just downloaded the source of avr-gcc and found the same thing. I also found sin.S which (once you get past the license and checks for redefinition) is just

Code:
#include "fp32def.h"
#include "asmdef.h"

/* float sin (float A);
     The sin() function returns the sine of A, where A is given in radians.
 */

ENTRY sin
push rA3
rcall _U(__fp_rempio2)
pop r0
sbrc r0, 7
subi ZL, -2
rjmp _U(__fp_sinus)
ENDFUNC
« Last Edit: October 14, 2012, 07:05:46 pm by Nantonos » Logged

Belgium
Offline Offline
Edison Member
*
Karma: 68
Posts: 1926
Arduino rocks; but with my plugin it can fly rocking the world ;-)
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Nantonos
Pual, Pete, thanks for the clarification.

Jantje, I had just downloaded the source of avr-gcc and found the same thing. I also found sin.S which (once you get past the license and checks for redefinition) is just

Code:
#include "fp32def.h"
#include "asmdef.h"

/* float sin (float A);
     The sin() function returns the sine of A, where A is given in radians.
 */

ENTRY sin
push rA3
rcall _U(__fp_rempio2)
pop r0
sbrc r0, 7
subi ZL, -2
rjmp _U(__fp_sinus)
ENDFUNC
This is just one level to deep for me. smiley-confuse
This definition would be the one I would expect the UNO to use. Are you sure there is no definition of sin with long double as well?
What does the S in sin.S stand for? I googled it but it is to close to sin to find something relevant quickly.
Best regards
Jantje

PS being someone who doesn't give up easily I hope the S to stand for small or single memory model and then a sin.L (or something else) could stand for large memory model containing the long double version.  smiley-twist
Logged

Do not PM me a question unless you are prepared to pay for consultancy.
Nederlandse sectie - http://arduino.cc/forum/index.php/board,77.0.html -

Nice, France
Offline Offline
Full Member
***
Karma: 11
Posts: 237
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

It seems that .S is being used for assembler files. (And no, I don't particularly undestand the AVR assembler. Showing my age, last time I coded in assembler it was for the Zilog Z80).

It also seems that the (8bit) Arduino family consider float and double to be identical, and to mean 32bit IEEE floating point.
Logged

Dubai, UAE
Offline Offline
Edison Member
*
Karma: 22
Posts: 1675
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi,
   I had a look through Paul implementation of the Arduino libraries last night, there has been a massive amount of work

Hardware/teensy/cores/teensy3/

I found that fastest way to get upto speed on the AVRs was to read through the libraries.

Duane B
Logged


Global Moderator
Dallas
Offline Offline
Shannon Member
*****
Karma: 210
Posts: 13039
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

I also found sin.S which (once you get past the license and checks for redefinition) is just...

Well, that's a bit of sin.  The code you posted prepares a small stack frame or preserves a working register (the push/pop), calls another function that actually determines the sin, then makes an adjustment for the sign.  In other words, the bulk of the sin function is somewhere else.
Logged

Pages: 1 ... 3 4 [5] 6 7 ... 9   Go Up
Jump to: