Différences entre versions de « AMD64 »
Sauter à la navigation
Sauter à la recherche
imported>SylvainBeucler m (Nouvelle page : * Détecter un processeur 64bit: cherche le flag <code>lm</code>: cat /proc/cpuinfo | grep --color -w lm * Compiler en 32bit sous AMD64: <pre> aptitude install lib32gcc1 libc6-dev...) |
imported>SylvainBeucler m |
||
(Une version intermédiaire par le même utilisateur non affichée) | |||
Ligne 37 : | Ligne 37 : | ||
* Créer un VServer 32bit sous 64bit: http://linux-vserver.org/Installing_32-bit_Fedora_on_64-bit_Debian (essentiellement: <code>export ARCH=i386</code>) | * Créer un VServer 32bit sous 64bit: http://linux-vserver.org/Installing_32-bit_Fedora_on_64-bit_Debian (essentiellement: <code>export ARCH=i386</code>) | ||
+ | |||
+ | == Test GCC plus poussé == | ||
+ | |||
+ | <pre> | ||
+ | #include <stdio.h> | ||
+ | |||
+ | struct test_alignment | ||
+ | { | ||
+ | int a, b, c; | ||
+ | }; | ||
+ | struct test_alignment2 | ||
+ | { | ||
+ | int a; | ||
+ | int *p; | ||
+ | }; | ||
+ | struct test_alignment3 | ||
+ | { | ||
+ | int a; | ||
+ | double d; | ||
+ | }; | ||
+ | |||
+ | |||
+ | int main(void) | ||
+ | { | ||
+ | struct test_alignment s[3]; | ||
+ | struct test_alignment2 s2[3]; | ||
+ | struct test_alignment3 s3[3]; | ||
+ | printf("sizeof(int) = %d\n", sizeof(int)); | ||
+ | printf("sizeof(void*) = %d\n", sizeof(void*)); | ||
+ | printf("sizeof(long) = %d\n", sizeof(long)); | ||
+ | printf("sizeof(long long) = %d\n", sizeof(long long)); | ||
+ | printf("sizeof(double) = %d\n", sizeof(double)); | ||
+ | printf("sizeof(struct test_alignment[0]) = %d\n", sizeof(s[0])); | ||
+ | printf("sizeof(struct test_alignment*3) = %d\n", sizeof(s)); | ||
+ | printf("sizeof(struct test_alignment2[0]) = %d\n", sizeof(s2[0])); | ||
+ | printf("sizeof(struct test_alignment2*3) = %d\n", sizeof(s2)); | ||
+ | printf("sizeof(struct test_alignment3[0]) = %d\n", sizeof(s3[0])); | ||
+ | printf("sizeof(struct test_alignment3*3) = %d\n", sizeof(s3)); | ||
+ | return 0; | ||
+ | } | ||
+ | </pre> | ||
+ | |||
+ | <pre> | ||
+ | # ./test32 | ||
+ | sizeof(int) = 4 | ||
+ | sizeof(void*) = 4 | ||
+ | sizeof(long) = 4 | ||
+ | sizeof(long long) = 8 | ||
+ | sizeof(double) = 8 | ||
+ | sizeof(struct test_alignment[0]) = 12 | ||
+ | sizeof(struct test_alignment*3) = 36 | ||
+ | sizeof(struct test_alignment2[0]) = 8 | ||
+ | sizeof(struct test_alignment2*3) = 24 | ||
+ | sizeof(struct test_alignment3[0]) = 12 | ||
+ | sizeof(struct test_alignment3*3) = 36 | ||
+ | |||
+ | # ./test64 | ||
+ | sizeof(int) = 4 | ||
+ | sizeof(void*) = 8 | ||
+ | sizeof(long) = 8 | ||
+ | sizeof(long long) = 8 | ||
+ | sizeof(double) = 8 | ||
+ | sizeof(struct test_alignment[0]) = 12 | ||
+ | sizeof(struct test_alignment*3) = 36 | ||
+ | sizeof(struct test_alignment2[0]) = 16 | ||
+ | sizeof(struct test_alignment2*3) = 48 | ||
+ | sizeof(struct test_alignment3[0]) = 16 | ||
+ | sizeof(struct test_alignment3*3) = 48 | ||
+ | </pre> | ||
+ | |||
+ | On remarque donc que: | ||
+ | * <code>int</code> garde la même taille | ||
+ | * <code>void*</code> double naturellement (plus grand adressage mémoire), mais aussi <code>long</code> | ||
+ | * <code>long long</code> et <code>double</code> ne bougent pas | ||
+ | * le compilateur continue d'aligner des blocs de 4 octets sur des multiples de 4 octets | ||
+ | * le compilateur aligne en revanche des blocs de 8 octets sur des multiples de 8 octets en 64bit, et non plus de 4 octets comme en 32bit | ||
+ | |||
+ | Conclusion: sur du code très courant, l'alignement ne changera pas, mais des changements surviennent tout de même facilement. |
Version actuelle datée du 17 juin 2008 à 16:38
- Détecter un processeur 64bit: cherche le flag
lm
:
cat /proc/cpuinfo | grep --color -w lm
- Compiler en 32bit sous AMD64:
aptitude install lib32gcc1 libc6-dev-i386 cat <<EOF | gcc -xc -o test32 - -m32 #include <stdio.h> int main() { printf("sizeof(int) = %d, sizeof(void*) = %d\n", sizeof(int), sizeof(void*)); } EOF
- Détecter un exécutable 32 ou 64:
$ file test32 test32: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), for GNU/Linux 2.6.0, dynamically linked (uses shared libs), for GNU/Linux 2.6.0, not stripped $ file test64 test64: ELF 64-bit LSB executable, AMD x86-64, version 1 (SYSV), for GNU/Linux 2.6.0, dynamically linked (uses shared libs), for GNU/Linux 2.6.0, not stripped
- Exécuter en 32bit sous AMD64: aucune manipulation particulière, mais il faut avoir les dépendances 32bit installées:
$ ./test32 sizeof(int) = 4, sizeof(void*) = 4 $ ./test64 sizeof(int) = 4, sizeof(void*) = 8
- Détecter un noyau (pas un processeur) 64bit:
$ uname -m x86_64
- Simuler un noyau 32bit:
$ aptitude install linux32 $ linux32 uname -m i686 # mais ça ne fait rien d'autre que ça
- Lancer un VServer installé en 32bit sous 64bit: aucune manipulation.
- Créer un VServer 32bit sous 64bit: http://linux-vserver.org/Installing_32-bit_Fedora_on_64-bit_Debian (essentiellement:
export ARCH=i386
)
Test GCC plus poussé
#include <stdio.h> struct test_alignment { int a, b, c; }; struct test_alignment2 { int a; int *p; }; struct test_alignment3 { int a; double d; }; int main(void) { struct test_alignment s[3]; struct test_alignment2 s2[3]; struct test_alignment3 s3[3]; printf("sizeof(int) = %d\n", sizeof(int)); printf("sizeof(void*) = %d\n", sizeof(void*)); printf("sizeof(long) = %d\n", sizeof(long)); printf("sizeof(long long) = %d\n", sizeof(long long)); printf("sizeof(double) = %d\n", sizeof(double)); printf("sizeof(struct test_alignment[0]) = %d\n", sizeof(s[0])); printf("sizeof(struct test_alignment*3) = %d\n", sizeof(s)); printf("sizeof(struct test_alignment2[0]) = %d\n", sizeof(s2[0])); printf("sizeof(struct test_alignment2*3) = %d\n", sizeof(s2)); printf("sizeof(struct test_alignment3[0]) = %d\n", sizeof(s3[0])); printf("sizeof(struct test_alignment3*3) = %d\n", sizeof(s3)); return 0; }
# ./test32 sizeof(int) = 4 sizeof(void*) = 4 sizeof(long) = 4 sizeof(long long) = 8 sizeof(double) = 8 sizeof(struct test_alignment[0]) = 12 sizeof(struct test_alignment*3) = 36 sizeof(struct test_alignment2[0]) = 8 sizeof(struct test_alignment2*3) = 24 sizeof(struct test_alignment3[0]) = 12 sizeof(struct test_alignment3*3) = 36 # ./test64 sizeof(int) = 4 sizeof(void*) = 8 sizeof(long) = 8 sizeof(long long) = 8 sizeof(double) = 8 sizeof(struct test_alignment[0]) = 12 sizeof(struct test_alignment*3) = 36 sizeof(struct test_alignment2[0]) = 16 sizeof(struct test_alignment2*3) = 48 sizeof(struct test_alignment3[0]) = 16 sizeof(struct test_alignment3*3) = 48
On remarque donc que:
int
garde la même taillevoid*
double naturellement (plus grand adressage mémoire), mais aussilong
long long
etdouble
ne bougent pas- le compilateur continue d'aligner des blocs de 4 octets sur des multiples de 4 octets
- le compilateur aligne en revanche des blocs de 8 octets sur des multiples de 8 octets en 64bit, et non plus de 4 octets comme en 32bit
Conclusion: sur du code très courant, l'alignement ne changera pas, mais des changements surviennent tout de même facilement.