Jeroen's profileCaptain's BlogBlogLists Tools Help

Blog


    January 06

    Parallel Programming using Parallel FX

    I am back to blogging now that we have moved to a new house and gone through the redecoration from hell.

    Anyway, back to today's topic, Parallel Programming. In the past Moore's law has been good to software developers. We didn't need to change our ways as every 18 months the execution speed of our software doubled.... completely for free.

    Nowadays CPUs are becoming faster by adding multiple cores. Unfortunately each individual core does not run significantly faster than their predecessors. We, software developers, actually have to adapt to this multiple core phenomenon to squeeze more performance out of our applications, which is less than trivial.

    Fortunately the nice people at Microsoft are constantly working to make or lives easier, this time by introducing the Parallel  FX library.

    I won't go into too much detail about the ins ad outs of the framework, the links provided below do a much better job at that. Let's just say that the Parallel FX framework automatically figures out how to divide bitesize chunks of work over the available processors and cores.

    As a test I downloaded the libraries and created a sample application in Visual Studio 2008 that executes the work in both the traditional sequential way as well as using the Parallel FX libraries. Note that I am executing all code on my laptop, which has an Intel Core Duo T2500 processor.

    The application is extremely useful, it calculates the area for all circles with a radius between 1 and 10000000...... as I said, very useful. As a baseline the same amount of iterations are called for an empty function.

    The results are as follow:

    • Sequential DoWorkNothing 194 msec
    • Parallel DoWorkNothing: 234 msec
    • Sequential DoWorkArea: 2979 msec
    • Parallel DoWorkArea: 1763 msec

    Based on these results, and this particular scenario, we can draw the following conclusions:

    1. Executing 10M iterations of an empty method is actually faster when done sequentially. This must be due to a little bit of overhead introduced by the libraries.
    2. Executing 10M iterations of calculating the area of a circle is 70% faster when executed in parallel when compared to sequential execution.

    Naturally neither of these scenarios are likely to be used in the real world so your mileage may vary.

    Related Links:

    June 27

    Windows Presentation Foundation - Day 4 - Optimizing video performance

     
    Before I go into the details of today's exercise I'll provide some quick links and useful information first. A few days ago Microsoft released a Post Beta 2 June CTP version of the .net Framework 3.0. Although it is always tempting to install the latest and greatest version, I advise against it as the Interactive Designer only works with the Beta 2 version. I have also had some problems installing the June version of the SDK and VS add-in. Until further notice my posts assume a Beta 2 installation.
     
    It is fun to see the WPF community growing little by little. Lee Brimelow, a very experienced Flash developer, has started an excellent WPF blog. His blog contains a number of small but powerful WPF examples that include full source code. He approaches everything from a Flash developer's point of view, which is a good thing. He has also authored a good article comparing WPF with Flash, which is spot on.
     
    On to the good stuff. Having played around with some samples, looked at the SDK and read some blog entries I feel comfortable enough to create some code and...gasp... give some advice with respect to performance.
     
    The full source code and a compiled binary can be downloaded here.
     

    Our final result

    Quite a few of the WPF showcases use a cool reflective surface that mirrors whatever action is going on, e.g. a movie, in real time. An obvious way to do this is to use 2 media elements with the same movie, vertically mirror one of the movies and add a transparency mask. Although in theory this works, it is very inefficient as the video needs to be streamed twice and decoded twice, which uses a lot of CPU and network bandwidth. It is also very difficult to keep the two video sources exactly in sync.
     
    A better way to do this is to create one MediaElement, create a vertically mirrored rectangle, and assign the MediaElement's VisualBrush to it.
     
    Sounds simple right, here is how we do it.
    1. Start Interactive Designer and create a new project
       
    2. Make the background of the Canvas black or use a fancy gradient to create a horizon
       
    3. In the Library window, select the MediaElement and draw it on the top 2/3 of the Canvas
       
    4. With the MediaElement still selected, navigate to the Properties Window and specify a video stream in the Source property, e.g. mms://wm.microsoft.com/ms/msnse/0606/27918/NathanDunlap_MBR.wmv
       
    5. Use the Rectangle Tool from the Toolbox Window to draw a rectangle about 1/3 of the height of the canvas straight underneath the MediaElement. I use gridlines and '0' margins to position everything and line things up, but you can also do it the quick and dirty way.
       
    6. Use the Properties Window to give the rectangle a name, in this case 'Reflection'
       
    7. To vertically mirror the rectangle, grab the handle at the top middle of the rectangle and flip it vertically by dragging it underneath the bottom line of the rectangle.

    The look of the fully created Scene in ID
     
    Make sure you save often as ID crashes frequently. I had to perform the previous steps about 3 times due to all kind of crashes.
     
     
    Now for the tricky bit, we need to create a vertical opacity mask in the Reflection rectangle. Follow the steps outline below:
    1. Select the Reflection rectangle
       
    2. In the Appearance Window select the OpacityMask
       
    3. Select the Linear Gradient Brush, the third icon from the left
       
    4. Select the right most gradient stop, the white one, and give it an 'A' (Alpha) of 0. The Opacity mask now blends from opaque to transparent.
       
    5. To rotate the Opacity Mask 90 degrees, select the Brush Transform Icon from the Tools Window. Rotate the arrow in the reflection rectangle by 90 degrees until the white part of the gradient is at the top (Weird, you would expect it to be the other way around and have the transparency at the bottom). After rotating, move the arrow 50% up and make it 2/3 of the original size. This provides a more realistic reflection

    Creating the opacity mask
     
    The scene is now finished, we just need to add a little bit of code to assign the Video's brush to the reflection rectangle:
    1. Open scene1.xaml.cs using the Projects Window
       
    2. Add the following code to the constructor to create a new VisualBrush and assign it to the rectangle.

      // Insert code required on object creation below this point.
      Reflection.Fill = new VisualBrush(MediaElement);
    That is it, press F5 to see the final results.
     
    Because we have been a bit naughty it doesn't work 100% as expected. The reflection takes the full size of the rectangle while the video may be much smaller. The reason for this is, most likely, that we didn't wait for the video to finish initialising (and thereby determining the video's width) before assigning it to the rectangle.
     
    There are 2 solutions, either wait for the video to initialise or draw a Border element around the video and use that border's VisualBrush, including the embedded video, as the reflection. The Border has a fixed width so we don't need to wait for it to finish loading.
     
    I secretly thought that this video would play roughly using the same CPU percentage as it would take Windows Media Player. Unfortunately that is not the case, even when we remove the reflection. While Windows Media Player only takes 10% CPU time, this WPF application almost maxes out one of the cores of my Core Duo CPU. If Anyone can shed any light on this then that would be much appreciated as the current performance is unacceptable, especially considering my Laptop has a 512MB Radeon X1600.
     
    Update: I contacted Andrew Whiddett and he mentioned that using video in brushes causes a bit of a performance problem in B2 and that it should be fixed in the post B2 build. This however has not yet been verified. I double checked and turning off the video brush increases performance by quite a bit.
     
    June 20

    Windows Presentation Foundation - Day 3 - What I have learned so far

     
    Ok, so Day 2 was really interesting, especially because the documentation in the SDK is not very up to date or correct. This required me to be very creative to get things to work. The good thing is that playing around is often the best way to learn a new technology.
     
    During my experimentations I also played around with the Interactive Designer (ID) by copying XAML between VS and ID and creating some animations. ID Shows promise, but it is not quite there yet. The user interface for the timeline is quite basic especially when compared to the Macromedia Flash one. For example it does not seem to be possible to insert frames or easily move (key) frames to a different position without selecting them painstakingly one by one.
     
    One of the things I like is the ability to copy the XAML between ID and VS. For example, I had absolutely no idea how to absolutely position an element in a grid. The easiest way to find this out is to just do it in ID and see what XAML is generated. It turns out that you don't position elements with TOP, LEFT etc properties, but by setting the margin attribute. Unconventional, but there is probably a good reason for doing it this way.
     
    Unfortunately, the moment you add any kind of animation to a scene in ID it no longer seems to be possible to copy the XAML to VS due to some problems with XML namespaces. I have posted a question on Channel 9 to find a workaround, but have yet to receive a reply. I know I should not copy and paste XAML around, but I just need to know what is going on under the hood.
     
    Anyone who worked through the articles in the SDK I suggested on Day 2 will have noticed that the documentation is not very accurate and up-to-date. Fortunately you can provide feedback to Microsoft's documentation team by clicking on the link at the bottom of each page in the documentation. They are very responsive as I received a personal reply and a thank you in a matter of hours.
     
    The integration of WPF in Visual Studio is coming along quite nicely, but it is not there yet. VS seems to crash more than often, especially when terminating a debug session. The Intellisense list for the objects and elements are also massive. It would be nice if the most common properties and properties that are part of the object itself, not one of the base objects, would be listed in a separate section at the top of the Intellisense window.
     
    Switching to the visual designer for a XAML file in VS also results in errors too often. For example, when the specified source of an image element does not exist then it is not possible to switch to the designer. It would be nice if the offending object would be disabled or skipped. 
     
    XAMLPad is quite useful as well for previewing XAML. Unfortunately it is not very happy when event handlers such as 'Click' have been specified, it just refuses to display the file. I would prefer it if these handlers could optionally be skipped as it takes a lot of time to manually remove all these attributes from the XAML.
     
    The VisualBrush element rocks! More about that in the future.
     
    Finally, as these are still early days, you cannot rely on Googling for help. Too few people use WPF or have posted about it. This, naturally, is just a matter of time.
     
    June 16

    Windows Presentation Foundation - Day 2 - Using the SDK

     
    Having installed all the prerequisites and tools, see Day 1, we have to start somewhere. It is always good to get your hands dirty and work your way through a couple of examples in the SDK.
     
    Follow the steps listed below:
    • Launch the SDK from  the Start Menu / All Programs / Microsoft Windows SDK / Windows SDK Documentation
       
    • Navigate to WinFX Development / Windows Presentation Foundation / Getting Started / Get started using Windows Presentation Foundation
       
    • Work your way through the following simple exercises:
       
      • Hello World
      • Use "XAML" to Create a Simple Layout
      • Use "XAML" to Create a Complex Layout
      • Create a Dynamic "XAML" Page (The documentation for this exercise seems broken in Beta 2, you may need to be a bit creative. I have reported this to Microsoft's SDK documentation team and receceived a reply within hours)
      • Create a Multipage Application (In Beta 2 the documentation is not 100% correct, but I managed to figure it out)
         
    • In the navigation tree navigate to the 'How-to Topics / Create a Windows Presentation Foundation' and execute the exercise.

    That is it for today, it shouldn't take you too long.

     

    June 15

    Windows Presentation Foundation - Day 1 - Getting started

    Over the next few weeks, hopefully not months, I will dive, head first, into the new Microsoft .net Framework 3.0. I will focus mainly on Windows Presentation Foundation (WPF), but I may sneak in some Windows Communication Foundation (WCF) and Windows Workflow Foundation (WF, not WWF as that one was already taken ;-).
     
    I will get some help from one of the few real world WPF experts, Andrew Whiddett, who created the excellent WPF based Nascar kiosk. I will blog about my experiences so if you are interested subscribe to my RSS feed.
     
    So, before we can do anything we need to setup our development environment with all the required development tools, SDKs and runtime components.
     
    We are currently at Beta 2, but as versions and links will be changing I am only going to provide one link, which is to the new .net Framework 3 site. From here you can download the .net framework 3.0 and all other components.
     
    Click on the download link and download:
    • WinFX runtime components.
    • Windows SDK for WinFX Runtime Components
    • Microsoft Visual Studio Extensions - Development Tools for WinFX
    After everything has been installed we need to verify that it works. The easiest thing is to open and compile one of the examples that come with the SDK. All WPF Samples are available in the following ZIP file:
    C:\Program Files\Microsoft SDKs\Windows\v1.0\samples\WPFSamples.zip
    Unzip the archive and open one of the examples such as:
    C:\Program Files\Microsoft SDKs\Windows\v1.0\samples\WPFSamples\Demos\15Puzzle\Csharp\15Puzzle.csproj
    And execute it.
     
    Andrew also advices to download the following as it will probably come in handy:

    Update: 1  The Learn WPF blog also has a getting started post that includes instructions on how to remove previous WPF installations first.

    Update 2: The link to the .Net Framework 3 site always links to the latest version of WPF, unfortunately the latest version is not compatible with Interactive Desginer. Until the final version of WPF is release I recommend downloading all Beta 2 parts.