September 24, 2008

Somebody made a video of grid

Filed under: Projects — by suasol @ 9:56 am
Tags: , ,

The gridding doesn’t actually start until about half way through.


September 3, 2008

Grid install instructions

Filed under: Projects — by suasol @ 9:20 pm
Tags: , ,

Install build dependencies (platform specific) perhaps something like:

sudo apt-get install libtool compiz-dev compizconfig-settings-manager compiz-bcop

git clone git://
# if you get build errors you may need to install more dependencies and make again
make install # you can install as a normal user into your ~/.compiz folder

Enable grid in the compiz settings manager (ccsm)

July 23, 2008

Winsplit revolution for Linux

Filed under: Uncategorized — by suasol @ 5:21 pm
Tags: , ,

Grid, the tiling plugin for compiz fusion has been updated. It now interacts much better with the builtin maximize function.

July 4, 2008

A List Of People Who Need To Stop Writing Software

Filed under: Uncategorized — by suasol @ 10:15 am

Printer Manufacturers

A Printer driver is a folder with one “.ini” file, and a couple of “.dll”s and that’s it. It is not a 50 MB download. It is not an IE Toolbar, and Side Pane. It is not half-baked photo software. It is not a splash screen when your computer starts. It is not a tray icon.

Brilliant. More at

July 2, 2008

GNU C++ POD madness

Filed under: Lowlevel — by suasol @ 10:47 am

(You may want to have a look at the previous article for a refresher on data and const data sections)

Constant non-POD objects cost more than you think. There are penalties in

* code size (executable size)
* working set size (“dirty” memory)
* program startup speed

What is a POD object? POD means “plain old data” and basically means a basic type or a C struct. Once you have constructors or assignment operator or most of the stuff that 10,000 page “guru” books tell you to have, you become non-POD.

First some source and the asm output

struct PodPoint { int x; int y; };
extern const PodPoint origin = { 5,7 };
PUBLIC    ?origin@@3UPodPoint@@B                ; origin
?origin@@3UPodPoint@@B DD 05H                ; origin
    DD    07H
// GCC
        .globl origin
        .section        .rodata
        .align 4
        .type   origin, @object
        .size   origin, 8
        .long   5
        .long   7

Perfect! If we were to disassemble this, we’d get 8 bytes exactly as we expect, 4 each for x and y.

Now, being a good C++ citizen surely we will add a constructor?

struct NonPodPoint
    int x;
    int y;
    NonPodPoint(int a,int b) : x(a), y(b) {}
extern const NonPodPoint origin(5,7);

PUBLIC	??0NonPodPoint@@QAE@HH@Z			; NonPodPoint::NonPodPoint
; Function compile flags: /Ogtpy
;	COMDAT ??0NonPodPoint@@QAE@HH@Z
_a$ = 8							; size = 4
_b$ = 12						; size = 4
??0NonPodPoint@@QAE@HH@Z PROC				; NonPodPoint::NonPodPoint, COMDAT
; _this$ = ecx
; File c:\dev\a.cpp
; Line 5
	mov	edx, DWORD PTR _b$[esp-4]
	mov	eax, ecx
	mov	ecx, DWORD PTR _a$[esp-4]
	mov	DWORD PTR [eax], ecx
	mov	DWORD PTR [eax+4], edx
	ret	8
??0NonPodPoint@@QAE@HH@Z ENDP				; NonPodPoint::NonPodPoint
PUBLIC	?origin@@3UNonPodPoint@@B			; origin
?origin@@3UNonPodPoint@@B DD 05H			; origin
	DD	07H

        .section        .ctors,"aw",@progbits
        .align 4
        .long   _GLOBAL__I_origin
        .align 2
        .type   _Z41__static_initialization_and_destruction_0ii, @function
        pushl   %ebp
        decl    %eax
        movl    %esp, %ebp
        jne     .L5
        cmpl    $65535, %edx
        jne     .L5
        movl    $5, origin
        movl    $7, origin+4
        popl    %ebp
        .size   _Z41__static_initialization_and_destruction_0ii, .-_Z41__static_initialization_and_destruction_0ii
        .align 2
        .type   _GLOBAL__I_origin, @function
        pushl   %ebp
        movl    $65535, %edx
        movl    %esp, %ebp
        movl    $1, %eax
        popl    %ebp
        jmp     _Z41__static_initialization_and_destruction_0ii
        .size   _GLOBAL__I_origin, .-_GLOBAL__I_origin
.globl origin
        .align 4
        .type   origin, @object
        .size   origin, 8
        .zero   8

MSVC does really well here, it’s almost the same as the optimal case with one important difference – somehow the definition of “origin” was moved to the _data section and thus is unshared and writable.

GCC (4.1.2 here) sadly completely gives up. It reserves some zeroed space and then arranges for the constructor to be called in the static initialization phase (that magic twilight between program startup and when main() is called)

Much of the cost is in the code for the constructors. Roughly speaking, we need a mov per member initialized (6 bytes). As you can imagine this really adds up for arrays. Again we lose the benefits of the .rodata section. Finally, if we have many objects requiring static initialization, startup can be slower.

The moral of the story: If you have constants, store them in POD types, not objects. If you’re careful, (and use compile-time asserts) you could cast your POD data into non-POD data.

Data & Read-only sections

Filed under: Lowlevel — by suasol @ 9:30 am

First lets look at the code generated with some simple examples.

extern int global_writable_var = 9; // a.cpp
extern const int global_const_var = 9; // a.cpp

Generate the assembly source with

cl /c /Fa a.cpp # MSVC: /c means compile only, don't link. /Fa means output assembly
gcc -c -S a.cpp # GCC: -c means compile only, don't link. -S means output assembly

And we get:

// MSVC : a.asm
PUBLIC	?global_writable_var@@3HA	; global_writable_var
PUBLIC	?global_const_var@@3HB		; global_const_var
?global_const_var@@3HB DD 09H		; global_const_var
?global_writable_var@@3HA DD 09H		; global_writable_var

// GCC : a.s
.globl global_writable_var                  ; attributes of the variable
        .align 4
        .type   global_writable_var, @object
        .size   global_writable_var, 4
        .long   9                           ; variable definition
.globl global_const_var
        .section        .rodata
        .align 4
        .type   global_const_var, @object
        .size   global_const_var, 4
        .long   9

The key thing to notice here is that the compiler puts constant data into a separate areas (try adding more variables). Typically these areas (known as the _data and _const segments on windows, known as .data and .rodata sections on unix) will have different memory protection bits enabled – thus writes to global_const_var would cause a hardware exception. Also if you’re compiling a shared library or have several executables running, then each time the library is loaded the data segment is duplicated, but the constant section may be shared between all instances.

Thus if you have a library (dll) which is linked many times (as is very common in linux for instance – try “ldd /path/to/executable” on some programs), the overhead can really add up.

See also:

June 28, 2008

New tiling plugin for compiz-fusion – grid

Filed under: Projects — by suasol @ 10:24 am
Tags: , ,

When, like all rockstar developers, you have an enormous flatscreen monitor bigger than your TV at home gracing your desk, it’s fair to say you no longer want to maximize your windows all the time.

The larger the monitor you have, the more time you spend tediously moving and resizing. Until winsplit revolution that is ( It’s really intuitive, small and fast. Also it has the hallmark of really good utilities. That is, when you use another machine without it, you want to stab your eyes out with paperclips at the sheer frustration of it all.

Winsplit screenshot

I liked it so much, I’ve written a version for Linux. A plugin for compiz-fusion specifically. Get it from:

git clone git://

You’ll need a boatload of dependencies to make it compile. If you’re on a debian-ish system you’ll want to apt-get build-dep compiz-fusion-plugins

« Previous Page

Blog at