Différences entre versions de « AMD64 »

De Cliss XXI
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 à 17: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.

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 taille
  • void* double naturellement (plus grand adressage mémoire), mais aussi long
  • long long et double 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.