YOUR FEEDBACK
NGASI Releases AppServer Manager 8.1
Dave Jenkins wrote: The remote server management is a welcomed added feature...

SYS-CON.TV
TOP MICROSOFT .NET LINKS


F# on a Virtual Super Computer
Understanding grid computing

Digg This!

Page 2 of 2   « previous page

Listing 5 defines a module called pb and creates a prototype for the CalculatePiDigits function. To a C# developer this looks really strange! It's essentially saying CalculatePiDigits takes an integer as an input and returns a string. The strangeness will continue as we look at the meat of the calculation class. But before I got into full-fledged F# development, I wanted to make sure it would run on the grid. I added the code in Listing 6 to pb.fs as a test.

From Listing 6, we see that we begin by declaring the implementation of module pb followed by opening System. Opening in F# is equivalent to the using statement in C#. Next we define a function CalculatePiDigits using the let syntax. CalculatePiDigits will explicitly take an integer, n, as an input argument and implicitly return a string. This is a key and unique feature of F#, the ability to mix explicit and implicit typing.

To call the F# code contained in the pb module, I modified the Start method of the PiCalcGridThread class and included the Microsoft.FSharp namespace statement in Listing 7.

After compiling the solution and running it, everything appeared to work but it showed Pi as 3 with no numbers after the decimal. A little digging into the Alchemi user guide and the log file revealed that my F# based plouffe_bellard.dll wasn't being sent to the executor. To overcome that I had to add the lines in Listing 8 to the startup code.

Adding file dependencies to the GApplication manifest let Alchemi distribute these files with the tasks. As a result the F# code can run on remote machines. Alternatively you can specify the standalone compiler option to compile these into a single DLL. If you use this option the dependency code looks like Listing 9. After this was done, the job ran. Figure 4 shows the result of the first test run.

I could now move on to rewriting the C# Plouffe-Bellard calculation class in F#. As a result of a lot of reading and instant messaging with optionsScalper, the first working F# Plouffe-Bellard module is in Listing 10.

To compare the differences between C# and F# take a look at Listing 2 and Listing 10. As you can see the use of F# mutables helps in this endeavor immensely! Mutables in F# are modifiable, by reference, values that are implicitly dereferenced. Mutables use the local mutation assignment operator: id exp r. As you become a more experienced F# developer, you'll find yourself using mutables less. However, mutables are indispensable when doing direct C# to F# conversion as you'll see.

Going All In
With the basic Plouffe-Bellard algorithm working well in F#, it was time to get rid of the C# all together. I began by converting the C# GThread over to F# by adding the definition to the pb.fsi file and the implementation to pb.fs as shown in Listing 11 and 12.

You'll see the similarities between Listing 4 and Listing 12. The differences include:

  • Inheritance technique
  • Constructor implementation
  • Use of base class
  • Method overloading technique
While certainly not an all-inclusive list of differences, they are some of the items I ran into. Inheritance is done using the inherit keyword just below the class definition.

Constructors are implemented using the new keyword and can be defined as using the keyword to access the base class. The use of the base class is required to implement method overloading using the override keyword.

Finally, I implemented the main code in F# in Listing 13.

In this code segment, some of the issues I ran into with F# are:

  • Hooking into events
  • Exception handling
  • Type up and down casting
The method for hooking events in F# reminds me of COM connection points. Instead of the addition assignment operator used in C#, we use the Add method of the IEvent interface. To the Add method we pass fun evArgs -> expr, where expr is an appropriate implementation of a callback. Exception handling takes on the try/with and try/finally forms in F#. Try/with is similar to try-catch blocks in C# while try/finally is similar to the try-finally. Up casting occurs when a type is converted to a more general type whereas down casting can occur on types that are derived from a more general type.

An example would be type car is derived from type vehicle then car needs to be up cast to a vehicle and vehicle needs to be down cast to a car.

More Advanced F#
F# was originally written by Dr. Don Syme of Microsoft Research. Dr. Syme still maintains F# and plays an active part of the F# community. After discussing this article and its code with him, he suggested some changes. The changes highlight some of the advantages of using F#. In particular he suggested:

  • Use for-loops instead of while loops
  • Try to remove mutables
  • Try to stick with F# convention and use lower case variable names for most letbound variables and arguments
  • Make your classes smaller and more reusable. Classes rarely need to capture variables explicitly
Dr. Syme was nice enough to provide a rewrite of some of my code segments. In Listing 14 you can see some of the major areas where thinking in F# can produce more elegant code.

The hardest thing for me to adapt to has been the use of let-bound functions. While it reminds me of the use of macros in other languages, I'm still not used to seeing them inline with the rest of the code. You can see an example of this in Listing 14. The declaration of check in the is_prime function took me a while to understand.

Performance Comparison
One of the most interesting parts of this process was examining the performance differences between C# and F#. My initial assumption was that the F# code had to be slower. This, in fact, is not the case. In a starting benchmark, I wanted to examine the differences in performance of the Plouffe-Bellard calculation.

Without any optimization the F# implementation took 453 ms. C# finished up in 62 ms. Turning optimization on caused the C# results to drop to 46 ms. And, most shocking of all, the F# was dead even at 46 ms! Apparently, the F# compiler does an excellent job optimizing the code. Continuing on, I ran the entire C# and F# grid applications against one another. Without any optimization the C# code took 3.9 seconds to calculate 100 digits of pi while F# only took 2.8 seconds. Optimizing this application showed that F# would finish in 1.5 seconds while C# would not complete any faster than 2.6 seconds. (Table 1)

A look at the IL showed the reason for the difference. From the beginning of Listing 10 you can see the use of the inline keyword, not available in C#, this lets F# squeeze out a little more performance. If you're not familiar with the concept of inline functions, let me explain. Each time a function is called arguments need to be pushed onto the stack or stored in registers. When the function is done results need to be pushed onto the stack, all this takes time. The cost of these calls can be avoided by moving the function into the body of the calling code. The C# compiler doesn't support the inlining, instead, it relies on the JIT to do this. Here's a simplified list of heuristics that the JIT uses to decide if a method should be inlined:

  • Methods that are greater than 32 bytes of IL won't be inlined.
  • Virtual functions aren't inlined.
  • Methods that have complex flow control won't be in-lined. Complex flow control is any flow control other than if/then/else; in this case, switch or while.
  • Methods that contain exception-handling blocks aren't inlined, though methods that throw exceptions are still candidates for inlining.
  • If any of the method's formal arguments are structs, the method won't be inlined.
F# can still take advantage of the JIT optimization but also allows the developer to control the use of method inlining. As a result, an F# developer can more explicitly control the performance characteristics of an application.

Conclusion
The intent of this article was to provide you with a glimpse into some exciting new technologies. I've presented some strategies for converting C# to F#, implementation of algorithms in F# and corresponding performance results. While discussing this article with a number of colleagues, it's obvious that there are a lot of applications for the coupling of these technologies. Further work might include the integration of grid computing into the F# language as well as the F# interactive console. Hopefully this article will inspire you to include F# and grid computing in your list of tools available to attack future problems.

Resources


Page 2 of 2   « previous page

About Chad Albrecht
Chad Albrecht is president of EnerLinx.com, Inc.

MICROSOFT .NET LATEST STORIES
Peer Networking Series - A Closer Look at PNRP vs. Bonjour/ZeroConf
It seems as though whenever I bring up PNRP and its benefits, I am immediately inundated with a list of questions or comments indicating that Microsoft is re-inventing the wheel and that PNRP has already been implemented before in the form of ZeroConf and, more specifically, Apple's im
Microsoft, Unisys, Yahoo and Vista
Microsoft, which spent $6 billion on aQuantive and was chasing Yahoo for its ads before it came to a dead stop, has been supporting - as in helping write - legislation in New York and Connecticut that would regulate the data that companies like Yahoo and Google collect for targeted adv
AJAX World - Xceed Launches Microsoft Silverlight 2 Control
Xceed launched Xceed Upload for Silverlight, the commercial offering in support of Microsoft's promising new Silverlight technology. The product is available now for purchase or as a fully functional 45-day trial on Xceed's website. Xceed Upload for Silverlight lets developers add uplo
Microsoft To Keynote 4th International Virtualization Conference & Expo
Mike Neil is general manager for virtualization strategy in the Windows Server Division at Microsoft. Mike is focused on the delivery of the Windows virtualization technology, including Windows Server 2008 Hyper-V, Microsoft Hyper-V Server and Virtual PC 2007. Mike also directs the tec
Microsoft Virtualization Takes Management Cross-Platform
Microsoft is making System Center, its central management scheme, natively manage Linux, Unix and VMware virtual servers. The widgetry has always been a Windows-only affair, but now there are betas available showing off Microsoft's cross-platform prowess, important to Microsoft's place
SUBSCRIBE TO THE WORLD'S MOST POWERFUL NEWSLETTERS
SUBSCRIBE TO OUR RSS FEEDS & GET YOUR SYS-CON NEWS LIVE!
Click to Add our RSS Feeds to the Service of Your Choice:
Google Reader or Homepage Add to My Yahoo! Subscribe with Bloglines Subscribe in NewsGator Online
myFeedster Add to My AOL Subscribe in Rojo Add 'Hugg' to Newsburst from CNET News.com Kinja Digest View Additional SYS-CON Feeds
Publish Your Article! Please send it to editorial(at)sys-con.com!

Advertise on this site! Contact advertising(at)sys-con.com! 201 802-3021

SYS-CON FEATURED WHITEPAPERS

ADS BY GOOGLE
BREAKING NEWS FROM THE WIRES
PR Newswire Summary of Technology Copy, May 9, 2008
Following is a summary of high technology news releases transmitted today by PR Newswire. T