OVH Cloud OVH Cloud

allocation dynamique sur la pile ?

34 réponses
Avatar
philou2109
Bonjour,
Est-il possible d'allouer sur la pile des tableaux dont la taille est
connue à l'exécution ?
raison : gain de performances par rapport au tas.
Merci

10 réponses

1 2 3 4
Avatar
Olivier Huet
Bonjour,


Est-il possible d'allouer sur la pile des tableaux dont la taille est
connue à l'exécution ?
raison : gain de performances par rapport au tas.



alloca est une fonction standard C (pas particulièrement C++) qui fait ça.

sous Windows, elle s'appelle _alloca dans les documentations : mais je
crois qu'un define de alloca vers _alloca existe : à vérifier.

MAIS ATTENTION : tout les compilateurs et OS ont leur limite dessus. Par
exemple, sous Windows + VC++ :

- tu as une adresse "butoire" pour la pile : tu as une pile par thread
et elle fait un peu moins de 1 MO par défaut.

- tu ne peut pas l'appeller depuis un bloc "catch" d'un try/catch.

- la "mémoire" ainsi allouée est libéré à la sortie de la fonction et
non simplement du scope --> ATTENTION donc de ne pas mettre ce genre de
chose dans une boucle longue.

Toujours sur la version Windows + VC++ voici plus de précisions :
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vclib/html/_CRT__alloca.asp


D'ailleurs, on sort peut-être de la limite de ce newsgroup C++, mais
est-ce que quelqu-un sait si les autres environnements ont tous ce genre
de limite (la première et la troisième je crois que oui, mais pour le
coup du catch...) ???


Olivier Huet

Avatar
Pierre Maurette
Olivier Huet a écrit:

Bonjour,


Est-il possible d'allouer sur la pile des tableaux dont la taille est
connue à l'exécution ?
raison : gain de performances par rapport au tas.



alloca est une fonction standard C (pas particulièrement C++) qui fait ça.
Pas ANSI/ISO C. Mais certainement assez répandue (GNU C, Win32), avec

des comportements peut-être diffférents selon implémentation (voir
plus bas).

sous Windows, elle s'appelle _alloca dans les documentations : mais je
crois qu'un define de alloca vers _alloca existe : à vérifier.

MAIS ATTENTION : tout les compilateurs et OS ont leur limite dessus. Par
exemple, sous Windows + VC++ :

- tu as une adresse "butoire" pour la pile : tu as une pile par thread
et elle fait un peu moins de 1 MO par défaut.

- tu ne peut pas l'appeller depuis un bloc "catch" d'un try/catch.

- la "mémoire" ainsi allouée est libéré à la sortie de la fonction et
non simplement du scope --> ATTENTION donc de ne pas mettre ce genre de
chose dans une boucle longue.

Toujours sur la version Windows + VC++ voici plus de précisions :
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vclib/html/_CRT__alloca.asp


D'ailleurs, on sort peut-être de la limite de ce newsgroup C++, mais
est-ce que quelqu-un sait si les autres environnements ont tous ce genre
de limite (la première et la troisième je crois que oui, mais pour le
coup du catch...) ???
Doc de alloca() de Borland (C++ Builder 6):


Header File

malloc.h

Category

Memory Routines

Prototype

void *alloca(size_t size);

Description

Allocates temporary stack space.

alloca allocates size bytes on the stack; the allocated space is
automatically freed up when the calling function exits.

The use of alloca is not encouraged. In the try-block of a C++ program
the alloca function should never be used. If an exception is thrown,
any values placed on the stack by alloca will be corrupted.

Return Value

If enough stack space is available, alloca returns a pointer to the
allocated stack area. Otherwise, it returns NULL.

--
Pierre


Avatar
Pierre Maurette
"philou2109" a écrit:

Bonjour,
Est-il possible d'allouer sur la pile des tableaux dont la taille est
connue à l'exécution ?
Prenons le raisonnement par un autre bout. Vous avez besoin d'une

variable automatique tab[x]. x n'est connu qu'à l'exécution. Mais si
vous ne jouez pas à la roulette russe, vous pouvez (devez ?)
déterminer un majorant x_max tel que l'allocation est possible si x < x_max. Or, vous avez toutes les chances que la déclaration int tab[2]
prenne exactement le même temps que int tab[1000]. Et comme cette
mémoire est restituée en sortie de fonction... Donc, déclarez
simplement une variable locale int tab[x_max].

Il existe certainement des cas dans lesquels cette analyse ne
s'applique pas. Par exemple si cette allocation est susceptible
d'apparaître plusieurs fois dans une pile d'appels (scabreux ?).
Ou si vous voulez tester la possibilité d'allocation et savez comment
réagir, par exemple par une allocation sur le tas. A ce moment-là,
voir alloca() dans autres messages.

raison : gain de performances par rapport au tas.
Certes. Ce n'est cerrtainement pas négligeable dans certains cas. MAis

est-ce pour autant nécessaire ?
--
Pierre

Avatar
kanze
Pierre Maurette wrote in message
news:...
Olivier Huet a écrit:


Est-il possible d'allouer sur la pile des tableaux dont la taille
est connue à l'exécution ?
raison : gain de performances par rapport au tas.


alloca est une fonction standard C (pas particulièrement C++) qui
fait ça.


Pas ANSI/ISO C. Mais certainement assez répandue (GNU C, Win32), avec
des comportements peut-être diffférents selon implémentation (voir
plus bas).


Pas standard Posix ni Open Systems non-plus. En C standard, je n'en vois
pas l'intérêt ; la façon standard de le faire, c'est simplement de
déclarer un tableau dont la taille n'est pas une expression constante,
par exemple :

void
f( int n )
{
double a[ n ] ;
// ...
}

En C++, la solution standard, c'est d'utiliser std::vector :

void
f( int n )
{
std::vector< double > a( n ) ;
// ...
}

Je ne m'écarterais pas de la solution standard tant que le profileur ne
m'a pas montré que c'est un problème réel et sérieux. Et même alors, ce
n'est pas dit que alloca soit plus rapide, surtout par rapport à la
solution C.

Question qualité d'implémentation, on pourrait aussi s'attendre à ce
qu'un bon compilateur C++ implémentation la solution C, comme extension.
C'est le cas de g++, par exemple.

--
James Kanze GABI Software http://www.gabi-soft.fr
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34



Avatar
Olivier Huet
Bonjour,

En C standard, je n'en vois
pas l'intérêt ; la façon standard de le faire, c'est simplement de
déclarer un tableau dont la taille n'est pas une expression constante,
par exemple :

void
f( int n )
{
double a[ n ] ;
// ...
}



J'étais persuadé que l'on ne pouvait pas faire ça - est-ce que ça existe
depuis le C "ancien" (disons par exemple le C ANSI) ???

Du coup, je trouve ça curieux, que le C++ ne l'ai pas gardé : après
tout, inclus comme ça dans le langage ce serait relativement pratique.


Olivier Huet

Avatar
drkm
Olivier Huet writes:


En C standard, je n'en vois
pas l'intérêt ; la façon standard de le faire, c'est simplement de
déclarer un tableau dont la taille n'est pas une expression constante,
par exemple :

void
f( int n )
{
double a[ n ] ;
// ...
}


J'étais persuadé que l'on ne pouvait pas faire ça - est-ce que ça existe
depuis le C "ancien" (disons par exemple le C ANSI) ???

Du coup, je trouve ça curieux, que le C++ ne l'ai pas gardé : après
tout, inclus comme ça dans le langage ce serait relativement pratique.


C'est du C99. Tu peux chercher après « VLA » sur f.c.l.c, si cela
t'amuse.

--drkm


Avatar
drkm
Olivier Huet writes:


C'est du C99. Tu peux chercher après « VLA » sur f.c.l.c, si cela
t'amuse.


Ok Merci, c'était plutôt par curiosité


Au fait, son adoption dans la norme C++ est-elle à l'ordre du jour ?

--drkm


Avatar
Fabien LE LEZ
On Sat, 04 Dec 2004 01:56:52 +0100, drkm :

Au fait, son adoption dans la norme C++ est-elle à l'ordre du jour ?


A priori, je n'en vois pas bien l'intérêt : d'une part, il n'apporte
pas grand-chose en C++ ; d'autre part, un VLA n'apparaît normalement
pas dans les headers, donc il n'y a pas de problème d'intégration de
modules C dans un project C++.


--
;-)

Avatar
James Kanze
Olivier Huet writes:

|> > En C standard, je n'en vois
|> > pas l'intérêt ; la façon standard de le faire, c'est simplement de
|> > déclarer un tableau dont la taille n'est pas une expression constante,
|> > par exemple :
|> > void
|> > f( int n )
|> > {
|> > double a[ n ] ;
|> > // ...
|> > }

|> J'étais persuadé que l'on ne pouvait pas faire ça - est-ce que ça
|> existe depuis le C "ancien" (disons par exemple le C ANSI) ???

Ça n'existait pas en C K&R, ni en C90. Mais ça fait partie de C99 (ce
qui est ce qu'on entend par C ISO aujourd'hui).

|> Du coup, je trouve ça curieux, que le C++ ne l'ai pas gardé : après
|> tout, inclus comme ça dans le langage ce serait relativement
|> pratique.

Il a été adopté en C en 1999. La norme C++ date de 1998. Voilà pourquoi
il n'y est pas. Mais comme j'ai dit, de bons compilateurs C++ le
supportent déjà, au moins en option.

--
James Kanze
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Pierre Sémard, 78210 St.-Cyr-l'École, France +33 (0)1 30 23 00 34
Avatar
James Kanze
drkm writes:

|> Olivier Huet writes:


|> >> C'est du C99. Tu peux chercher après « VLA » sur f.c.l.c, si
|> >> cela t'amuse.

|> > Ok Merci, c'était plutôt par curiosité

|> Au fait, son adoption dans la norme C++ est-elle à l'ordre du jour ?

Je crois qu'on en discute. D'après le peu que j'ai entendu, les VLA de C
entières posent un certain nombre de problèmes. Une VLA peut, par
exemple, être le dernier élément d'un struct. Ce qui rend l'héritage
assez problèmatique. Il y a aussi des problèmes, j'imagine, lors d'un
new :

struct VLA { size_t length ; MonTypeAvecCtor array[*] ; } ;
VLA *p = new VLA ; // ???

Ce qui veut dire que les discussions risquent d'être longues.

En fait, moi aussi, j'aimerais les voir, au moins en partie. Mais je
n'ai pas actuellement le temps de m'en occuper, et si personne s'en
occupe, et personne n'y met le temps, les problèmes ne se résoudront
pas, et ils risquent de tomber à côté.

--
James Kanze
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Pierre Sémard, 78210 St.-Cyr-l'École, France +33 (0)1 30 23 00 34
1 2 3 4