Writing a Xaml attached property in C++/CX to resize Images, with a Performance twist

By jay at February 04, 2013 21:41 Tags: , , , , , ,

TL;DR: Writing Xaml/C++ attached properties sometimes gives a 30% improvement over the C# version, which can be caused by the use of events. This article shows code sample for both versions.

 

 

Since it is possible to write a XAML application entirely in C++/CX, I decided to give a try to the performance of some simple code.

There is, after all, some marshaling involved when communicating from C# to native code, particularly with events.

 

The ImageDecodeSizeBehavior

WinRT’s BitmapImage class supports, as does WPF and Silverlight, the DecodePixelWidth and DecodePixelHeight properties.

These are very useful properties that forces the memory surface to store the image to fit a certain size, and avoid the waste of memory induced by large downscaled images. This is a very common performance issue for applications that display variable sized images, where the memory can grow very quickly.

More...

Using Precompiled Headers

By Jerome at March 01, 2004 11:50 Tags: ,
(How to speed up the C/C++ compilation step with Visual Studio .NET 2003)

Visual C++ Pre compilation feature

Microsoft C/C++ compiler features for a long time now something called Header Precompilation, also known as PCH. You may have already encountered it or used it without knowing it.

The concept is quite simple : Why having to parse header files for each C/C++ file to compile that includes them ? For a given compilation, the header files used will not likely change and even for any subsequent compilations. Standard include files like stdio.h, stdlib.h and many system header files do not need to be parsed at each inclusion.

The C/C++ compiler uses a special set of files (default is stdafx.cpp and stdafx.h) where it can find all the files to precompile, and then reuse these pre-compiled headers in an efficient way in any future compilation. This avoids to recompile all these header files, especially the ones from the STL that can be really huge.


1. Using precompiled headers, the default way

At first, the C/C++ compiler searches for a file named stdafx.cpp and tries to compile it. This file only includes the stdafx.h file. This compilation generates a file called $(ProjectName).pch that will be used by other files being compiled to find pre-compiled symbols quickly.

Any other C/C++ file must then have a line like this one :

#include "stdafx.h"

Be aware that this line must be the very first line of your C/C++ file. Anything that you will place before will be ignored, not even parsed.

2. Using precompiled headers, from scratch

PCH feature can also be activated from a empty project, by adding files one by one. Here is the way to do this.

First, create an empty project and add 3 new files : main.cpp, stdafx.h and stdafx.cpp.

  • File stdafx.h :

    #ifndef __STDAFX_H#define __STDAFX_H#include #include #include #include #endif // __STDAFX_H
    
  • File stdafx.cpp, quite simple :

    #include "stdafx.h"
    
  • File main.cpp, also quite simple :

    #include "stdafx.h"int main(){ std::string myString("Hello, World !"); std::cout << myString.c_str() << std::endl; return 0;}
    
  • Once these files are added in the solution explorer into your C++ project, follow these steps :

  • Select the stdafx.cpp file, right click and select Properties :

    The two fields "Create/Use PCH Through File" and "Precompiled Header File" will be filled automatically.

  • Then select the project item in the solution explorer right click and select Properties :

    The two fields "Create/Use PCH Through File" and "Precompiled Header File" will be filled automatically.

    Note that changing the C/C++ properties for the project propagates them to C/C++ files that have not been customized. Here it is main.cpp, but not stdafx.cpp because we've customized settings in the previous step.

  • After setting all this, the first file to be compiled is stdafx.cpp and then the other files in the project.

    You will see that big projects compile much faster when PCH features is enabled. Also note that you can use multiple precompiled header files in one project, although it is not recommended. If you feel like you need to make multiple PCH files, it is time for you to make a static or a dynamic library.

    SEH et Exceptions en C++

    By Jerome at February 03, 2004 11:49 Tags: ,

    Qui ne s'est pas déja retrouvé devant une horrible boite de dialogue de crash de programme ressemblant à celle ci :

    "The memory cannot be 'written' at 0x404459FF".

    Cette boite de dialogue, bien connue des utilisateurs et développeurs sur Windows, est le résultat d'une exception matérielle, souvent la conséquence d'un problème logiciel comme un deréférencement de pointeur nul. Il existe bien entendu beaucoup raisons pour lesquelles cette boite peut apparaitre comme des Access Violation, Divide By Zero, Invalid Operation, Float Overflow et Underflow, Privileged Instruction,... autant de problèmes potentiels qui peuvent arrêter l'exécution d'un programme. 

    Le C++ met à disposition un mécanisme de gestion des exceptions par l'intermédiaire des mots clés try et catch tout en utilisant le handler par défaut. Ce handler (catch(...)) du mécanisme standard n'est cependant pas le plus intéressant car il ne permet pas d'obtenir le contexte d'exécution du processeur lors de la génération de l'exception, ni d'en savoir la cause.

    Windows met à disposition du développeur une API spécifique permettant d'utiliser le Structured Exception Handling. Cela permet, entre autres, d'afficher une boite de dialogue à l'utilisateur avec un minimum d'informations de debug. Il est également possible d'avoir un StackTrace pour un exécutable en utilisant les informations de debug séparées. Contrairement à une idée recue, il est possible de génerer avec visual studio des informations de debug pour un exécutable optimisé avec /Ox par exemple.

    Le compilateur C++ met à disposition un certain nombre de nouveaux mots clés permettant de protéger une section de code ou bien un programme entier et d'en intercepter les exceptions d'une manière plus efficace. On peut notamment utiliser __try, __except et __finally qui spécifiques au compilateur Microsoft. Cette méthode n'est cependant pas la plus simple à utiliser.

    L'utilisation du SEH ici est couplée à l'utilisation de la librairie imagehlp.dll. Cette librairie permet d'explorer les fichiers de symboles (pdb) pour déterminer par exemple les fonctions trouvées en parcourant la StackFrame.

    Cet article du MSJournal de 1997 ainsi que celui ci, (Oui, oui, 1997...) décrit assez bien le fonctionnement et l'utilisation du SEH au travers de l'utilisation d'une instance de classe en singleton, mais ce mode ne permet pas de rendre simplement la main au dernier handler d'exception présent.

    Dans ce code, un mélange de l'utilisation du SEH et des exceptions du C++ permet de protéger des morceaux de code dans des exceptions C++ standard. L'utilisation de la fonction _set_se_translator permet d'enregistrer une fonction appelée lorsqu'une exception survient et de transformer ces exception Win32 en exceptions C++. L'exemple ici n'est pas parfait puisque l'original est utilisé dans le cadre de la protection d'un programme complet (tout le main en quelque sorte). Il se pourrait qu'une exception SEH lancée en dehors d'un bloc protégé génère tout de même la boite de dialogue de plantage générique.

    Quoi qu'il en soit, l'utilisation de ce code est assez simple, il faut juste noter qu'il est nécessaire d'activer la génération des StackFrames (désactiver Omit Stack Frames) ainsi que des informations de debug sous forme de fichier extérieur (Debug Information Format : Program Database). Il faut noter également qu'il est indispensable de distribuer le fichier imagehlp.dll et les fichiers pdb (Program Database) avec l'executable pour avoir l'affichage de la StackTrace lors d'une exception.

    Bien entendu pour la distribution publique d'un programme, on ne publiera pas les fichiers pdb, qui contiennent énormément d'informations.

    Il faut noter également qu'il est possible d'utiliser le SEH sous sa forme "native", en C. Vous aurez simplement à supprimer les fonctionnalités spécifique au C++ du code précédent. (Je donne l'info puisque certains utilisent encore ce langage... :p)

    Bon debug !

    About me

    My name is Jerome Laban, I am a Software Architect, C# MVP and .NET enthustiast from Montréal, QC. You will find my blog on this site, where I'm adding my thoughts on current events, or the things I'm working on, such as the Remote Control for Windows Phone.