Monday, November 21, 2022

Saturday, January 19, 2013

Raspberry Pi Performance

With Groovy inside RPI, it is hard to resist running some performance tests after talking to my students. I know it will be unfair to compare RPI with a typical PC which costs more than 10-20 times however it will be interesting to see how far behind the RPI will be.
For that, I use 2 scenarios to evaluate the performance. The first scenario writes 2000 (by default) integers into a file. The second scenario reads the saved integers from the file and append them to a buffer. These scenarios exercise I/O, loop and string accumulation to a buffer. Each scenario runs 10 times, discards the best and worst performance then compute the average.

Raspberry Pi model B specs:
CPU: ARM11 700Mhz
RAM: 512MB
OS: Linux
Disk: 8GB class 4


PC specs:
CPU: Intel Core i5 2.6GHz Dual Core with hyper-threading technology
RAM: 16 GB
OS: Windows 7
Disk: 320GB 5400 RPM


Groovy Script to evaluate the performance: 
int maxFile = 10
int maxValue = args.length ? args[0].toLong() : 2000

long start
def l = []

// write to file
maxFile.times {
       File f = new File("perf${it}.txt")
       start = System.currentTimeMillis()
       maxValue.times {
              f << "${it}\n"
       }
       l << System.currentTimeMillis() - start
       println "Write to file: ${l[it]} ms"
}
println "Write to file avg:${(l.sum() - l.max() - l.min())/(maxFile - 2)} ms"

// read from file
l = []
StringBuilder sb
maxFile.times {
       sb = new StringBuilder(10000)
       File f = new File("perf${it}.txt")
       start = System.currentTimeMillis()
       f.eachLine {
              sb.append it
       }
       l << System.currentTimeMillis() - start
       println "Read from file: ${l[it]} ms, sb length:${sb.size()}"
}
println "Read from file avg:${(l.sum() - l.max() - l.min())/(maxFile - 2)} ms"

// delete file
maxFile.times {
       File f = new File("perf${it}.txt")
       f.delete()
}

RPI Results:
Write to file: 4368 ms
Write to file: 2063 ms
Write to file: 1938 ms
Write to file: 1969 ms
Write to file: 1938 ms
Write to file: 1950 ms
Write to file: 1941 ms
Write to file: 1918 ms
Write to file: 1927 ms
Write to file: 1917 ms
Write to file avg:1955.5 ms
Read from file: 309 ms, sb length:6890
Read from file: 120 ms, sb length:6890
Read from file: 52 ms, sb length:6890
Read from file: 38 ms, sb length:6890
Read from file: 38 ms, sb length:6890
Read from file: 38 ms, sb length:6890
Read from file: 38 ms, sb length:6890
Read from file: 39 ms, sb length:6890
Read from file: 38 ms, sb length:6890
Read from file: 38 ms, sb length:6890
Read from file avg:50.125 ms
 

PC Results:
Write to file: 1647 ms
Write to file: 1411 ms
Write to file: 1410 ms
Write to file: 1627 ms
Write to file: 1372 ms
Write to file: 1443 ms
Write to file: 1177 ms
Write to file: 2094 ms
Write to file: 1387 ms
Write to file: 1206 ms
Write to file avg:1437.875 ms
Read from file: 16 ms, sb length:6890
Read from file: 14 ms, sb length:6890
Read from file: 8 ms, sb length:6890
Read from file: 18 ms, sb length:6890
Read from file: 11 ms, sb length:6890
Read from file: 11 ms, sb length:6890
Read from file: 12 ms, sb length:6890
Read from file: 7 ms, sb length:6890
Read from file: 6 ms, sb length:6890
Read from file: 2 ms, sb length:6890
Read from file avg:10.625 ms


You may have noticed that the RPI has a slow start and consistent after few iterations while the PC results are varying. In one occurrence, the PC "write" scenario is higher than most of RPI results. On average, the PC "write" scenario is ONLY 1.36 times faster than the RPI. That is really impressive for the RPI. For the "read" scenario, the PC is 4.7 times faster. Finally, by adding the cost on the table, the Raspberry Pi offers a way better cost-performance ratio. By extrapolating these results, it is not a surprise to see new/old companies building computers with several low cost processors such as ARM.

Sunday, January 13, 2013

Groove your Raspberry Pi

After playing with the GPIO by using Python as a programming language with my nephews, I was tempted to augment the Raspberry Pi (RPI) with Groovy programming language. Just image what you can do with a small machine and a modern programming language. To do that, you need to install Java and Groovy. Here I provide straightforward instructions to quickly groove your RPI.

Get a new 4GB+ SD card and flash the "Soft-float Debian, wheezy" image. The image is available at http://www.raspberrypi.org/downloads

Since you need more space to install Java and Groovy, you need to resize a partition or create a new partition. Here I provide instructions to resize the root file system for simplification. To resize the root file system, use raspi-config tool and select expand_rootfs; it will use all available space for that partition. Then reboot your RPI.

After run df -h to verify if the root file system has been resized.

Get Java 7 soft floating-point for embedded Linux (ARMv6/7 Linux - Headless EABI, VFP, SoftFP ABI, Little Endian) http://www.oracle.com/technetwork/java/embedded/downloads/javase/index.html

Create a java directory where you will unpack Java:
mkdir /home/pi/java
cd /home/pi/java
tar -zxvf ejre-7u10-fcs-b18-linux-arm-vfp-client_headless-28_nov_2012.tar.gz

Verify that java is properly installed by doing
./ejre1.7.0_10/bin/java -version

Get Groovy at http://groovy.codehaus.org/Download, here I use version 1.8.8 but you can use the latest.

Create a groovy directory where you will unpack Groovy:
mkdir /home/pi/groovy
cd /home/pi/groovy
unzip groovy-binary-1.8.8.zip

Set Java and Groovy home environment variables add their bin directory to the PATH environment variable.
export JAVA_HOME=/home/pi/java/ejre1.7.0_10
export GROOVY_HOME=/home/pi/groovy/groovy-1.8.8
export PATH=$PATH:$JAVA_HOME/bin:$GROOVY_HOME/bin

Verify Groovy installation by doing
groovy -v
groovy -e "println 'Hello World'"

Voilà you have grooved your Rapsberry Pi!

Saturday, April 7, 2012

Not so final!

Last time I was reviewing a code and found out something interesting regarding the Java finally-clause. Suppose we have the code below which adds strings to a StringBuilder and returns this object.


public StringBuilder finallyReturnString() {
StringBuilder s = new StringBuilder();
s.append("init");
try {
s.append("-try");
return s;
} finally {
s.append("-finally");
}
}


It will return a StringBuilder containing “init-try-finally”. However, let’s dissemble the code above.


   0:   new     #23; //class java/lang/StringBuilder
   3:   dup
   4:   invokespecial   //StringBuilder()
   7:   astore_1
   8:   aload_1
   9:   ldc     #80; //String init
   11:  invokevirtual   //StringBuilder.append()
   14:  pop
   15:  aload_1
   16:  ldc     #82; //String -try
   18:  invokevirtual   #36; //StringBuilder.append()
   21:  pop
   22:  aload_1
   23:  astore_3
   24:  aload_1
   25:  ldc     #84; //String -finally
   27:  invokevirtual   //StringBuilder.append()
   30:  pop
   31:  aload_3
   32:  areturn
   33:  astore_2
   34:  aload_1
   35:  ldc     #84; //String -finally
   37:  invokevirtual   //StringBuilder.append()
   40:  pop
   41:  aload_2
   42:  athrow


Here the try-clause is represented by the lines 15-23 and 31-32 and the finally-clause between the lines 24-30. The "finally" string is appended to the variable 1 or 3 and then “init-try-finally” contained in variable 3 is returned. You may have noticed that the finally-clause is repeated at lines 35-40.

Now let's take a similar example. Here we will not append string but set a new String each time. This will return "try" and not "finally".



public StringBuilder finallyReturnString() {
StringBuilder s = new StringBuilder("init");
try {
s = new StringBuilder("try");
return s;
} finally {
s = new StringBuilder("finally");
}
}



The disassembled code looks like:


   0:   new     #23; //class java/lang/StringBuilder
   3:   dup
   4:   ldc     #79; //String init
   6:   invokespecial   //StringBuilder(String)
   9:   astore_1
   10:  new     #23; //class java/lang/StringBuilder
   13:  dup
   14:  ldc     #65; //String try
   16:  invokespecial   //StringBuilder(String)
   19:  astore_1
   20:  aload_1
   21:  astore_3
   22:  new     #23; //class java/lang/StringBuilder
   25:  dup
   26:  ldc     #73; //String finally
   28:  invokespecial   //StringBuilder(String)
   31:  astore_1
   32:  aload_3
   33:  areturn
   34:  astore_2
   35:  new     #23; //class java/lang/StringBuilder
   38:  dup
   39:  ldc     #73; //String finally
   41:  invokespecial   //StringBuilder(String)
   44:  astore_1
   45:  aload_2
   46:  athrow

Here the the try-clause is represented by the lines 10-21 and 32-33, and the finally-clause by the lines 22-31. "init" and "try" strings are stored in variables 1 and 3. "finally" string is stored in variable 1 but variable 3 which contains "try" is returned.

This time, we will make things more clear in case you did not catch the twist; we will use String (immutable class) as a return type. The finallyReturnString() will also return "try".


public String finallyReturnString() {
String s = "init";
try {
s = "try";
return s;
} finally {
s = "finally";
}
}

The disassembled code looks like:


   0:   ldc     #75; //String init
   2:   astore_1
   3:   ldc     #61; //String try
   5:   astore_1
   6:   aload_1
   7:   astore_3
   8:   ldc     #69; //String finally
   10:  astore_1
   11:  aload_3
   12:  areturn
   13:  astore_2
   14:  ldc     #69; //String finally
   16:  astore_1
   17:  aload_2
   18:  athrow

The try-clause is represented by lines 3-7 and 11-12, and the finally-clause by the lines 8-10. Same as previous example, "init" and "try" string are stored in variables 1 and 3. "finally" string is stored in variable 1 but variable 3 which contains "try" is returned.
Next time when you have a return statement in your try-clause combined with finally-clause which affects variables, watch-out! May be you need to refactor your code!

Saturday, February 26, 2011

The Trio: DCNM, .Net, and Powershell

Few decades ago MS-DOS CLI was the only shell available on PC. Many of my friends do not want to hear about DOS shell even though they daily use Windows OS in their corporate environment. People trying to escape Microsoft, jump into flashy Apple world and quickly are obliged to use VMware fusion to get a piece of Windows OS to run non-converted Windows applications; what do you want Microsoft is dominant :)
It is true that DOS shell is limited for scripting and people use alternatives such as Perl, Python, Ruby, Groovy, Cygwin, etc. in Windows environment. But with Powershell, Microsoft is trying to catch up by providing a decent scripting language to administrators. With Powershell it is possible to instantiate .Net classes and access Windows OS API; that is indeed powerful for Windows environment. By adding DC network API to the mixture you get the perfect trio for your data center. Indeed, you get an OO (Object-Oriented) scripting environment where you can monitor the status and health of network resources (devices and servers), automate network and server tasks, and get events/alerts to conditions that impact network resources. These OO scripts can be seamlessly plugged into your existing environment to manage your DC network infrastructure. See the video and screen-shots below.




For the video use 720p HD and full-screen to see the shell detail.



 Screen-shots



Wednesday, January 19, 2011

DC Network API

With the proliferation of mobile devices, social networks, virtualization, cloud computing, video contents, and personal computers to perform daily activities, the electronic services over the intranet and internet have tremendously increased in the last decade. This phenomenon has significantly boosted demand in the DC (Data Center) for more storage, computation power, and bandwidth. As a result in the DC, the number of network devices and computers have increased, and its management and monitoring become more and more complex and costly. While changing and growing, DC must be agile and automated to add latest network technologies without disturbing existing infrastructure or increasing downtime otherwise company might lose revenue, credibility and business. Today, network API springs up in few companies to assist IT in their quest to reduce network operation complexity and expense. In this area, Cisco Systems offers a DC network API worthy to discuss.  This API is part of DCNM (Data Center Network Manager) product and allows to automate, manage and monitor the network portion of the Data Center. In DCNM, functional management areas (configuration, provisioning, inventory, monitor, fault and troubleshooting) are in a single product and works in unison, consequently its interfaces are not disparate increasing operational efficiencies. The DC network API can be an ingredient of your DC automation; it can be used as an Adapter to complement your existing management infrastructure and provides a unified and coherent views of your DC network.  It may save you time and money, and on top of that the good news it is freely available. To read more about this article see:
http://sites.google.com/site/aznichet/dc-network-api