9 Replies Latest reply on Aug 29, 2014 3:02 AM by SpiderKenny

    Quick and dirty comparison Windows ™ v Linux

    SpiderKenny

      Here is a really quick and dirty, non scientific comparison of a Galileo GEN1 board running Windows ™ against the same board running linux.

      SPI Flash version is 1.0.2.

       

      Login to windows is via telnet.

      Login to linux is via ssh.

       

      Time taken from power-on to login:

      Linux  48 Seconds

      Windows 68 Seconds

       

      Time taken to power off:

      Linux    3.25 Seconds

      Windows  12.54 Seconds

       

      Next I wrote a simple 'blink' executable thats sets up Pin 13 for GPIO and then turns it on/off in a tight loop. Source code for both is below. Both are built in 'release' mode.

      To write the app for Windows on Galileo you need an external PC running Windows 7 or later, and Visual Studio 2013 or later, with the Microsoft IoT dev kit extensions installed.

      To write the app for Linux, you need any PC or Terminal capable of attaching via telnet or RS232.

       

      Size of simple 'blink' executable

      Linux  10080 Bytes

      Windows 19456 Bytes

       

      Speed of executing GPIO Writes

      The simple app after setting up the GPIO runs in a tight loop just switching the GPIO Pin to 1 and 0 continuously.

      The Linux loop:

      while(1)

      {

          write(fd,"1",1);

          write(fd,"0",1);

      }

      The windows loop:

      void loop()

      {

          digitalWrite(led, LOW);    // turn the LED off by making the voltage LOW

          digitalWrite(led, HIGH);  // turn the LED on by making the voltage HIGH

      }

       

      These gave the following results:

      The Linux version gave a steady 223.9 Hz square wave with a 50% duty cycle. Pulse width is about 2.24 ms.

      Screen Shot 2014-08-27 at 15.00.42.png

       

      The Windows version gave a jittery 42.72 Hz wave with a 35% Duty cycle. Pulse width is about 14.97 ms, but there were occasional gaps in the wave form where it paused for 10 ms or so.

      Screen Shot 2014-08-27 at 14.36.39.png

       

      And finally, the full source code for each of the test apps.

      Linux source code:


      #include <stdint.h>

      #include <unistd.h>

      #include <stdio.h>

      #include <stdlib.h>

      #include <string.h>

      #include <fcntl.h>


      void setGPIOPin(char* pin, char* dir, char* drive, char* val)

      {

        char buf[256];

        int fd;

       

        // Open the GPIO Export file

        fd = open("/sys/class/gpio/export",O_WRONLY);

        if(fd == -1)

        exit(-1);

       

        // Export chosen pin

        write(fd, pin, strlen(pin)); // Export GPIO pin

        close(fd);

       

        // Open exported pin DIRECTION file

        sprintf(buf,"/sys/class/gpio/gpio%s/direction",pin);

        fd = open(buf,O_WRONLY); // open GPIOxx direction file

        if(fd==-1)

        exit(-1);

        // write out the direction

        write(fd,dir,strlen(dir)); // set GPIOxx direction to out

        close(fd);

       

        // open the drive file

        sprintf(buf,"/sys/class/gpio/gpio%s/drive",pin);

        fd = open(buf,O_WRONLY); // open GPIO drive strength file

        if(fd==-1)

        exit(-1);

       

        write(fd,drive,strlen(drive)); // set GPIO drive

        close(fd);

       

        sprintf(buf,"/sys/class/gpio/gpio%s/value",pin);

        fd = open(buf,O_WRONLY);

        if(fd==-1)

        exit(-1);

       

        write(fd,val,strlen(val)); // set GPIO value

        close(fd);

       

      }


      void setMux(void)

      {

       

        // Switch all the SPI1 pins through to the header pins. And enable level shifter.

        setGPIOPin("55","out","pullup","1"); // mux

        setGPIOPin("39","out","pullup","1"); // Pin 13

        setGPIOPin("4","out","pullup","1"); // Level shifter

      }

       

      int main(int argc, char *argv[])

      {

        int fd;

       

        setMux();

       

        fd = open("/sys/class/gpio/gpio39/value",O_WRONLY);

        if(fd==-1)

        {

          printf("Failed to open GPIO On pin 13\n");

          exit(-1);

        }

       

        while(1)

        {

          write(fd,"1",1);

          write(fd,"0",1);

        }

       

        return 0;

      }

       

      Windows Source code:

      #include "stdafx.h"

      #include "arduino.h"


      int _tmain(int argc, _TCHAR* argv[])

      {

          return RunArduinoSketch();

      }

       

      int led = 13;  // This is the pin the LED is attached to.

      void setup()

      {

          pinMode(led, OUTPUT);      // Configure the pin for OUTPUT so you can turn on the LED.

      }

       

      // the loop routine runs over and over again forever:

      void loop()

      {

          digitalWrite(led, LOW);    // turn the LED off by making the voltage LOW

          digitalWrite(led, HIGH);  // turn the LED on by making the voltage HIGH

      }

        • 1. Re: Quick and dirty comparison Windows ™ v Linux
          AlexT_Intel

          Nice one, thanks! Hopefully the Windows' result is going to improve over time - after all they're just starting with this

          • 2. Re: Quick and dirty comparison Windows ™ v Linux
            flummer

            Isn't this comparison slightly skewed?

             

            The Windows example uses the Arduino function abstraction layer, but the Linux one doesn't?

             

            I don't know exactly how to manipulate the regular I/O under Windows, but I did a test with the internal LED (On Board LED based on this example, just switching as fast as possible), and the performance was way better, probably because that one doesn't go through the I/O expander if I recall correctly.

             

            Maybe a similar test with the internal LED would be interesting.

             

            The Arduino abstraction layer does give a performance hit, also on the regular AVR chips.

             

            /Thomas

            • 3. Re: Quick and dirty comparison Windows ™ v Linux
              AlexanderMerz

              The test is flawed because Window has a base tick between 10 and 16 ms. Arduino.h respects and takes care of this to some extent. So, at least re-try a test like this:

               

              void loop()

              {

                   while(true) {

                     digitalWrite(led, LOW);    // turn the LED off by making the voltage LOW

                     digitalWrite(led, HIGH);  // turn the LED on by making the voltage HIGH

                   }

              }

               

              Also to be fair: really use a binary created by Intels Arduino IDE to include the Arduino-Overlay also on Linux - or if you want to do it on a base level, use the embprusr.dll-API directly or the GPIO Driver API of Windows.

               

              I made some other tests basically like this (SPI Linux +Arduino IDE vs. Windows + VS + Arduino.h):

               

              int startts = 0;

              int endts  = 0;

              int ts        = 0;

               

              ...

               

              void loop()

              {

                

                 startts = millis();

                 digitalWrite(13, 1); // or int  i = digitalRead(13);

                 endts = millis();

               

                 ts = endts - startts;

                // systemspecific Log output method.... Serial. vs. Log() 

               

              }

               

              As a result:

              digitalRead: Linux - 2ms, Windows - 110ms

              digitalWrite: Linux - 62ms, Windows - 210ms

               

              It would be nice to see, if somebody could verify the results, because they seems to high (for Win and Linux)

              • 4. Re: Quick and dirty comparison Windows ™ v Linux
                SpiderKenny
                Isn't this comparison slightly skewed?


                There is no other way to access GPIO under windows. I used the best possible method on each platform.

                • 5. Re: Quick and dirty comparison Windows ™ v Linux
                  SpiderKenny
                  The test is flawed because Window has a base tick between 10 and 16 ms


                  The tick resolution has nothing at all to do with code execution! It might if I was using SetTimer and ON_TIMER but I am not.


                  • 6. Re: Quick and dirty comparison Windows ™ v Linux
                    SpiderKenny

                    >>Arduino.h respects and takes care of this to some extent. So, at least re-try a test like this:


                    Well then your arduino.h is different from mine!


                    My arudino.h calls loop() in a while(1) loop like this:


                    while(1)

                    {

                         loop();

                    }


                    So the tick resoltion does not come into it in any way at all.

                    Anyway, I repeated the test using this as the windows loop:


                    while(1)

                    {

                    digitalWrite(led, LOW);    // turn the LED off by making the voltage LOW

                           digitalWrite(led, HIGH);  // turn the LED on by making the voltage HIGH

                    }


                    And got almost exactly the same results as my original post, to within 0.2 mS

                    • 7. Re: Quick and dirty comparison Windows ™ v Linux
                      SpiderKenny

                      Also to be fair: really use a binary created by Intels Arduino IDE to include the Arduino-Overlay also on Linux - or if you want to do it on a base level, use the embprusr.dll-API directly or the GPIO Driver API of Windows.


                      Well, that's not the point!


                      If I was going to " use the embprusr.dll-API directly or the GPIO Driver API of Windows" then I'd have to use low-level IOCLTs and driver interaction on Linux too. Both platforms would score a performance interaction. What I used was the features and facilities as provided by both platforms, at the user level, using the templates provided by both platforms. On windows that means the Visual Studio templates, because that is where you start, on linux is means an empty text file edited in "vi" or "nano" or whatever your favourite text editor is.


                      The point is that I compared easy user-mode code, without having to resort to low level APIs or device-driver interaction on both platforms. (Granted, the windows loops could have been slightly more optimised by putting an infinite loop inside the infinite loop that arduino.h already provides, but even when I did that, it made very little difference to the results.

                      I created simple apps that anyone can do, using the features provided by both platforms at the user level, without resorting to low-level drivers and API interaction and recorded the results. It is what it is. And I did say it was quick and dirty, and non scientific.


                      If I were to write some code taking advantage of windows DLLs and even maybe using IOCTLs to interface directly to the low level device drivers. And do the same thing in linux, I still think linux would come out on top. I'm not flogging windows, I'm just presenting what I found.

                      • 8. Re: Quick and dirty comparison Windows ™ v Linux
                        Marss

                        Login to Windows via Telnet using PuTTY but connection is lost every 3-4 minutes need to reboot the board everytime it happens. checked packet loss by using ping

                        • 9. Re: Quick and dirty comparison Windows ™ v Linux
                          SpiderKenny

                          It might be better to start a separate discussion on this topic.

                           

                          But I haven't seen that at all, so I wonder what is different with your setup?

                          Do you have it connected like Microsoft's suggestion to hook the Galileo directly to a Laptop, or do you connect to a hub/switch? (I use a switch).

                           

                          Is there anything else running on Galileo at the same time?