Cypress PSoC 6 Kit Arrives

I received my Cypress PSoC 6 BLE Pioneer Kit.  Once again, Cypress has put together a nice little package for doing some prototyping of their products.  The kit came with a PSoC 6 BLE chip (Dual Core MCU, 1MB Flash, 288K SRAM, BLE Radio) on board and some nice on-board peripherals to play with.  It also came with an E-Ink Display shield/board.  I never used an E-Ink display before, only saw them in Kindles as I walked by.  I’m interested to see the power/performance of such a device.  Time to download the beta version of their PSoC Creator software with supports the PSoC 6 series.  I really hope this new chip is worth the wait.

How Fast is the Arduino Uno?

This was a question that popped into my mind lately.  Or rather, how efficiently does the Arduino Uno execute its C code?

I had read lots of articles of people switching to 32-bit chips on the Arduino platform in order to get better performance.  At first, I did not think much of this, but then started pondering why.  I mean, the 8-bit Uno can effectively execute one instruction per clock cycle giving it about 16 million instruction-per-second throughput.  Personally I think that is damn quick.  That beats my old Commodore Amiga computer by about four times (and that computer could play games, browse the Internet and run office productivity software.)  I started wondering if the Uno wasn’t actually attain its theoretical level of performance.  Does the C code compile so poorly that you lose a majority of the processing power?  To answer that question, I devised a little benchmark to see how efficiently the Arduino Uno can execute the mundane tasks associated with microcontrollers.

Here is the code.  The results are sent to the serial console.  (9600 baud)

// ---------------------------------
// Simple 'C' Benchmark for Arduino.
// ---------------------------------
// Date:  Aug. 3, 2016
// By: Brian Chhristian

// Clear the instruction counter.
unsigned long count = 0;

void setup()
{
    // There is nothing to initially setup.
}

void loop()
{
    count = 0;    // Clear the instruction counter
    int b = 0;    // Initialize result variable.
    
    // Get start time.
    unsigned long start_time = micros();

    // DO SOME STUFF.
    // I tried picking some commonly used functions to simulate
    // what might be used in the real world.  I did not use any
    // crazy mathematics as they are probably no indicative of
    // what the average user may incorporate.

    count++;                                // Increment instruction counter for each line of code.
    for (unsigned int x=0; x<1000; x++)     // Do something 1,000 times.
    {
        count++;
        b = DoSomething(1);                  // Jump to a subroutine.
    }

    // Get completion time.
    count++;
    unsigned long end_time = micros();

    // Calculate elapsed time and IPS performance.
    unsigned long calc_time = end_time - start_time;
    unsigned long ips = count / (calc_time * 1E-6);

    // Send result via serial console and wait.
    Serial.begin(9600);
    Serial.print("Expected result (1): ");
    Serial.println(b);
    Serial.print("Lines of code executed: ");
    Serial.println(count);
    Serial.print("Execution Time (us): ");
    Serial.println(calc_time);
    Serial.print("MIPS: ");
    Serial.println(ips / 1E6);
    Serial.println("");
    Serial.end();

    // Wait before running again.
    delay(5000);
}

// Do some stuff in a subroutine.
int DoSomething(int y)
{
    count++;
    int b = 0;

    count++;
    for (int z=0; z<16; z++)   // Do something 16 times.
    {
        count++;
        int a = a + 1;

        count++;
        if (a > 8)             // Lets do a compare.
        {
            count++;
            b = b + 10;        // How about some math.
        }
    }

    // Some more simple math and bit operations.
    count++;
    b = b / 2;

    count++;
    b = b & 8;

    count++;
    b = b << 3;
    
    count++;
    b = b - 63;
    
    count++;
    return b;          // Let's return.
}

There really isn’t anything scientific about this benchmark.  I just did a number of loops with compares, bit operations and some simple math.  This is somewhat representative of the kind of code I generally use.  Hardly ever do I use complex math in my controller projects, so I left that kind of stuff out.

What I have found with this experiment is that, as a baseline, you can assume the Uno can execute around 2.5 million lines of code per second.  Definitely the kind of code you write can make a big difference, but I feel this gives me a good starting benchmark when determining whether or not something is feasible on the Uno.  (Now if only the “digitalWrite” routine was as quick…)