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 de bits


Sujet :

C

  1. #1
    Membre éclairé Avatar de genteur slayer
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juin 2002
    Messages
    710
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2002
    Messages : 710
    Points : 825
    Points
    825
    Par défaut Tableau de bits
    Bonjour, Voilà mon problème:
    je dois faire un tableau de bits avec lecture/écriture la taille du tableau est variable, et la limite haute de taille nes pas spécialement définie, mais disons 1000000 pour l'exemple....
    du coup le fais une allocation du style:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    static const unsigned char bits_in_char =8;
     
    unsigned char* allocate(unsigned int taille) {
      return (unsigned char*)malloc(taille/bits_in_char + 1);
    }
    pour les fonctions de lecture/écriture
    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
     
    bool get_bit(unsigned char* tab,unsigned int index){
      unsigned int kn,in;
      kn=(index+bits_in_char-1)/bits_in_char;
      in=(index-1)%bits_in_char;
      return (1 & (tab[kn] >> in));
    }
     
    void set_bit(unsigned char* tab,unsigned int index,bool val){
      unsigned int kn,in;
      kn=(index+bits_in_char-1)/bits_in_char;
      in=(index-1)%bits_in_char;
      if (val)
        tab[kn]= tab[kn] | (1 << in);
      else
        tab[kn]= tab[kn] & ~(1 << in);
    }
    Mon soucis c'est que ces fonctions (surtout la lecture) sont appelée un très grand nombre de fois. Et je constate que c'est lent!

    Est-ce qu'il y a un meilleur moyen de définir/lire/écrire un tableau de bits?
    il n'y a que ceux qui savent qui ne savent pas qu'ils savent...
    Libere-toi hacker, GNU's Not Unix!!!

  2. #2
    Expert confirmé
    Inscrit en
    Mars 2005
    Messages
    1 431
    Détails du profil
    Informations forums :
    Inscription : Mars 2005
    Messages : 1 431
    Points : 4 182
    Points
    4 182
    Par défaut
    En premier lieu, utilise CHAR_BIT plutôt qu'une constante à toi.

    Hé oui, l'accès à un tableau de bits sera toujours plus lent qu'un tableau du type natif int où chaque entier fait office de bascule binaire ! Bon en pratique c'est loin d'être aussi simple, ça dépend de beaucoup de choses notamment la quantité de données que tu as besoin de rapatrier dans le cache à chaque session de bit fiddling...

    Difficile donc d'accuser le code proposé sans voir le reste de ton programme. Quelques pistes cependant pour accélérer l'exécution de tes routines :

    • compile avec -O2 ;
    • utilise un tableau d'int ou d'unsigned int pour stocker les bits (à la rigueur (u)int_fast64_t lorsque tu compiles sous Windows 64 bit) ;
    • d'une manière générale, utilise également et exclusivement des int au sein des opérations arithmétiques (pas de char, pas de bool...) ;
    • évite les branchements conditionnels if...else dans les routines d'accès, utilise uniquement de l'arithmétique et des opérateurs bit à bit ;
    • inline tes fonctions ou fais-en des macros.


    Tu peux vérifier la sortie assembleur du compilateur pour t'assurer de l'impact de tes modifications.

  3. #3
    Expert éminent
    Homme Profil pro
    Ingénieur développement matériel électronique
    Inscrit en
    Décembre 2015
    Messages
    1 565
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 60
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Ingénieur développement matériel électronique
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Décembre 2015
    Messages : 1 565
    Points : 7 648
    Points
    7 648
    Par défaut
    Bonjour,

    +1
    Une fois compilé en optimisé get_bit() fait 3 instructions assembleur en ARM ou 5 en Intel. A condition que les fonctions soient inline.
    Utiliser des int plutôt que des char permet une meilleure optimisation (l'accès mémoire char fait perdre un cycle).
    En ayant des index qui commencent à 1 plutôt qu'à 0, on perd aussi un cycle précieux
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    inline bool get_bit( const unsigned* tab , unsigned int index ) {
      unsigned kn = index / INT_BIT;
      unsigned in = index % INT_BIT;
      return 1 & tab[kn] >> in;
    }

  4. #4
    Expert confirmé
    Inscrit en
    Mars 2005
    Messages
    1 431
    Détails du profil
    Informations forums :
    Inscription : Mars 2005
    Messages : 1 431
    Points : 4 182
    Points
    4 182
    Par défaut
    Citation Envoyé par dalfab Voir le message
    En ayant des index qui commencent à 1 plutôt qu'à 0, on perd aussi un cycle précieux
    Bien vu, ça..


    J'allais aussi oublier le classique : ne caste pas le résultat de malloc !

Discussions similaires

  1. [unity]Copier un tableau de bits dans un mot
    Par zykoo dans le forum Automation
    Réponses: 2
    Dernier message: 18/04/2010, 10h51
  2. Comment enregistrer un tableau de bits TBits
    Par colorid dans le forum Langage
    Réponses: 6
    Dernier message: 16/12/2009, 18h16
  3. Tableau de bits
    Par Marvint dans le forum C#
    Réponses: 8
    Dernier message: 09/09/2009, 03h25
  4. Réponses: 1
    Dernier message: 28/03/2005, 12h33

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