IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

 C Discussion :

Tableau global initialisé


Sujet :

C

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre émérite
    Avatar de Pouet_forever
    Profil pro
    Inscrit en
    Octobre 2009
    Messages
    671
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2009
    Messages : 671
    Par défaut Tableau global initialisé
    Bonjour à tous.

    Dernièrement j'ai découvert quelque chose qui m'a surpris.
    En déclarant un tableau global et en l'initialisant, il se trouve que mon exécutable grossi en fonction de la taille de ce tableau et le temps de compilation est, lui aussi, fortement augmenté.
    Si je n'initialise pas ce tableau, rien de bien particulier, tout se passe bien.

    Voilà le code incriminé (gros tableau pour bien montrer le problème) :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    #include <stdio.h>
    #include <stdlib.h>
     
    int tab[1000][1000][100] = {{{ 0 }}};
     
    int main(void) {
     
      return EXIT_SUCCESS;
    }
    Sur linux avec gcc, ou win avec mingw je n'ai aucun problème, tandis que quand je fais ça avec gcc sous Mac... le problème se pose.

    Version GCC : gcc version 4.2.1 (Apple Inc. build 5646) (dot 1)

    Quelqu'un aurait-il une idée ?

    Merci d'avance.

  2. #2
    Responsable 2D/3D/Jeux


    Avatar de LittleWhite
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mai 2008
    Messages
    27 105
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Mai 2008
    Messages : 27 105
    Billets dans le blog
    146
    Par défaut
    Bonjour,

    Je sais deux trois choses, mais je ne comprends pas trop pourquoi vous avez le problème que sous MAC... en partant du principe que le problème est la taille de l'executable.

    Un tableau statique se met dans la pile. La pile est un morceau de mémoire qui est chargé directement à partir du programme. ( En assembleur, je crois que c'est le segment .DATA )
    Lorsque l'on fait l'initialisation directement dans le programme ( explicitement ) je pense que le compilateur doit préparé tout le segment dans l'executable. Donc remplissage d'une bonne partie.
    Après, que l'effet soit sous MAC seulement, il y a plusieurs cas, premièrement, une optimisation possible car vous demander un remplissage avec 0 ( peut être que c'est 0 par defaut et que le compilateur triche ). Sinon, peut être car les fichiers sous Windows / Linux sont compressés ( optimisés ).
    Je ne sais pas trop dans le détails, et j'ai pu dire des bétises :s
    Vous souhaitez participer à la rubrique 2D/3D/Jeux ? Contactez-moi

    Ma page sur DVP
    Mon Portfolio

    Qui connaît l'erreur, connaît la solution.

  3. #3
    Modérateur
    Avatar de Obsidian
    Homme Profil pro
    Chercheur d'emploi
    Inscrit en
    Septembre 2007
    Messages
    7 461
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Chercheur d'emploi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2007
    Messages : 7 461
    Par défaut
    Si tu initialises le tableau, qu'il soit dans la pile ou en global, les données servant à le remplir doivent être écrites en dur dans le code de ton programme pour y être copiées à l'exécution. Si tu déclares un tableau géant, les données associées le sont tout autant.

    Après, gcc est effectivement capable d'optimiser la chose si les données sont redondantes. Pourquoi ça ne marche pas sous Mac, mystère, effectivement.

  4. #4
    Modérateur
    Avatar de gangsoleil
    Homme Profil pro
    Manager / Cyber Sécurité
    Inscrit en
    Mai 2004
    Messages
    10 150
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Manager / Cyber Sécurité

    Informations forums :
    Inscription : Mai 2004
    Messages : 10 150
    Par défaut
    Bonjour,

    Le plus simple(*) est de regarder le code assembleur généré, voir de le passer dans un profiler de code pour savoir dans quelles parties il passe le plus de temps.

    Le fait de répéter cette opération sur différents OS te permettra de trouver la source de ton soucis.


    (*) : Oui oui, c'est simple, même si ca demande de comprendre plusieurs langages assembleurs
    "La route est longue, mais le chemin est libre" -- https://framasoft.org/
    Les règles du forum

  5. #5
    Membre émérite
    Avatar de Pouet_forever
    Profil pro
    Inscrit en
    Octobre 2009
    Messages
    671
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2009
    Messages : 671
    Par défaut
    Sous mac, si on tableau est initialisé il met 'tab' dans le segment 'data' directement et n'alloue pas la taille du tableau mais 4 fois la taille du tableau...
    Non initialisé il met ça sur la pile.

    Pour Linux :
    - non initialisé : pile
    - initialisé à 0 : bss
    - initialisé avec autre chose que 0 : data et l'exécutable grossi énormement. ^^

    Que ce soit Linux ou Mac, ils allouent tous deux 4 fois la taille du tableau.

    Voilà l'asm de chaque, pour voir si je me suis pas planté.

    Mac, tab non initialisé :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    	.text
    .globl _main
    _main:
    LFB6:
    	pushq	%rbp
    LCFI0:
    	movq	%rsp, %rbp
    LCFI1:
    	movl	$0, %eax
    	leave
    	ret
    LFE6:
    .comm _tab,400000000,5
    	.section __TEXT,__eh_frame,coalesced,no_toc+strip_static_syms+live_support
    EH_frame1:
    	.set L$set$0,LECIE1-LSCIE1
    	.long L$set$0
    LSCIE1:
    	.long	0x0
    	.byte	0x1
    	.ascii "zR\0"
    	.byte	0x1
    	.byte	0x78
    	.byte	0x10
    	.byte	0x1
    	.byte	0x10
    	.byte	0xc
    	.byte	0x7
    	.byte	0x8
    	.byte	0x90
    	.byte	0x1
    	.align 3
    LECIE1:
    .globl _main.eh
    _main.eh:
    LSFDE1:
    	.set L$set$1,LEFDE1-LASFDE1
    	.long L$set$1
    LASFDE1:
    	.long	LASFDE1-EH_frame1
    	.quad	LFB6-.
    	.set L$set$2,LFE6-LFB6
    	.quad L$set$2
    	.byte	0x0
    	.byte	0x4
    	.set L$set$3,LCFI0-LFB6
    	.long L$set$3
    	.byte	0xe
    	.byte	0x10
    	.byte	0x86
    	.byte	0x2
    	.byte	0x4
    	.set L$set$4,LCFI1-LCFI0
    	.long L$set$4
    	.byte	0xd
    	.byte	0x6
    	.align 3
    LEFDE1:
    	.subsections_via_symbols
    Linux non initialisé :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    	.file	"main.c"
    .globl tab
    	.data
    	.align 32
    	.type	tab, @object
    	.size	tab, 400000000
    tab:
    	.long	1
    	.zero	396
    	.zero	399600
    	.zero	399600000
    	.text
    .globl main
    	.type	main, @function
    main:
    	pushl	%ebp
    	movl	%esp, %ebp
    	movl	$0, %eax
    	popl	%ebp
    	ret
    	.size	main, .-main
    	.ident	"GCC: (Ubuntu 4.4.1-4ubuntu9) 4.4.1"
    	.section	.note.GNU-stack,"",@progbits
    nico@ubuntu:~/Bureau$ gcc -S main.c
    nico@ubuntu:~/Bureau$ cat main.s
    	.file	"main.c"
    	.comm	tab,400000000,32
    	.text
    .globl main
    	.type	main, @function
    main:
    	pushl	%ebp
    	movl	%esp, %ebp
    	movl	$0, %eax
    	popl	%ebp
    	ret
    	.size	main, .-main
    	.ident	"GCC: (Ubuntu 4.4.1-4ubuntu9) 4.4.1"
    	.section	.note.GNU-stack,"",@progbits
    Mac initialisé à 0 :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    .globl _tab
    	.data
    	.align 5
    _tab:
    	.space 400000000
    	.text
    .globl _main
    _main:
    LFB6:
    	pushq	%rbp
    LCFI0:
    	movq	%rsp, %rbp
    LCFI1:
    	movl	$0, %eax
    	leave
    	ret
    LFE6:
    	.section __TEXT,__eh_frame,coalesced,no_toc+strip_static_syms+live_support
    EH_frame1:
    	.set L$set$0,LECIE1-LSCIE1
    	.long L$set$0
    LSCIE1:
    	.long	0x0
    	.byte	0x1
    	.ascii "zR\0"
    	.byte	0x1
    	.byte	0x78
    	.byte	0x10
    	.byte	0x1
    	.byte	0x10
    	.byte	0xc
    	.byte	0x7
    	.byte	0x8
    	.byte	0x90
    	.byte	0x1
    	.align 3
    LECIE1:
    .globl _main.eh
    _main.eh:
    LSFDE1:
    	.set L$set$1,LEFDE1-LASFDE1
    	.long L$set$1
    LASFDE1:
    	.long	LASFDE1-EH_frame1
    	.quad	LFB6-.
    	.set L$set$2,LFE6-LFB6
    	.quad L$set$2
    	.byte	0x0
    	.byte	0x4
    	.set L$set$3,LCFI0-LFB6
    	.long L$set$3
    	.byte	0xe
    	.byte	0x10
    	.byte	0x86
    	.byte	0x2
    	.byte	0x4
    	.set L$set$4,LCFI1-LCFI0
    	.long L$set$4
    	.byte	0xd
    	.byte	0x6
    	.align 3
    LEFDE1:
    	.subsections_via_symbols
    Linux initialisé à 0 :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    	.file	"main.c"
    .globl tab
    	.bss
    	.align 32
    	.type	tab, @object
    	.size	tab, 400000000
    tab:
    	.zero	400000000
    	.text
    .globl main
    	.type	main, @function
    main:
    	pushl	%ebp
    	movl	%esp, %ebp
    	movl	$0, %eax
    	popl	%ebp
    	ret
    	.size	main, .-main
    	.ident	"GCC: (Ubuntu 4.4.1-4ubuntu9) 4.4.1"
    	.section	.note.GNU-stack,"",@progbits
    Mac initialisé à 1 :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    .globl _tab
    	.data
    	.align 5
    _tab:
    	.long	1
    	.space 396
    	.space 399600
    	.space 399600000
    	.text
    .globl _main
    _main:
    LFB6:
    	pushq	%rbp
    LCFI0:
    	movq	%rsp, %rbp
    LCFI1:
    	movl	$0, %eax
    	leave
    	ret
    LFE6:
    	.section __TEXT,__eh_frame,coalesced,no_toc+strip_static_syms+live_support
    EH_frame1:
    	.set L$set$0,LECIE1-LSCIE1
    	.long L$set$0
    LSCIE1:
    	.long	0x0
    	.byte	0x1
    	.ascii "zR\0"
    	.byte	0x1
    	.byte	0x78
    	.byte	0x10
    	.byte	0x1
    	.byte	0x10
    	.byte	0xc
    	.byte	0x7
    	.byte	0x8
    	.byte	0x90
    	.byte	0x1
    	.align 3
    LECIE1:
    .globl _main.eh
    _main.eh:
    LSFDE1:
    	.set L$set$1,LEFDE1-LASFDE1
    	.long L$set$1
    LASFDE1:
    	.long	LASFDE1-EH_frame1
    	.quad	LFB6-.
    	.set L$set$2,LFE6-LFB6
    	.quad L$set$2
    	.byte	0x0
    	.byte	0x4
    	.set L$set$3,LCFI0-LFB6
    	.long L$set$3
    	.byte	0xe
    	.byte	0x10
    	.byte	0x86
    	.byte	0x2
    	.byte	0x4
    	.set L$set$4,LCFI1-LCFI0
    	.long L$set$4
    	.byte	0xd
    	.byte	0x6
    	.align 3
    LEFDE1:
    	.subsections_via_symbols
    Linux initialisé à 1 :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    	.file	"main.c"
    .globl tab
    	.data
    	.align 32
    	.type	tab, @object
    	.size	tab, 400000000
    tab:
    	.long	1
    	.zero	396
    	.zero	399600
    	.zero	399600000
    	.text
    .globl main
    	.type	main, @function
    main:
    	pushl	%ebp
    	movl	%esp, %ebp
    	movl	$0, %eax
    	popl	%ebp
    	ret
    	.size	main, .-main
    	.ident	"GCC: (Ubuntu 4.4.1-4ubuntu9) 4.4.1"
    	.section	.note.GNU-stack,"",@progbits
    Quand je dis initialisé à 1 c'est uniquement ça : int tab[1000][1000][100] = {{{ 1 }}};

    Merci.

  6. #6
    Rédacteur

    Avatar de ram-0000
    Homme Profil pro
    Consultant en sécurité
    Inscrit en
    Mai 2007
    Messages
    11 517
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Consultant en sécurité
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Mai 2007
    Messages : 11 517
    Par défaut
    Citation Envoyé par Pouet_forever Voir le message
    Sous mac, si on tableau est initialisé il met 'tab' dans le segment 'data' directement et n'alloue pas la taille du tableau mais 4 fois la taille du tableau...
    Non, il alloue la taille du tableau * par sizeof(int) = 4 (probablement)
    Raymond
    Vous souhaitez participer à la rubrique Réseaux ? Contactez-moi

    Cafuro Cafuro est un outil SNMP dont le but est d'aider les administrateurs système et réseau à configurer leurs équipements SNMP réseau.
    e-verbe Un logiciel de conjugaison des verbes de la langue française.

    Ma page personnelle sur DVP
    .

  7. #7
    Membre émérite
    Avatar de Pouet_forever
    Profil pro
    Inscrit en
    Octobre 2009
    Messages
    671
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2009
    Messages : 671
    Par défaut
    Bien vu.

Discussions similaires

  1. Help prob de declaration de tableau global
    Par JeFF Boss dans le forum C++
    Réponses: 4
    Dernier message: 11/04/2007, 12h14
  2. [XML] [EXPAT] Parsing XML et tableau global
    Par GLDavid dans le forum Bibliothèques et frameworks
    Réponses: 1
    Dernier message: 10/02/2006, 12h31
  3. tableau global - d'une fenêtre à l'autre
    Par grinder59 dans le forum Général JavaScript
    Réponses: 2
    Dernier message: 04/02/2006, 10h50
  4. Changer la taille d'un tableau déjà initialisé
    Par totofweb dans le forum C++
    Réponses: 2
    Dernier message: 25/07/2004, 15h55

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo