risorse | heap & vc10
Per quanto primitiva, ho utilizzato con profitto la libreria heap in un paio di progetti, prima in ambiente MinGW, successivamente con il Visual Studio 2008 Express Edition. La migrazione di uno di questi progetti verso il compilatore VC10 – disponibile nel Windows Platform SDK 7.1 – ha evidenziato tempi d'esecuzione particolarmente elevati in modalità DEBUG. La responsabilità della libreria è risultata da subito evidente: disabilitando il tracciamento delle allocazioni, i tempi di esecuzione si sono attestati su valori di gran lunga più ragionevoli.
Le ipotesi più accretidate sono due: un'inefficienza intrinseca della libreria, che conserva l'elenco delle allocazioni in una lista linkata, non particolarmente efficiente nello scenario d'uso – l'applicativo tende a deallocare l'ultimo oggetto allocato –, associata ad un possibile aumento del numero di allocazioni (il nuovo compilatore porta in dote una libreria standard in gran parte riscritta[1]).
Si sono allora messe a confronto due differenti implementazioni della libreria heap, quella originale basata su lista linkata ed una – approntata per l'occasione – che sfrutta una mappa della libreria standard. La tabella sottostante raccoglie i risultati degli esperimenti condotti su un test-case particolarmente critico:
ADT | Piattaforma | Allocazioni | Durata (ms) |
---|---|---|---|
lista linkata | VC9 | 174061 | 14071 |
lista linkata | VC10 | 2375492 | 105721 |
std::map | VC9 | 348123 | 11232 |
std::map | VC10 | 4750984 | 32292 |
È confermata l'ipotesi che a fronte del codice esistente, la nuova liberia standard effettua un numero di allocazioni molto maggiore rispetto alla versione precedente; i numeri in gioco sono talmente elevati da mettere in crisi l'implementazione della lista linkata, considerate le risorse disponibili della macchina di test (Windows Vista Businness SP2 con 2GB di RAM).
L'aumento del numero di allocazioni è in parte da imputare al controllo sulla validità degli iteratori[3] che la libreria standard fornita da Microsoft mette in atto di default quando è compilata in modalità DEBUG; la tabella sottostante evidenzia l'effetto della disabilitazione del controllo sul numero di allocazioni e sui tempi di esecuzione del test-case citato in precedenza per la combinazione lista linkata/VC10:
Impostazione | Allocazioni | Durata (ms) | Note |
---|---|---|---|
_ITERATOR_DEBUG_LEVEL=2 | 2375492 | 106891 | default di sistema |
_ITERATOR_DEBUG_LEVEL=1 | 2375492 | 105487 | |
_ITERATOR_DEBUG_LEVEL=0 | 541053 | 20373 |
Durante le analisi è emersa una possibile criticità circa la ridefinizione di una parola chiave del linguaggio; al punto 17.4.3.1.1.2, lo standard C++11 recita infatti:
A translation unit that includes a header shall not contain any macros that define names declared or defined in that header. Nor shall such a translation unit define macros for names lexically identical to keywords.
Risulta quindi che la definizione:
#define new new(__FILE__, __LINE__)
usata dalla libreria per catturare la posizione ove ha avuto luogo l'allocazione è in contrasto con quanto prescritto dallo standard. Aspetti correlati a questo problema si trovano in abbondanza[2][5].
La libreria heap presenta delle problematiche che non la rendono utilizzabile in progetti che richiedono l'uso di compilatori «moderni». Conviene quindi dotarsi (o sviluppare) strumenti alternativi. Limitatamente all'ambiente Microsoft, uno spunto interessante per lo sviluppo di una nuova libreria si trova in MSDN[4].
Pagina modificata il 21/05/2012