Some interesting execution time tests, 101 vs. UNO

I was briefly considering the 101 for a pulse generator application and did some crude timing tests with the same code running on a 101 (Intel Curie, 32 MHz, core 1.0.5) and an UNO (Atmega 328, 16 MHz).

This is not a thorough or representative exploration, but the results might interest someone else. The procedures are as follows:

a. loop execution with 2 "if" conditionals and ~ 5 variable assignments b. all above plus a bare-bones (2-line) integer pseudorandom sequence generator c. all above plus a floating-point remapping that calls a logarithm, i.e. log()

Results in microseconds:

UNO: a=4, b=11, c=215 101: a=1, b=5, c=368

The surprising thing is the last entry; adjusting for clock rate, the 101 appears 3.4 x less efficient at the log() and associated conversions (other tests I've done confirm it's mostly the log). Neither processor has a FPU, so this sort of calculation should be avoided unless you really need it.

Please forgive the test code, it was just a hasty snip out of my project. I won't have the 101 much longer so I'm posting what I have in case it is useful for anyone else.

#define pulseOutPin     7
#define pulseBarOutPin  6
#define buffySize       512           // for buffer method
unsigned int buffy[buffySize];              // for buffer method
unsigned long tic = 0;
unsigned long toc = 0;
unsigned long toe = 0;
unsigned long standardSeed = 701;     // seed for standardRand()
unsigned long tauMean = 600;          // microseconds
long delayTime = tauMean;             // microseconds [NB: may go negative temporarily !]
unsigned int pulseWidth = 0;                  // microseconds
int fixedRate = 1 ;                   // mode switch
int b = 0;                            // diagnostic, limit serial writes inside loop()

void setup() {
  Serial.begin(115200);
  while(!Serial);
  Serial.println("req time"); Serial.print("\t");
  Serial.print("calc time");Serial.print("\t");
  Serial.println("elapsed total");

  digitalWrite(pulseOutPin, LOW);
  digitalWrite(pulseBarOutPin, HIGH);
  
  standardSeed = analogRead(A0);          // seed PRNG with open ADC noise
  tauMean = max(tauMean, pulseWidth);     // floor
  
  for (int k = 0; k < buffySize; k++) {     // fill buffer;
    buffy[k] = getExpRand(tauMean);
  }
} // end of setup()

void loop() {
  tic = micros();                         // mark time
//  digitalWrite(pulseOutPin, HIGH);
//  digitalWrite(pulseBarOutPin, LOW);
  delayMicroseconds(pulseWidth);
//  digitalWrite(pulseOutPin, HIGH);
//  digitalWrite(pulseBarOutPin, LOW);
//  //
  if (fixedRate != 0) {                   // constant pulse interval
    delayTime = tauMean ;
  } 
  else {
    if (tauMean > 701) {
      //  generate-on-the-fly method
      float sample = standardRand() * 3.0517578e-05;  // uniform long int mapped to float in [0,1)
      sample =  tauMean * (-log(1.0 - sample));       // uniform to exponential PDF
      delayTime = (long) sample;               // desired interval to next pulse start
    }
    else {
      //  scramble-the-preloaded-buffer method
      int j = standardRand() % buffySize;           // random pointer in [0 , buffySize)
      delayTime = buffy[j];                    // desired interval to next pulse start
    }
  }
    //  calculate time to next pulse start
    toc = micros() - tic;                   // elapsed time from last pulse start
//    delayTime = delayTime - toc;            // deduct from desired  (RESULT MAY BE NEGATIVE!)
    delayTime = max(delayTime, 0);          // floor at zero delay
    if (delayTime > 999 ) {
      delay(delayTime / 1000);                  //
    }
    delayMicroseconds(delayTime % 1000) ;   // delay remaining microseconds
  //  diagnostics
  toe = micros() - tic;
  if (b < 1000) {
    b++;
    Serial.print(delayTime); Serial.print("\t");
    Serial.print(toc); Serial.print("\t");   // microsec
    Serial.println(float(toe/1000.), 3); Serial.print("\t");         // calc exec + pulse time
    delay(1);
  }

} // end of loop()

unsigned int standardRand() {
  /*
     basic PRNG as supposedly used in C "rand()" function
     from Kernighan & Ritchie, 2nd ed., p.43
  */
  standardSeed = standardSeed * 1103515245 + 12345;
  return (unsigned int)(standardSeed / 65536) % 32768;
} // end of standardRand()

unsigned int getExpRand(unsigned long distMean) {
  /*
    generate exponentially-distributed random number with specified mean
  */
  float samp = standardRand() * 3.0517578e-05;  //  uniform dist, int mapped to float in [0,1)
  samp =  distMean * (-log(1.0 - samp));   // exp dist with mean = distMean
  return (unsigned int) samp;
} // end of getExpRand()

The only thing I would probably change is the use of DELAY as everyone knows it is a BLOCKING function.

There are non blocking methods for delays which may alter your results.