C++ Virtual Function Optimization

Interesting read on gamedev.net:

http://www.gamedev.net/reference/programming/features/AbsPolyOpt/

Powered by ScribeFire.

A scheme for automatic build numbers in C/C++ projects

Many times it’s desirable on medium and large scale projects to generate some form of build number in a semiautomatic or automatic way to differentiate builds in order to track different release code bases, even to generate different but easily distinguishable private and public builds, on single or multiplatform projects.

Unfortunately, none of the C/C++ compilers I know (VC/GCC) support build versioning, altough this task is better suited to build systems. However, none of the systems I use (UNIX make, QMake, Microsoft NMAKE) can generate build version information automatically.

In the build script for the project I’m developing at a private company, I’ve developed an automatic build numbering system, running under Windows command line. This approach is working for Win32 projects compiled with QMake (QT’s build systems), altough I imagine it can be adapted to different toolchains on either Windows or Unix/Linux platforms.

The script generates build numbers and modifies Win32 resource files (RC) accordingly, so each target executable and DLL built gets the build number on their VERSION_INFO resource.

On the directory where my build script resides, I created the following three important folders:

  • verstamp where the version stamping actually occurs.
  • tools where the needed command line tools reside (actually, only gawk for Windows is there).
  • rc where the RC files for each subproject are located. Those are processed by the RC.EXE tool when NMAKE processes the Makefiles generated by QMake

The flow is as follows.

On each release build, my verstamp utility reads a VERSIONINFO file. This file contains the current build number (major version, minor version, SVN commit rev, and build). For example:

1,0,10234,230

I also generate the latest revision number from Tortoise SVN SUBWCREV utility and store it in %REV% environment var. The SUBWCREV utility substitutes $WCREV$ string to the latest commit rev. So a simple file named __SVN__.REV contains the template:

$WCREV$

To replace the string with the commit number in a new SVN.REV file, copying result to %REV%:

subwcrev %SOURCETREE% __SVN__.REV SVN.REV > NUL
set /p REV= < SVN.REV

Where %SOURCETREE% is the root of my SVN-managed source tree.

Using AWK, build number is increased and SVN rev patched up, with this line:

awk -F, “{ printf(\”%%d,%%d,%%d,%%d\”,$1,$2,%REV%,$4+1); }” VERSIONINFO.OLD > VERSIONINFO

Now VERSIONINFO contains the updated build number and source revision.

Version resource update

To update the version information resource on my executables, first I store the new build number on proper environment variables (on Unix shells this would be far better — NT command line is lackluster):

awk -F, "{ print $1; }" VERSIONINFO > MAJORVER
 awk -F, "{ print $2; }" VERSIONINFO > MINORVER
 awk -F, "{ print $4; }" VERSIONINFO > BUILD
 set /p MAJOR= < MAJORVER
 set /p MINOR= < MINORVER
 set /p BUILD= < BUILD

The task now is to patch a header that is included by my RC files, where product name, product version, file version are defined. I work with the following ‘template’, named version_info.hdr:

#define PRODUCTNAME		"Your product for Windows\0"
#define PRODUCTVER		$$MAJOR$$,$$MINOR$$,$$REV$$,$$BUILD$$
#define FILEVER			PRODUCTVER
#define STRPRODUCTVER		"$$MAJOR$$.$$MINOR$$.$$REV$$.$$BUILD$$"
#define STRFILEVER		STRPRODUCTVER

Each field is updated by AWK using the gsub command with the MAJOR,MINOR,REV and BUILD variables setup above:

awk “{ gsub(/\$\$MAJOR\$\$/, %MAJOR%); gsub(/\$\$MINOR\$\$/, %MINOR%); gsub(/\$\$REV\$\$/, %REV%); gsub(/\$\$BUILD\$\$/, %BUILD%); print }” version_info.hdr > version_info.h

Now version_info.h is ready for inclusion:

#define PRODUCTNAME		"Your product for Windows\0"
#define PRODUCTVER		1, 0, 10260, 231
#define FILEVER			PRODUCTVER
#define STRPRODUCTVER		"1.0.10260.231"
#define STRFILEVER		STRPRODUCTVER

Finally, a typical RC using our generated build numbers in my project is as:

#include "version_info.h"  // Generated above

/////////////////////////////////////////////////////////////////////////////
//
// Version
//
1 VERSIONINFO
 FILEVERSION FILEVER
 PRODUCTVERSION PRODUCTVER
 FILEFLAGSMASK 0x0L
#ifdef _DEBUG
 FILEFLAGS 0x1L
#else
 FILEFLAGS 0x0L
#endif
 FILEOS 0x40004L
 FILETYPE 0x1L
 FILESUBTYPE 0x0L
BEGIN
    BLOCK "StringFileInfo"
    BEGIN
        BLOCK "040904E4"
	    BEGIN
        	VALUE "CompanyName", "my company name\0"
	        VALUE "FileDescription", "file desc\0"
        	VALUE "FileVersion", STRFILEVER
	        VALUE "InternalName", "binname.exe\0"
        	VALUE "LegalCopyright", "(c) copyright\0"
	        VALUE "OriginalFilename", "binname.exe\0"
        	VALUE "ProductName", PRODUCTNAME
	        VALUE "ProductVersion", STRPRODUCTVER
	END
    END

    BLOCK "VarFileInfo"
    BEGIN
	VALUE "Translation", 0x0409, 1252
    END
END

And that’s all!

Powered by ScribeFire.

My CPU Timeline (1986-2009)

Here’s, retrieved from my old web, my own timeline of CPUs 1986-2009. I think it’s pretty correct.

Microprocessors

  • 1986: CSG6510, ~1MHz (PAL C64)
  • 1990: NEC V20, 8MHz
  • 1992: AMD Am386, 40MHz
  • 1995: 40MHz(?) Cyrix 4×86
  • 1996: AMD 486DX4, 100MHz
  • 1997: Intel Pentium (P54C, no-MMX) 166MHz
  • 1998: Intel Celeron 300MHz (cacheless)
  • 1999: Intel Pentium II 400MHz
  • 2000: Intel Pentium III 500 MHz
  • 2000: Intel Pentium III 650 MHz
  • 2001: Intel Pentium III-E 750MHz
  • 2001: AMD Athlon 1GHz (‘Thunderbird’)
  • 2003: AMD Athlon XP 2000+ (‘Palomino’) 1.66GHz
  • 2004: AMD Athlon XP 2600+ (‘Barton’ ?) 1.97GHz
  • 2008: AMD Athlon X2 5200+ (2.6GHz)

80s nostalgia book

CBM History Book

CBM History Book

I’ve nearly finished reading the amazing book “On The Edge: The Spectacular Rise and Fall of Commodore”. This 500-page gem travels through the intense and somewhat bizarre story of Commodore, the once mighty computer company, from the 6502 microprocessor design by Chuck Peddle at MOS to the final liquidation of CBM in 1994. This is not a boring bussiness-oriented book but a constant talk between the reader and the former top Commodore employees and managers. Of course, the interesting business aspects of how Commodore was managed everyday is presented in a very enjoyable way.

As a former Commodore64 owner, this was a joy to read. I’ll always thank the engineers at Commodore forever for creating such a masterpiece, from where I discovered my interests on computing and programming.

DLL Best Practices

Creating Win32 DLLs may seem rather easy, however there are many subtle things to take in account (loader deadlocks are unknown by many Win32 developers)

Here’s a very good read for the topic:

http://www.microsoft.com/whdc/driver/kernel/DLL_bestprac.mspx

Live Messenger reverse engineering article

I’ve published an article at Codeproject about Windows Live Messenger in the context of a research project we’ve done at Nektra, check out it at http://www.codeproject.com/KB/macros/wlmplugin.aspx

Nektra website is at http://www.nektra.com, blog at blog.nektra.com. If you are into hooking, reverse engineering et al, check out Trappola, Deviare and/or Spystudio.

Hackint0sh Xbench 1.3 results

The XBench 1.3 results for my AMD X2 5200 system are:

Test            Score
===========================================================
CPU             95.98
Thread          174.32
Memory          138.36
Quartz          176.39
OpenGL          130.86
UI              304.50
Disk            58.41
OVERALL         122.50

Of course that even middle range MacPros perform better… but hey … this is a pretty standard computer by this time and works with Leopard very well. I think disk performance may be quite not as high as I wanted… probably it’s related to the SerialATA controller being setup as IDE-emulation, not AHCI which effectively disables NCQ for example. But I need to install AHCI on Windows XP — if I setup that I will try again to see if I can improveĀ  the disk score.