OVH Cloud OVH Cloud

Specialisation de templates et types prédéfinis

29 réponses
Avatar
diego-olivier.fernandez-pons
Bonjour,

Comme mon code C/C++ doit tourner sur une multitude de plateformes
=E9tranges, je red=E9finis les types pr=E9d=E9finis (bool, int, float) avec
=E9ventuellement suivant des plateformes des cast affreux (typedef float
myInt) pour contourner les multiples bugs des plateformes/compilateurs
(machines 64 bits avec entiers 32 bits, machines avec entiers 16 bits,
etc.)

Mais du coup le syst=E8me de types est totalement perdu dans la
sp=E9cialisation des templates :

template <typename T> class Array {...} // tableau de pointeurs sur des
objets

// optimisations classiques avec les types natifs "unboxed"
template <> class Array <myBool> {...}
template <> class Array <myInt> {...}
template <> class Array <myFloat> {...}

Oui mais avec myInt =3D myFloat =3D float, le compilateur se perd.
Forc=E9ment.

Quelqu'un sait comment expliquer au compilateur que je veux qu'en
machine myInt =3D myFloat mais syntaxiquement myInt !=3D myFloat ?

Diego Olivier

10 réponses

1 2 3
Avatar
kanze
wrote:

[DOFP]
Sur une machine raisonnable on a :
Table of the numbers of bytes used for different data type
char : 1
int : 4
long int : 4
float : 4
double : 8
long double : 12


[Kanze]
Tu as une drôle d'idée de « raisonable ». Je n'ai jamais
encore vu une machine comme ça ;


Ma machine de développement prétend s'appeler Intel Pentium
III 500. Et elle dit même qu'elle a plein de soeurs et de
cousines qui lui ressemblent.


Au niveau hardware, l'architecture Intel 32 bits a trois tailles
de virgule flottant : 4, 8 et 10 bits. Comment on les mappe aux
flottants du C++ dépend du compilateur -- dans la pratique,
float, c'est toujours le premier, et double le deuxième. Quant
au long double, les compilateurs Microsoft d'aujourd'hui le
mappe aussi au deuxième (c-à-d qu'un long double a 8 octets,
exactement comme un double). Si on le mappe au troisième, on
serait normallement amené à augmenter la taille pour des raisons
d'alignement, pour en faire en fait 16 octets -- c'est ce que
faisait certaines versions (très anciennes) des compilateurs C
de Microsoft.

Évidemment, on pourrait en augmenter la taille pour en faire 12
aussi. Ou 11. Ou 13. C'est cependant un choix un peu bizarre.
(Pour éviter des rallentissements, il faut que la taille d'un
objet soit un diviseur de la taille d'une ligne de cache. La
taille des lignes de cache varie, mais elles sont toujours une
puissance de deux. Or, 12 n'est diviseur d'aucune puissance de
deux. C'est donc un mauvais choix -- autant que faire, il vaut
mieux rester à 10.)

--
James Kanze GABI Software
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
diego-olivier.fernandez-pons
Bonjour,

Au niveau hardware, l'architecture Intel 32 bits [...]
C'est donc un mauvais choix -- autant que faire, il vaut
mieux rester à 10.


Si tu veux te plaindre du fait que sizeof ne renvoie pas la valeur qui
te convient, eh bien il faut écrire aux développeurs de GCC. Moi, je
n'y peux strictement rien.

Diego Olivier

Avatar
Gabriel Dos Reis
"kanze" writes:

| wrote:
|
| > [DOFP]
| > > Sur une machine raisonnable on a :
| > > Table of the numbers of bytes used for different data type
| > > char : 1
| > > int : 4
| > > long int : 4
| > > float : 4
| > > double : 8
| > > long double : 12
|
| > [Kanze]
| > > Tu as une drôle d'idée de « raisonable ». Je n'ai jamais
| > > encore vu une machine comme ça ;
|
| > Ma machine de développement prétend s'appeler Intel Pentium
| > III 500. Et elle dit même qu'elle a plein de soeurs et de
| > cousines qui lui ressemblent.
|
| Au niveau hardware, l'architecture Intel 32 bits a trois tailles
| de virgule flottant : 4, 8 et 10 bits.

Cela m'étonnerait.

[...]

| Évidemment, on pourrait en augmenter la taille pour en faire 12
| aussi. Ou 11. Ou 13. C'est cependant un choix un peu bizarre.

Lequel est bizarre, 11, 12, ou 13?

| (Pour éviter des rallentissements, il faut que la taille d'un
| objet soit un diviseur de la taille d'une ligne de cache. La
| taille des lignes de cache varie, mais elles sont toujours une
| puissance de deux. Or, 12 n'est diviseur d'aucune puissance de
| deux. C'est donc un mauvais choix -- autant que faire, il vaut
| mieux rester à 10.)

Peux-tu expliquer cela en détail ? Parce que j'ai du mal à suivre ton
raisonnement, unr partie bonne des premisses étant non-vérifié.

-- Gaby
Avatar
Gabriel Dos Reis
writes:

| Bonjour,
|
| > Au niveau hardware, l'architecture Intel 32 bits [...]
| > C'est donc un mauvais choix -- autant que faire, il vaut
| > mieux rester à 10.
|
| Si tu veux te plaindre du fait que sizeof ne renvoie pas la valeur qui
| te convient, eh bien il faut écrire aux développeurs de GCC. Moi, je
| n'y peux strictement rien.

Je crois implement que James confond « bits » avec « bytes » et fait
des raisonnements qui ne tiennent pas.

-- Gaby
Avatar
James Kanze
Gabriel Dos Reis wrote:
writes:


| > Au niveau hardware, l'architecture Intel 32 bits [...]
| > C'est donc un mauvais choix -- autant que faire, il vaut
| > mieux rester à 10.


| Si tu veux te plaindre du fait que sizeof ne renvoie pas la
| valeur qui te convient, eh bien il faut écrire aux
| développeurs de GCC. Moi, je n'y peux strictement rien.


Je crois implement que James confond « bits » avec « bytes » et fait
des raisonnements qui ne tiennent pas.


Je n'arrive pas à comprendre toute ta phrase, mais je ne
confonds certainement pas « bits » et « bytes ».

Je constate que sous Linux, g++ a effectivement choisi une
taille de 12 pour long double, c-à-d qu'il enforce un alignement
de 4. Je ne connais pas les raisons de ce choix, mais je sais
qu'avec les hardward actuel, il n'y a aucune justification
technique -- il n'y a aucun amélioration de la vitesse par
rapport à un alignement de 2 (ce qui donne un sizeof de 10), par
exemple.

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

Avatar
James Kanze
Gabriel Dos Reis wrote:
"kanze" writes:


| wrote:


| > [DOFP]
| > > Sur une machine raisonnable on a :
| > > Table of the numbers of bytes used for different data type
| > > char : 1
| > > int : 4
| > > long int : 4
| > > float : 4
| > > double : 8
| > > long double : 12


| > [Kanze]
| > > Tu as une drôle d'idée de « raisonable ». Je n'ai jamais
| > > encore vu une machine comme ça ;


| > Ma machine de développement prétend s'appeler Intel Pentium
| > III 500. Et elle dit même qu'elle a plein de soeurs et de
| > cousines qui lui ressemblent.


| Au niveau hardware, l'architecture Intel 32 bits a trois
| tailles de virgule flottant : 4, 8 et 10 bits.


Cela m'étonnerait.


Faute de frappe évidente, non ? Changer « bits » en « bytes ».

[...]


| Évidemment, on pourrait en augmenter la taille pour en faire
| 12 aussi. Ou 11. Ou 13. C'est cependant un choix un peu
| bizarre.


Lequel est bizarre, 11, 12, ou 13?


Tous. Logiquement, on choisira soit 16, pour la vitesse maximum,
soit 10, pour la taille minimum. On pourrait, évidemment
choisir n'importe quoi : Microsoft a choisi 8, en mappant long
double au format 8 octets d'Intel, plutôt qu'au format 10
octets.

| (Pour éviter des rallentissements, il faut que la taille
| d'un objet soit un diviseur de la taille d'une ligne de
| cache. La taille des lignes de cache varie, mais elles sont
| toujours une puissance de deux. Or, 12 n'est diviseur
| d'aucune puissance de deux. C'est donc un mauvais choix --
| autant que faire, il vaut mieux rester à 10.)


Peux-tu expliquer cela en détail ? Parce que j'ai du mal à
suivre ton raisonnement, unr partie bonne des premisses étant
non-vérifié.


Je me base simplement sur la documentation d'Intel. Au niveau du
hardware, l'architecture supporte trois tailles de flottant : 4,
8 et 10 octets. Au niveau du hardware, l'architecture n'impose
aucun alignement en soi. En revanche, si une instruction accède
à une donnée qui se trouve à cheval de deux lignes de cache, il
faut bien deux accès physiques pour le charger. Avec une taille
de 12, dans un tableau, il y aurait fatalement des éléments qui
sont à cheval de deux lignes de cache. Si on choisit la taille
de long double uniquement en fonction de la vitesse d'exécution,
le bon choix de la taille serait 16.

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

Avatar
Gabriel Dos Reis
James Kanze writes:

| Gabriel Dos Reis wrote:
| > "kanze" writes:
|
| > | wrote:
|
| > | > [DOFP]
| > | > > Sur une machine raisonnable on a :
| > | > > Table of the numbers of bytes used for different data type
| > | > > char : 1
| > | > > int : 4
| > | > > long int : 4
| > | > > float : 4
| > | > > double : 8
| > | > > long double : 12
|
| > | > [Kanze]
| > | > > Tu as une drôle d'idée de « raisonable ». Je n'ai jamais
| > | > > encore vu une machine comme ça ;
|
| > | > Ma machine de développement prétend s'appeler Intel Pentium
| > | > III 500. Et elle dit même qu'elle a plein de soeurs et de
| > | > cousines qui lui ressemblent.
|
| > | Au niveau hardware, l'architecture Intel 32 bits a trois
| > | tailles de virgule flottant : 4, 8 et 10 bits.
|
| > Cela m'étonnerait.
|
| Faute de frappe évidente, non ?

Non. Parce que tout ton raisonement était basé sur ça.
Par contre, cela paraissait une confusion évidente entre bits et
bytes et pas seulement une faute de frappe.

| Changer « bits » en « bytes ».
|
| > [...]
|
| > | Évidemment, on pourrait en augmenter la taille pour en faire
| > | 12 aussi. Ou 11. Ou 13. C'est cependant un choix un peu
| > | bizarre.
|
| > Lequel est bizarre, 11, 12, ou 13?
|
| Tous. Logiquement, on choisira soit 16, pour la vitesse maximum,
^^^^^^^^^^^

Mais selon *quelle* logique ? La tienne ?

| soit 10, pour la taille minimum.

sauf que 10 c'est pas un multiple de quatre -- alignement naturel,
sur un x86 32-bit.

Maintenant, refais ton raisonement en considérant un sizeof 10 et un
alignement de 10. Si tu ne vois pas un trou, on arrête la discussion.

-- Gaby
Avatar
Gabriel Dos Reis
James Kanze writes:

| Gabriel Dos Reis wrote:
| > writes:
|
| > | > Au niveau hardware, l'architecture Intel 32 bits [...]
| > | > C'est donc un mauvais choix -- autant que faire, il vaut
| > | > mieux rester à 10.
|
| > | Si tu veux te plaindre du fait que sizeof ne renvoie pas la
| > | valeur qui te convient, eh bien il faut écrire aux
| > | développeurs de GCC. Moi, je n'y peux strictement rien.
|
| > Je crois implement que James confond « bits » avec « bytes » et fait
| > des raisonnements qui ne tiennent pas.
|
| Je n'arrive pas à comprendre toute ta phrase, mais je ne
| confonds certainement pas « bits » et « bytes ».

Extrait de :

Au niveau hardware, l'architecture Intel 32 bits a trois tailles
de virgule flottant : 4, 8 et 10 bits.

| Je constate que sous Linux, g++ a effectivement choisi une
| taille de 12 pour long double, c-à-d qu'il enforce un alignement
| de 4. Je ne connais pas les raisons de ce choix,

As-tu pensé, une seconde, que GCC *ne fait qu'implémenter* l'ABI définit
pour la plateforme cible ?

-- Gaby
Avatar
James Kanze
Gabriel Dos Reis wrote:
James Kanze writes:


| Gabriel Dos Reis wrote:
| > writes:


| > | > Au niveau hardware, l'architecture Intel 32 bits
| > | > [...] C'est donc un mauvais choix -- autant que
| > | > faire, il vaut mieux rester à 10.


| > | Si tu veux te plaindre du fait que sizeof ne renvoie
| > | pas la valeur qui te convient, eh bien il faut écrire
| > | aux développeurs de GCC. Moi, je n'y peux strictement
| > | rien.


| > Je crois implement que James confond « bits » avec «
| > bytes » et fait des raisonnements qui ne tiennent pas.


| Je n'arrive pas à comprendre toute ta phrase, mais je ne
| confonds certainement pas « bits » et « bytes ».


Extrait de :


Au niveau hardware, l'architecture Intel 32 bits a trois
tailles de virgule flottant : 4, 8 et 10 bits.


C'est une faute de frappe évidente, dont la correction est aussi
évidente.

| Je constate que sous Linux, g++ a effectivement choisi une
| taille de 12 pour long double, c-à-d qu'il enforce un
| alignement de 4. Je ne connais pas les raisons de ce choix,


As-tu pensé, une seconde, que GCC *ne fait qu'implémenter*
l'ABI définit pour la plateforme cible ?


Je n'accuse personne. Je sais que les raisons derrière tel ou
tel choix peuvent être légion. Tout ce que je dis, c'est que
c'est un chois qui n'a pas de sens *pour* *les* *hardware*
*modernes* -- il pourrait bien se justifer pour les 80386, par
exemple.

N'oublie pas le contexte de la discussion, non plus. On n'avait
pas dit qu'il s'agissait d'un choix g++, mais que c'est un
caractèristique des Intel Pentium. On est bien d'accord, je
crois, qu'un compilateur *peut* choisir ce qu'il veut. Il
s'avère que sur cette plate-forme, il y a trois types de
flottant supportés directement dans le hardware, et aucun n'a 12
octets. Et qu'aussi, le compilateur de loin le plus répandu sur
cette plate-forme a des long double de type 8. L'utilisation des
long double de taille 12 reste une exception -- peut-être plus
répandue que je ne le croyais au départ, mais toujours une
exception, présente uniquement sour un système minoritaire pour
la seule plate-forme où il existe.

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

Avatar
James Kanze
Gabriel Dos Reis wrote:
James Kanze writes:


| Gabriel Dos Reis wrote:
| > "kanze" writes:


| > | wrote:


| > | > [DOFP]
| > | > > Sur une machine raisonnable on a :
| > | > > Table of the numbers of bytes used for different data type
| > | > > char : 1
| > | > > int : 4
| > | > > long int : 4
| > | > > float : 4
| > | > > double : 8
| > | > > long double : 12


| > | > [Kanze]
| > | > > Tu as une drôle d'idée de « raisonable ». Je n'ai
| > | > > jamais encore vu une machine comme ça ;


| > | > Ma machine de développement prétend s'appeler Intel
| > | > Pentium III 500. Et elle dit même qu'elle a plein de
| > | > soeurs et de cousines qui lui ressemblent.


| > | Au niveau hardware, l'architecture Intel 32 bits a
| > | trois tailles de virgule flottant : 4, 8 et 10 bits.


| > Cela m'étonnerait.


| Faute de frappe évidente, non ?


Non. Parce que tout ton raisonement était basé sur ça.


Tu divages, ou quoi ? Tout mon raisonement était basé sur le
fait que les tailles supportées en hardware étaient de 4, de 8
et de 10 octets. C'était assez clair pour celui qui n'y met pas
de mauvaise fois.

Par contre, cela paraissait une confusion évidente entre bits
et bytes et pas seulement une faute de frappe.


| Changer « bits » en « bytes ».


| > [...]


| > | Évidemment, on pourrait en augmenter la taille pour en
| > | faire 12 aussi. Ou 11. Ou 13. C'est cependant un choix
| > | un peu bizarre.


| > Lequel est bizarre, 11, 12, ou 13?


| Tous. Logiquement, on choisira soit 16, pour la vitesse maximum,
^^^^^^^^^^^


Mais selon *quelle* logique ?


La logique « technique ». C'est vrai qu'il y a d'autres raisons,
commercielles ou politiques, qu'il faut souvent prendre en
compte.

La tienne ?


| soit 10, pour la taille minimum.


sauf que 10 c'est pas un multiple de quatre -- alignement
naturel, sur un x86 32-bit.


C'est quoi, cet alignement « naturel » ? Au niveau hardware, on
n'impose aucun alignement ; alignement « naturel » est 1.
Seulement, certains alignements peuvent payer une pénalité de
performance. Lesquels dépendent de la machine, mais sur des
processeurs moderne, un alignement de seulement 4 en fait parti.

Maintenant, refais ton raisonement en considérant un sizeof 10
et un alignement de 10. Si tu ne vois pas un trou, on arrête
la discussion.


J'ai une meilleur idée : fais des mesures des temps d'accès avec
des alignements de 4, et des alignements de 16. Parce que je ne
parle pas des raisonements théoriques, mais des temps
d'exécutions mesurables.

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

1 2 3